numpy配列の形式の16ビット画像(ただし、有効なのは10ビットのみ)があります。画像の表示に使用されている現在のコードは次のとおりです。
from Tkinter import *
import Image, ImageTk
from functools import *
import numpy as np
class ImExam():
def __init__(self):
self.imExamDisp = Toplevel()
Label(self.imExamDisp, text="Pixel").grid(row=0, column=0)
self.pixelCoord = Label(self.imExamDisp); self.pixelCoord.grid(row=0, column=1)
Label(self.imExamDisp, text="Value").grid(row=0, column=2)
self.pixelValue = Label(self.imExamDisp); self.pixelValue.grid(row=0, column=3)
self.imgDisp = Label(self.imExamDisp, borderwidth=0)
self.imgDisp.grid(row=1, column=0, columnspan=4)
def updateImage(self, img, dispIMin=None, dispIMax=None):
self.i = Image.fromarray(img, mode='I;16')
self.iTk = ImageTk.PhotoImage('I;16', img.shape)
self.iTk.paste(self.i)
self.imgDisp.bind('<Motion>', partial(self.getPixelValue, img=self.i))
self.imgDisp.configure(image=self.iTk)
self.imgDisp.grid(row=1, column=0, columnspan=4)
self.imExamDisp.update()
def getPixelValue(self, event, img):
x = event.x
y = event.y
value = img.getpixel((x, y))
self.pixelCoord.configure(text="%02s, %02s" % (x, y))
self.pixelValue.configure(text="%0.4g" % value)
ImageTk.PhotoImage
ただし、I;16
モードで呼び出しているにもかかわらず、画面に表示される画像は8ビットです。
まず、この例(つまり、updateImage(img)
)は、ライブ画像フィードを使用して別のTkinterウィンドウを更新することを目的としておりgetPixelValue
、現在のピクセルと値の組み合わせを更新します。他の人が恩恵を受けることができる場合に備えて、すべて投稿しました。
Label
しかし、私の質問は、ウィジェットの表示範囲をどのように制御するかです。結果の16ビット(10ビット)画像は、ピクセル値は正しいものの、8ビットにスケーリングされます。私の画像には次のプロパティがあります。
print np.min(img), np.max(img), img.shape, img.dtype
109 1023 (491, 656) uint16
そして、その質問に続いて、表示スケールを変更できますか?たとえば、0〜1023の値を表示する代わりに、たとえば100〜800の画像を表示できますか?
Tkinterはこれを実現する方法ではないかもしれないので、私は他のパッケージを受け入れています。また、画像のスケーリング(たとえば、100〜800の間)は、numpyなどで行う方が適切です。それも受け入れられます。どんな提案もありがたいです!
PILドキュメントや他の投稿などでこれに対する解決策を見つけることができないようです...
編集:
OK、それで私は自分の質問に部分的に答えています。これがそれを行う場所であるかどうかはわかりませんが、役立つかもしれません。代わりに次のコードを使用してショットを作成しました(ここの例に従ってmatplotlib
インターフェイスされています):Tkinter
from Tkinter import *
import matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
from functools import *
import numpy as np
class ImExam():
def __init__(self):
self.font = ("Helvetica", 9)
self.imExamDisp = Toplevel()
Label(self.imExamDisp, text="Pixel").grid(row=0, column=0)
self.pixelCoord = Label(self.imExamDisp); self.pixelCoord.grid(row=0, column=1)
Label(self.imExamDisp, text="Value").grid(row=0, column=2)
self.pixelValue = Label(self.imExamDisp); self.pixelValue.grid(row=0, column=3)
matplotlib.rcParams.update({'font.family': "Helvetica", 'font.size': 9})
#
### Setup image window
#
self.fig = Figure(frameon=False)
self.subPlot = self.fig.add_axes([0, 0, 1, 1], frameon=False); # add_axes needed to fill image in Figure
self.subPlot.set_axis_off()
self.imgDisp = FigureCanvasTkAgg(self.fig, master=self.imExamDisp)
self.imgDisp.show(); self.imgDisp.get_tk_widget().grid(row=0, column=0, sticky=N+E+S+W)
def updateImage(self, img, dispIMin=0., dispIMax=1023., virtFlag=0):
self.subPlot.imshow(img, vmin=dispIMin, vmax=dispIMax, interpolation="quadric", aspect='auto', cmap='gray')
self.imgDisp.draw()
self.imgDisp.get_tk_widget().bind('<Motion>', partial(self.getPixelValue, img=img))
self.imgDisp.get_tk_widget().grid(row=1, column=0, columnspan=4)
self.imExamDisp.update()
def getPixelValue(self, event, img):
x = event.x
y = event.y
value = img[y, x] # imshow (or something) switches x, y
self.pixelCoord.configure(text="%02s, %02s" % (x, y))
self.pixelValue.configure(text="%0.4g" % value)
img
はまだ.を含むnumpy配列img.dtype = uint16
です。残念ながら、画像の右側に約6ピクセル、下部に1ピクセルの境界線があり、カーソルは表示されません(0-489と0-649から、0-490と0-655である必要があります)。 。これがフレームの問題なのか、それとも他の問題なのかわかりません。画像の周りにはまだ厄介な黒い境界線がありますが、それは取り除かれると思いましたframeon=False
が、そうではないかもしれません...私がそれを理解したら、これにコメントを投稿します。この問題が発生した場合はお知らせください。ありがとう!