【问题标题】:Cannot display a 32 bit grayscale tif image in tkinter无法在 tkinter 中显示 32 位灰度 tif 图像
【发布时间】:2022-01-01 13:01:39
【问题描述】:

我正在尝试从 tkinter 中的光子探测器和皮拉图斯探测器系统打开一个 32 位灰度图像。 tkinter 画布中显示的图像是黑色的。我找不到任何可行的建议。感谢您对以下代码的任何帮助。 谢谢 [皮拉图斯图片][1]

from skimage import io, img_as_float,  util, morphology
from skimage.util import img_as_ubyte

from tkinter import *
from PIL import Image, ImageTk
from tkinter import Tk, Button, Canvas, Frame, Label, filedialog
img_data= img_as_float(io.imread("slice0040.tif"))
Width, Height=img_data.shape

#convert img_data to 8 bit using skimage
#and making an image for display using tkinter
img=Image.fromarray(util.img_as_ubyte(img_data))


root=Tk()


frame=LabelFrame(root,text='Image frame',width=Width,height=Height)
frame.grid(row=1,column=0,rowspan=2)

canvas = Canvas(frame, width=Width, height=Height)
canvas.grid(row=0, column=0,sticky=W)
img = ImageTk.PhotoImage(img.resize((Width, Height), Image.ANTIALIAS))
img_container = canvas.create_image(Width-int(Width/2), int(Height)-int(Height/2), image=img)

root.mainloop()

这个适用于 int 类型和 float 类型的图像。

import cv2
import numpy as np
from tkinter import *
from PIL import Image, ImageTk
# Load with PIL
im = Image.open('Pilatus.tif')
# Make into Numpy array and normalise
na   = np.array(im)
if im.mode =='F' :
    norm = cv2.normalize(na, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
else:
    norm = na
img=(norm*255).astype(np.uint8)

root=Tk()
Width=1000
Height=1000

label=Label(root,text="Root label",font=("Verdana",12))
label.grid(row=0,column=0)

frame=LabelFrame(root,text='Image frame',width=Width,height=Height)
frame.grid(row=1,column=0,rowspan=2)

print(Width,Height)
label=Label(frame,text="Image frame")
label.grid(row=2,column=0,columnspan=2)

canvas = Canvas(frame, width=Width, height=Height)
canvas.grid(row=3, column=0,sticky=W)
img=Image.fromarray(img)
img = ImageTk.PhotoImage(img.resize((Width, Height), Image.ANTIALIAS))
img_container = canvas.create_image(Width-int(Width/2), int(Height)-int(Height/2), image=img)

root.mainloop()

【问题讨论】:

  • 如果是TIFF图片,为什么不直接使用PIL.Image来加载图片呢?
  • 我不熟悉您使用的特定库,但通常浮点格式的图像具有 0.0 到 1.0 范围内的像素值。如果你盲目地将其转换为 8 位整数,你只会得到 0 或 1 的像素值 - 换句话说,“黑色”和“非常接近黑色,你无法区分”。
  • @acw1668,这是一个 32 位输入图像,PIL 不支持加载 32 个图像。如果我错了,请纠正我。我是新手。谢谢。
  • 基于图像modes上的文档,PIL支持32位图像。您可以简单地尝试使用 PIL 加载图像并查看它是否有效。
  • @acw1668,对不起,我之前不清楚。我们可以使用 PIL 加载 32 位图像,但 tkinter 不支持 32 位图像。在画布上显示它们之前,它们需要转换为 8 位或 16 位类型。我想使用 skimage 进行图像处理,这就是我使用 skimage 加载图像的原因。

标签: tkinter python-imaging-library scikit-image 32-bit


【解决方案1】:

我不能 100% 确定您有什么限制,或者绝对显示精度对您来说到底有多重要,但是如果您现在只想在屏幕上看到某些内容,您可以将数据标准化到 0.. 255 并将其命名为 unsigned int 8ubyte

因此,如果它当前在 -2..1577 范围内,您想要添加 2,那么它将在 0..1579 范围内。然后乘以 255.0/1577.0,四舍五入并命名为ubyte。它应该以完整的对比度范围显示。

或使用 OpenCV

from PIL import Image
import cv2
import numpy as np

# Load with PIL
im = Image.open('Photonics.tif')

# Make into Numpy array and normalise
na   = np.array(im)
norm = cv2.normalize(na, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)

# Save
cv2.imwrite('Photonics-OpenCV.jpg', (norm*255).astype(np.uint8))

【讨论】:

  • 感谢@MarkSetchell。我使用 scikit 的 rescale_intensity 选项重新调整了强度。现在,我可以看到原始图像,但它只显示图像的四分之一。检查了尺寸,它们是正确的。您能否从这段代码中提出问题所在?
  • #skimage img_data= img_as_uint(io.imread("Pilatus.tif")) img_data_contrast=exposure.rescale_intensity(img_data) print(f'Max and Min is ', np.max(img_data_contrast),np.min(img_data_contrast)) img_data=img_data_contrast Width, Height = img_data.shape #convert img_data to 8 bit using skimage #and making an image for display using PIL img=Image.fromarray(img_data,mode='L')
  • 请分享您的实际 TIFF - 使用 Google Drive 或 Dropbox 等。目前它是一个PNG。谢谢。
  • 图片链接在这里。图像 Pilatus.tif 是一个 int 图像,Photonics.tif 是一个浮点图像。 link谢谢
  • 我现在对你的问题感到困惑。请按数字说明以下各点。 1)您对哪个图像有疑问 - 皮拉图斯?光子学?两个都? 2)实际问题是什么?图像的大小/形状是否错误?亮度不对? 3)图像应该是什么样子?谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多