繁体   English   中英

PIL.ImageTk.PhotoImage 的更快替代方案是什么?

[英]What's a faster alternative to PIL.ImageTk.PhotoImage?

我正在尝试显示视频,并使用有关如何在 Tkinter 上播放视频的问题的示例/解决方案似乎无法提供流畅和快速的渲染。

例如:

frame = self.vid_cap.read()
frame = cv2.resize(frame, (696, 486))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

self.latest_img_ = Image.fromarray(frame)
self.latest_img_ = ImageTk.PhotoImage(image=self.latest_img_)

self.canvas.create_image(0, 0, anchor="nw", image=self.latest_img_)

上面的代码有效,但视频太慢了,即使使用self.canvas.after(1, self.video_loop_)类的东西。 经过一些基准测试后,结果是以下行:

self.latest_img_ = ImageTk.PhotoImage(image=self.latest_img_)

无论我在四核 mac 还是 12 核设备上运行代码,都需要 9 毫秒到 100 毫秒,而上面的整个代码(从捕获到将 numpy 数组转换为图像)只需要 0 毫秒到 1 毫秒。

有什么比ImageTk.PhotoImage更快的替代品?

您应该保留canvas object 的参考并对其进行修改,而不是每次都创建新对象。 为此,您可以首先通过传递image=None创建一个占位符。 下面是一个最小样本:

import tkinter as tk
import cv2
from PIL import Image, ImageTk


class GUI(tk.Tk):
    def __init__(self):
        super().__init__()
        self.canvas = tk.Canvas(self)
        self.canvas.pack(fill="both", expand=1)
        self.streaming_image = self.canvas.create_image(0, 0, anchor="nw", image=None)

    def show_frame(self):
        _, frame = self.vid_cap.read()
        frame = cv2.resize(frame, (696, 486))
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        img = Image.fromarray(frame)
        self.latest_img = ImageTk.PhotoImage(image=img)
        self.canvas.itemconfig(self.streaming_image, image=self.latest_img)
        self.after(10, self.show_frame)

    def start_video(self, path=None):
        self.vid_cap = cv2.VideoCapture(path)
        self.show_frame()


root = GUI()
root.start_video("your_path_here")
root.mainloop()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM