我正在尝试将 numpy 数组转换为 PIL 格式,然后将其显示为标签!我可以对原始图像执行此操作,但在获取 fft 和 fftshift 后,我无法正确显示它。!
image1=Image.open('sam.jpg')
image1 = image1.resize((120, 120), Image.ANTIALIAS)
Labe(image=photo1).grid(row=0, column=7, columnspan=3, rowspan=2, padx=5, pady=5)
ipx1=np.array(image1)
(w,h)=ipx1.shape #120x20
现在我用我的图像做一些事情:
img_fft=np.fft.fft2(image1)
img_shift=np.fft.fftshift(image1_fft)
img_plot1=np.log10(1+abs(img_shift))
foto=Image.fromarray((img_plot1*255.999).round().astype(np.uint8),mode='L')
photo=ImageTk.PhotoImage(foto)
Label(image=photo).grid(row=0, column=10, columnspan=4, rowspan=2, padx=5, pady=5)
但不是:
我得到:
有什么想法吗?
最佳答案
当您将内容转换回 uint8
时,您会遇到溢出问题。
您正在使用 (img_plot1*255.999).round().astype(np.uint8)
进行转换,但对于接近或等于 1 的值将会溢出。(任何大于 0.998 的值)
假设 img_plot1
将始终包含 0 到 1 之间的值,我认为您只想执行以下任一操作:
(img_plot1 * 255.99).astype(np.uint8)
或
(img_plot1 * 255).round().astype(np.uint8)
round
调用将向上或向下舍入,而纯 int 转换实际上是floor
调用。
但是,仅从输出图像中的“带”猜测,您的输入数据就会溢出并多次“包装”。因此,您的输入数据的范围可能大于 0-1。
因此,如果您不想担心 img_plot1
中值的确切范围,您可以根据其范围将其重新调整为 0-255:
rescaled = 255 * (img_plot1 - img_plot1.min()) / img_plot1.ptp()
foto = Image.fromarray(rescaled.astype(np.uint8), mode='L')
您还可以使用np.digitize
来重新缩放数组,但我认为它的可读性较差。如果您想剪辑高于和低于阈值(例如 0 和 255)的值,还可以查看 np.clip
。
关于python - ImageTk.PhotoImage 无法正确显示图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13431621/