如何利用多进程优化Python视频应用

烂漫一生 提交于 2019-12-05 17:43:29

如果要用Python播放视频,或者打开摄像头获取视频流,我们可以用OpenCV Python。但是在视频帧获取的时候同时做一些图像识别和处理,可能会因为耗时多而导致卡顿。一般来说,我们首先会想到把这些工作放入到线程中处理。但是由于Python GIL的存在,用不用线程几乎没有区别。所以要解决这个问题,必须通过多进程。这里分享下使用Dynamsoft Barcode Reader开发Python条形码扫码的例子。

用Python和摄像头打造的桌面条形码扫码应用

安装Dynamsoft Barcode Reader:

pip install dbr

安装OpenCV Python

pip install opencv-python

在主程序中创建一个新的扫码进程和共享内存:

from multiprocessing import Process, Queue
frame_queue = Queue(4)
finish_queue = Queue(1)
dbr_proc = Process(target=dbr_run, args=(
        frame_queue, finish_queue))
dbr_proc.start()

通过OpenCV不断获取视频帧插入到队列中:

vc = cv2.VideoCapture(0)
 
if vc.isOpened():  # try to get the first frame
    rval, frame = vc.read()
else:
    return
 
windowName = "Barcode Reader"
base = 2
count = 0
while True:
    cv2.imshow(windowName, frame)
    rval, frame = vc.read()
 
    count %= base
    if count == 0:
        try:
            frame_queue.put_nowait(frame)
        except:
            try:
                while True:
                    frame_queue.get_nowait()
            except:
                pass
 
    count += 1

条形码读取进程不断从队列中拿出数据进行解码:

def dbr_run(frame_queue, finish_queue):
    dbr.initLicense(config.license)
    while finish_queue.qsize() == 0:
        try:
            inputframe = frame_queue.get_nowait()
            results = dbr.decodeBuffer(inputframe, config.barcodeTypes)
            if (len(results) > 0):
                print(get_time())
                print("Total count: " + str(len(results)))
                for result in results:
                    print("Type: " + result[0])
                    print("Value: " + result[1] + "\n")
        except:
            pass
 
    dbr.destroy()

这样基本完成。不过在app退出的时候会看到一些错误信息:

Traceback (most recent call last):
 
File "E:\Programs\Python\Python36\lib\multiprocessing\queues.py", line 236, in _feed
 
send_bytes(obj)
 
File "E:\Programs\Python\Python36\lib\multiprocessing\connection.py", line 200, in send_bytes
 
self._send_bytes(m[offset:offset + size])
 
File "E:\Programs\Python\Python36\lib\multiprocessing\connection.py", line 290, in _send_bytes
 
nwritten, err = ov.GetOverlappedResult(True)
 
BrokenPipeError: [WinError 109] The pipe has been ended

记得在结束应用之前要清空队列中的数据:

def clear_queue(queue):
    try:
        while True:
            queue.get_nowait()
    except:
        pass
    queue.close()
    queue.join_thread()

程序运行效果:

源码

https://github.com/dynamsoft-dbr/python/blob/master/examples/camera/camera_multiprocessing.py

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!