使用opencv的gtk中的视频播放器卡住了

时间:2018-01-02 05:04:20

标签: python opencv gtk

我试图在gtk环境中使用python中的opencv代码简单地播放视频。为了实现它,我制作了一个glade文件,其中包含一个顶层窗口,一个文件菜单,一个绘图区域和一个文件选择器对话框。当用户选择文件时,代码启动一个调用函数VideoPlayerDA的线程,该函数开始读取视频,并在每帧之后生成一个queue_draw信号,以在绘图区域中显示帧。然而问题是,在几帧之后,整个用户界面冻结并变得无法响应,视频卡住了。 工具:我在debian stretch 上使用 Gtk版本3.22.11,python 3.5.3,OpenCV版本3.3.0。 PS:cv2.waitkey似乎也没有用。

import cv2
import time
import threading
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject, Gdk, GdkPixbuf

GObject.threads_init()

mymutex = threading.Lock()
dimg = GdkPixbuf.Pixbuf.new_from_file('test.jpg')

def VideoPlayerDA(filename,drawing_area):
    global dimg,dimg_available
    cap = cv2.VideoCapture(filename)

    while(cap.isOpened()):
        mymutex.acquire()
        ret, img = cap.read()
        if img is not None:
            boxAllocation = drawing_area.get_allocation()
            img = cv2.resize(img, (boxAllocation.width,\
                                   boxAllocation.height))

            img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) # opencv by default load BGR colorspace. Gtk supports RGB hance the conversion
            dimg = GdkPixbuf.Pixbuf.new_from_data(img.tostring(),
                                                  GdkPixbuf.Colorspace.RGB,False,8,
                                                  img.shape[1],
                                                  img.shape[0],
                                                  img.shape[2]*img.shape[1],None,None)

            #time.sleep(0.03)     
            drawing_area.queue_draw()
            mymutex.release()       
            time.sleep(0.03)
            #if ((cv2.waitKey(30) & 0xFF) == ord('q')):
            #    break
        else:
            mymutex.release()
            break

    print('end of file')

class video_player_gui:

    def on_main_window_destroy(self,object):
        Gtk.main_quit()

    def on_open_activate(self,widget):
        response = self.file_chooser.run()
        if response == 0:
            self.filename = self.file_chooser.get_filename()            
            thread = threading.Thread(target = VideoPlayerDA, args=(self.filename, self.drawing_area,))
            thread.daemon = True
            thread.start()
            self.file_chooser.hide()
        else:
            pass

    def on_drawing_area_draw(self,widget,cr):
        global dimg
        Gdk.cairo_set_source_pixbuf(cr, dimg.copy(), 0, 0)
        cr.paint()

    def __init__(self):
        self.gladefile = '/home/nouman/Development/Glade/P2/OpenCv_integration_test.glade'
        self.builder = Gtk.Builder()
        self.builder.add_from_file(self.gladefile)
        self.builder.connect_signals(self)
        self.main_window = self.builder.get_object("main_window")
        self.file_chooser = self.builder.get_object("file_chooser")
        self.drawing_area = self.builder.get_object("drawing_area")
        self.main_window.show()

if __name__ == "__main__":
    main =  video_player_gui()
    Gtk.main()

1 个答案:

答案 0 :(得分:0)

我现在为任何会遇到同样问题的人找到了解决方案。我正在使用没有线程同步的全局变量dimg。在使用变量之前同步线程解决了问题。编辑on_drawing_area_draw如下将解决问题

autogrow.js