簡體   English   中英

圖像處理中的多線程 - 視頻 python opencv

[英]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 個線程並使用一個隊列:

  1. 獲取框架並處理它
  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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM