我试图在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()
答案 0 :(得分:0)
我现在为任何会遇到同样问题的人找到了解决方案。我正在使用没有线程同步的全局变量dimg。在使用变量之前同步线程解决了问题。编辑on_drawing_area_draw如下将解决问题
autogrow.js