[英]Multi-threading in image processing - video python opencv
我正在使用 opencv Z23EEEB4347BDD26BFC6B7EE9A3B755DD. 我拥有的程序在单个线程上运行,因为屏幕上显示的结果视频甚至看起来不像视频,因为检测过程存在延迟。 所以,我试图使用多个线程重新实现它。 我使用一个线程读取帧,另一个线程显示检测结果,大约 5 个线程一次在多个帧上运行检测算法。 我已经编写了以下代码,但结果与单线程程序没有什么不同。 我是 python 的新手。 因此,任何帮助表示赞赏。
import threading, time
import cv2
import queue
def detect_object():
while True:
print("get")
frame = input_buffer.get()
if frame is not None:
time.sleep(1)
detection_buffer.put(frame)
else:
break
return
def show():
while True:
print("show")
frame = detection_buffer.get()
if frame is not None:
cv2.imshow("Video", frame)
else:
break
if cv2.waitKey(1) & 0xFF == ord('q'):
break
return
if __name__ == "__main__":
input_buffer = queue.Queue()
detection_buffer = queue.Queue()
cap = cv2.VideoCapture(0)
for i in range(5):
t = threading.Thread(target=detect_object)
t.start()
t1 = threading.Thread(target=show)
t1.start()
while True:
ret, frame = cap.read()
if ret:
input_buffer.put(frame)
time.sleep(0.025)
else:
break
print("program ended")
假设检测算法是 CPU 密集型的,您需要使用多处理而不是多线程,因为由于争用全局解释器锁,多个线程不会并行运行 Python 字节码。 您还应该摆脱所有对sleep
的调用。 当您运行多个线程或以您的方式处理时,也不清楚什么保证帧将以正确的顺序成为 output,也就是说,第二帧的处理可以在第一帧的处理之前完成,并且首先写入detection_buffer
。
以下使用 6 个进程的处理池(现在不需要隐式输入队列)。
from multiprocessing import Pool, Queue
import time
import cv2
# intialize global variables for the pool processes:
def init_pool(d_b):
global detection_buffer
detection_buffer = d_b
def detect_object(frame):
time.sleep(1)
detection_buffer.put(frame)
def show():
while True:
print("show")
frame = detection_buffer.get()
if frame is not None:
cv2.imshow("Video", frame)
else:
break
if cv2.waitKey(1) & 0xFF == ord('q'):
break
return
# required for Windows:
if __name__ == "__main__":
detection_buffer = Queue()
# 6 workers: 1 for the show task and 5 to process frames:
pool = Pool(6, initializer=init_pool, initargs=(detection_buffer,))
# run the "show" task:
show_future = pool.apply_async(show)
cap = cv2.VideoCapture(0)
futures = []
while True:
ret, frame = cap.read()
if ret:
f = pool.apply_async(detect_object, args=(frame,))
futures.append(f)
time.sleep(0.025)
else:
break
# wait for all the frame-putting tasks to complete:
for f in futures:
f.get()
# signal the "show" task to end by placing None in the queue
detection_buffer.put(None)
show_future.get()
print("program ended")
对我来说,我所做的是为 2 个函数构建 2 个线程并使用一个队列:
上限变量在我的进程 function 中。
def process:
cap = cv2.VideoCapture(filename)
ret, frame = cap.read()
while ret:
ret, frame = cap.read()
#detection part in my case I use tensorflow then
# end of detection part
q.put(result_of_detection)
def Display():
while True:
if q.empty() != True:
frame = q.get()
cv2.imshow("frame1", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
if __name__ == '__main__':
# start threads
p1 = threading.Thread(target=process)
p2 = threading.Thread(target=Display)
p1.start()
p2.start()
它对我来说很好用
希望我有所帮助:D
另外,我认为这个页面可能会有所帮助: https://pyimagesearch.com/2015/12/21/increasing-webcam-fps-with-python-and-opencv/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.