3

Python(pylab)とプロットについて質問があります-画像を読み込んで表示することはできますが(下のコードは下の画像を読み込みます)、これを3Dで輪郭としてプロットすることはできません、配列はpylab.contourf(x,y,z)ロードされた画像データからこれを達成する方法がわかりませんが、必要です。

任意の提案や支援をお願いします。私のコード:

from PIL import Image
import pylab

fileName = "image1.png"
im = Image.open(fileName)
#pylab.contourf(im) # don't work - needs an array but how
pylab.axis('off')
pylab.imshow(im)
pylab.show()

image1.png

4

3 に答える 3

5

画像を等高線図で表すことができる理由は、それが明らかに疑似カラー画像、つまり、完全なRGBカラースペクトルを使用して単一の変数を表す画像であるためです。 等高線図は、色(つまり、Z軸)を決定する単一の変数を持つデータも表すため、画像データを等高線図として表すこともできます。

これが、最初に等高線図を使用することを提案した理由です。(ただし、この質問で実際に求めているものは一般に存在しません。カラー画像には一般にRGBと3つの独立した色があるため、カラー画像を等高線図に変換する一般的に有効な方法はありません。等高線図には1つ(Z軸)しかありません。つまり、これは疑似カラー画像に対してのみ機能します。)

あなたの問題を具体的に解決するには:

1)表示する疑似カラー画像の作成に使用されるz軸データがある場合は、このデータを等高線図で使用します。これが最善の解決策です。

2)zデータがない場合は、画像の色をz値に反転してから、これを等高線図に入れる必要があるため、面倒です。あなたが表示する画像はほぼ確実にカラーマップmatplotlib.cm.jetを使用しており、unubtuがここで言うよりもそれを反転するためのより良い方法を私は見ることができません。

最後に、詳細を機能させるには、等高線図と画像の違いを理解する必要があります。

convertなぜ機能しないのかのデモ
ここでは、左から右へのz値のランプを使用して完全なテストケースを実行します。明らかなように、最大​​だった値が最小になるなどの理由で、z値が完全に台無しになりました。

つまり、目標はそのイチジクです。2マッチ図。4、しかしそれらは非常に異なっています。もちろん、問題は、元のz値のセットにconvert正しくマップされないことです。jet

ここに画像の説明を入力してください

import numpy as np
import matplotlib.pyplot as plt
import Image

fig, axs = plt.subplots(4,1)

x = np.repeat(np.linspace(0, 1, 100)[np.newaxis,:], 20, axis=0)

axs[0].imshow(x, cmap=plt.cm.gray)
axs[0].set_title('1: original z-values as grayscale')

d = axs[1].imshow(x, cmap=plt.cm.jet)
axs[1].set_title('2:original z-values as jet')    
d.write_png('temp01.png')  # write to a file

im = Image.open('temp01.png').convert('L')  # use 'convert' on image to get grayscale
data = np.asarray(im)  # make image into numpy data
axs[2].imshow(data, cmap=plt.cm.gray)
axs[2].set_title("3: 'convert' applied to jet image")

img = Image.open('temp01.png').convert('L')
z   = np.asarray(img)
mydata = z[::1,::1]  # I don't know what this is here for
axs[3].imshow(mydata,interpolation='nearest',cmap=plt.cm.jet)
axs[3].set_title("4: the code that Jake French suggests")

plt.show()

しかし、私が上で示唆したように、これを正しく行うことはそれほど難しくありません。

于 2013-03-24T16:41:01.760 に答える
4

OK、いくつかの調査とコードの簡略化、キーはconvert('L')、つまりrgbからグレースケールになります。Ali_mのコードは機能します。

from mpl_toolkits.mplot3d import Axes3D
from matplotlib import pylab as pl
from PIL import Image
import numpy as np
import pylab

img = Image.open('40.jpg').convert('L')
z   = np.asarray(img)
mydata = z[::1,::1]
fig = pl.figure(facecolor='w')
ax1 = fig.add_subplot(1,2,1)
im = ax1.imshow(mydata,interpolation='nearest',cmap=pl.cm.jet)
ax1.set_title('2D')

ax2 = fig.add_subplot(1,2,2,projection='3d')
x,y = np.mgrid[:mydata.shape[0],:mydata.shape[1]]
ax2.plot_surface(x,y,mydata,cmap=pl.cm.jet,rstride=1,cstride=1,linewidth=0.,antialiased=False)
ax2.set_title('3D')
ax2.set_zlim3d(0,100)
pl.show()

ここに出力

于 2013-03-24T22:09:36.113 に答える
2

編集:申し訳ありませんが、OPの元の質問を誤解しました。ImagePILオブジェクトからnumpy配列を取得するには、通常、を呼び出すだけnp.array(im)です。ただし、私は多くの顕微鏡データを処理しており、一部の画像形式(特に16ビットTIFF)では、この構文が常に機能するとは限らないことがわかりました。その場合は、を使用しますnp.asarray(im.getdata()).reshape(*im.shape[::-1])

修正された例を次に示します。

import numpy as np
from matplotlib import pylab as pl
from mpl_toolkits.mplot3d import Axes3D
from PIL import Image

def getimarray(path):
    im = Image.open(path,'r')
    return np.array(im)

def doplots(path='tmp/cell.png'):

    mydata = getimarray(path)
    mydata = mydata[::5,::5]
    fig = pl.figure(facecolor='w')
    ax1 = fig.add_subplot(1,2,1)
    im = ax1.imshow(mydata,interpolation='nearest',cmap=pl.cm.jet)
    ax1.set_title('2D')
    ax2 = fig.add_subplot(1,2,2,projection='3d')
    x,y = np.mgrid[:mydata.shape[0],:mydata.shape[1]]
    ax2.plot_surface(x,y,mydata,cmap=pl.cm.jet,rstride=1,cstride=1,linewidth=0.,antialiased=False)
    ax2.set_title('3D')
    ax2.set_zlim3d(0,255)

    return fig,ax1,ax2

if __name__ == '__main__':
    doplots()
于 2013-03-23T02:27:51.547 に答える