python-3.x 属性错误:"PhotoImage"对象没有属性"_PhotoImage__photo"

xxslljrj  于 2023-01-18  发布在  Python
关注(0)|答案(4)|浏览(872)

我正在Yolo3 - 4-PY上工作,用tkinter实现它。
我到处都找过了,但还是没能解决这个问题。
当我运行程序时,画布显示,但当我点击开始视频(按钮),我得到以下错误:
正在从权重/yolov3.weights...加载权重完成!/usr/local/lib/python3.5/dist-packages/PIL/ImageTk. py:119:未来警告:元素间比较失败;返回标量,但如果模式不在["1","L","RGB","RGBA"]中,则以后将执行元素级比较:

Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.5/tkinter/__init__.py", line 1553, in __call__
return self.func(*args)
File "webcam_demo.py", line 13, in start_video
show_frame()
File "webcam_demo.py", line 39, in show_frame
imgtk = ImageTk.PhotoImage(image=cv2image)
File "/usr/local/lib/python3.5/dist-packages/PIL/ImageTk.py", line 120, in 
__init__
mode = Image.getmodebase(mode)
File "/usr/local/lib/python3.5/dist-packages/PIL/Image.py", line 313, in 
getmodebase
return ImageMode.getmode(mode).basemode
File "/usr/local/lib/python3.5/dist-packages/PIL/ImageMode.py", line 55, in 
getmode
return _modes[mode]
TypeError: unhashable type: 'numpy.ndarray'
Exception ignored in: <bound method PhotoImage.__del__ of 
<PIL.ImageTk.PhotoImage object at 0x7f4b73f455c0>>
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/PIL/ImageTk.py", line 130, in 
__del__    name = self.__photo.name
AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'
5f0d552i

5f0d552i1#

在我例子中,只需添加以下行即可

root = tkinter.Tk()

完整代码:

root = tkinter.Tk()
image = PIL.Image.open(r"C:\Users\Hamid\Desktop\asdasd\2.jpeg")
img = ImageTk.PhotoImage(image)
l = Label(image=img)
l.pack()
8ulbf1ek

8ulbf1ek2#

问题

在行imgtk = ImageTk.PhotoImage(image=cv2image)中,您将numpy数组(cv2image)作为输入传递给ImageTk.PhotoImage,但是PIL.ImageTk的源代码提到它需要PIL图像。
这是PIL. ImageTk的源代码为PhotoImage的init()所提到的内容。

class PhotoImage(object):
    .....
    :param image: Either a PIL image, or a mode string.  If a mode string is
              used, a size must also be given.

溶液

因此,基本上,您必须将numpy数组转换为PIL Image,然后将其传递给ImageTk.PhotoImage()。

    • 那么,可以将imgtk = ImageTk.PhotoImage(image=cv2image)行替换为imgtk = ImageTk.PhotoImage(image=PIL.Image.fromarray(cv2image))吗?**

这会将numpy数组转换为PIL Image,并将其传递给方法。

参考文献

我从this source中提取了将numpy数组转换为PIL Image的代码。

mbjcgjjk

mbjcgjjk3#

当你把image变量放在标签中时,你必须把image变量初始化为“image”。
例如:(正确方法)

photo = PhotoImage(file = "C://Users//Carl//Downloads//download.png")
label1 = Label(image = photo)
label1.pack()

例如:(错误方法)

photo = PhotoImage(file = "C://Users//Carl//Downloads//download.png")
label1 = Label(photo)
label1.pack()
y4ekin9u

y4ekin9u4#

有趣的是......显然Tkinter有一种讨厌的副作用会导致这种情况。
注意(来自hamidjahandideh的answer),在创建ImageTk之前创建根窗口很重要。
即,AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'无法执行此操作

im_numpy = cv2.imread(ResourcePhotos.BLUE_PERSON_TRAIL_PHOTO)[:, :, ::-1].copy()  # Load BGR Image
im_pil = Image.fromarray(im_numpy)
imagetk = ImageTk.PhotoImage(im_pil)
window = tk.Tk()  # This line must come BEFORE crearting ImageTk
tk.Label(window, image=imagetk).pack()
window.mainloop()

但这是可行的:

im_numpy = cv2.imread(ResourcePhotos.BLUE_PERSON_TRAIL_PHOTO)[:, :, ::-1].copy()  # Load BGR Image
im_pil = Image.fromarray(im_numpy)
window = tk.Tk()  # This line must come BEFORE creating ImageTk
imagetk = ImageTk.PhotoImage(im_pil)
tk.Label(window, image=imagetk).pack()
window.mainloop()

相关问题