【问题标题】:Memory error while trying to display video on tkinter window using opencv尝试使用 opencv 在 tkinter 窗口上显示视频时出现内存错误
【发布时间】:2020-08-02 18:49:35
【问题描述】:

我正在尝试为游戏编写代码,并且想在 tkinter 窗口中显示视频。当我将它与我的游戏代码一起使用时,我的代码加载和显示视频时遇到了一些问题。但是当我运行单独显示视频的代码时它工作正常。这是我得到的错误

    cv2.error: OpenCV(4.3.0) C:\projects\opencv-python\opencv\modules\core\src\alloc.cpp:73: error: (-4:Insufficient memory) Failed to allocate 2764800 bytes in function 'cv::OutOfMemoryError'

为什么会这样??我该如何解决?如果有人知道显示视频的更好方法,那也很棒。这是我的代码的相关部分


    def intro(self):
        Game.clear(self)
        vid = cv2.VideoCapture("project_files\\video.mp4")
        width = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
        height = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
        def get_frame():
            ret,frame = vid.read()
            if ret :
                return(ret,cv2.cvtColor(frame,cv2.COLOR_BGR2RGB))
            else :
                return(ret,None)    
        def update():
            ret,frame = get_frame()
            if ret :
                img = Image.fromarray(frame)
                photo = ImageTk.PhotoImage(image=img)
                photo.image=img
                label = Label(root,image=photo)
                label.place(relx=0.5,rely=0.5,anchor=CENTER)
                label.image=photo
                root.after(delay,update)
    
        delay = 15
        update()
        Game.qn_call(self,"a",iteration=0)

我是 tkinter 和 opencv 的新手,所以请保持简单

【问题讨论】:

  • 您正在为每一帧视频创建一个全新的标签 - 但对以前的标签没有任何作用:它们只是在内存中堆积。您要么每次都需要销毁以前的标签,要么最好只拥有一个标签,然后每次都设置其image 选项。
  • @jasonharper 感谢您的提示。根据您所说,我修改了我的代码,现在它可以工作了。我调用了一个我之前定义的函数,每次调用 update() 时,它都会清除屏幕上的所有小部件。它破坏了所有以前的标签,解决了问题。

标签: python python-3.x opencv tkinter


【解决方案1】:

感谢您的评论。我通过调用一个函数解决了这个问题,该函数在每次调用 update() 时都会销毁当前屏幕上的所有小部件。下面给出了工作代码的相关部分


    def clear(self):
        for widget in root.winfo_children():
            widget.destroy()
        
    def intro(self):
        Game.clear(self)
        vid = cv2.VideoCapture("project_files\\video.mp4")
        width = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
        height = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
        def get_frame():
            ret,frame = vid.read()
            if ret :
                return(ret,cv2.cvtColor(frame,cv2.COLOR_BGR2RGB))
            else :
                return(ret,None)
        def update():
            Game.clear(self)    #i added this to delete the labels.
            ret,frame = get_frame()
            print(ret)
            if ret :
                img = Image.fromarray(frame)
                photo = ImageTk.PhotoImage(image=img)
                photo.image=img
                label = Label(root,image=photo)
                label.place(relx=0.5,rely=0.5,anchor=CENTER)
                label.image=photo
            root.after(delay,update)
    
        delay = 15
        update()
        Game.qn_call(self,"a",iteration=0)

【讨论】:

  • 为什么不只创建一次标签,然后在update() 中更新它的图像?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-01
  • 1970-01-01
  • 2020-02-01
  • 2021-02-15
  • 2019-01-09
  • 2019-08-13
  • 2017-09-12
相关资源
最近更新 更多