[英]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.