我有一个 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)
但是屏幕上生成的图像是 8 位的,尽管ImageTk.PhotoImage
在I;16
模式下调用。
首先,此示例(即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 文档、其他帖子等找到解决方案……
编辑:
好的,所以我部分地回答了我自己的问题;不确定这是否是这样做的地方,但它可能会有所帮助。我试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 个像素的边框(从 0-489 和 0-649 开始;应该是 0-490 和 0-655) . 我不知道这是框架问题还是其他问题。图像周围仍然有一个讨厌的黑色边框,我认为它frameon=False
会摆脱,但也许不会......如果我弄明白了,我会对此发表评论。如果您遇到此问题,请告诉我。谢谢!