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

本文介绍了如何使用Python结合OpenCV和DynamsoftBarcodeReader库,通过多进程来实现实时摄像头条形码扫描。在处理图像识别时,由于Python的GIL限制,多线程无法有效提升性能,因此采用多进程来避免卡顿。代码示例展示了如何创建扫描进程,通过队列传递视频帧,并在子进程中进行解码。在退出应用时需要注意清空队列以避免错误。
摘要由CSDN通过智能技术生成

如果要用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()

程序运行效果:

multiprocessing-python-barcode.PNG

源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值