簡體   English   中英

OpenCV python 3.7 異步處理 cv2.VideoCapture(0)

[英]OpenCV python 3.7 handle cv2.VideoCapture(0) asynchronously

我是 python 和 openCV 的新手。 我希望這個問題是有道理的。 我想在 python 中使用異步/多線程,以便異步處理 openCV 中的 cv2.VideoCapture(0)。

原因:據我所知,我只能創建一個 cv2.VideoCapture(0) object 並且無法復制它。 這是我得到的錯誤。

類型錯誤:無法腌制“cv2.VideoCapture”object

TypeError: 'cv2.VideoCapture' object 不可下標

首先,我想在 window 中展示 PC 攝像頭拍攝的視頻:

cap = cv2.VideoCapture(0)

def one():
        while cv2.waitKey(1) < 0:
        hasFrame, frame = cap.read()
        cv2.imshow('Capturing1', frame)

雖然我在不同的 function 中處理相同的幀:


def two():
    while cv2.waitKey(1) < 0:
        hasFrame, frame = cap.read()
        frameWidth = frame.shape[1]
        frameHeight = frame.shape[0]

        inpBlob = cv2.dnn.blobFromImage(frame, 1.0 / 255, (inWidth, inHeight),
                                        (0, 0, 0), swapRB=False, crop=False)

        net.setInput(inpBlob)
        output = net.forward()

        H = output.shape[2]
        W = output.shape[3]
        # Empty list to store the detected keypoints
        points = []
        for i in range(nPoints):
            threshold = 0.1
            # confidence map of corresponding body's part.
            probMap = output[0, i, :, :]

            # Find global maxima of the probMap.
            minVal, prob, minLoc, point = cv2.minMaxLoc(probMap)

            # Scale the point to fit on the original image
            x = (frameWidth * point[0]) / W
            y = (frameHeight * point[1]) / H

            if prob > threshold:
                # cv2.circle(frameCopy, (int(x), int(y)), 8, (0, 255, 255), thickness=-1, lineType=cv2.FILLED)
                # cv2.putText(frameCopy, "{}".format(i), (int(x), int(y)), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, lineType=cv2.LINE_AA)

                # Add the point to the list if the probability is greater than the threshold
                points.append((int(x), int(y)))
                print(points)
            else:
                points.append(None)

我想這樣做,因為

 cv2.imshow('Capturing1', frame)

如果我將這兩個函數合二為一,則def one()中的代碼會減慢def two()中的代碼。

非常感謝您的幫助。 我希望這對你有意義。

您不必復制VideoCapture並且可能無法使用兩個副本來讀取相機,因為只有一個VideoCapture可以訪問相機。

您可以使用線程同時運行兩個或多個進程 - 因為線程共享 memory 所以您不必使用queuepickle將幀從一個線程發送到另一個線程。

您可以在主線程中創建一個VideoCapture並使用一個線程來讀取幀和其他線程來運行創建少量幀的幾個進程,但是您必須在主線程中運行 GUI(顯示幀)。

import cv2
import threading
import time

# --- functions ---

def read_frame():
    global has_frame
    global frame

    while running:
        has_frame, frame = cap.read()
        #time.sleep(.1)  # 0.1s to use less CPU

def one():
    global frame1

    while running:
        if has_frame:
            # processing frame
            frame1 = frame.copy()
            frame1 = cv2.putText(frame1, "One: fast process", (10, 30), cv2.FONT_HERSHEY_PLAIN, 2, (255, 255, 255))
        time.sleep(.1)  # 0.1s to use less CPU

def two():
    global frame2
    
    while running:
        if has_frame:
            # processing frame
            frame2 = frame.copy()
            frame2 = cv2.putText(frame2, "Two: slow process", (10, 30), cv2.FONT_HERSHEY_PLAIN, 2, (255, 255, 255))
            # simulate long running code
            time.sleep(2)        
        time.sleep(.1)  # 0.1s to use less CPU

#--- main ---

# - init ---

# create variables at start with default values
has_frame = False 
frame = None   # original frame from camera

frame1 = None  # frame after processing
frame2 = None  # frame after processing

cap = cv2.VideoCapture(0)  # create only one access to camera

# - create threads -

t0 = threading.Thread(target=read_frame)
t1 = threading.Thread(target=one)
t2 = threading.Thread(target=two)

# - start threads -

running = True  # use in threads to stop loops

t0.start()
t1.start()
t2.start()

# - GUI has to be in main thread -

while cv2.waitKey(100) != 27:  # ESC  # 100ms to use less CPU

    if frame1 is not None:
        cv2.imshow('Capturing1', frame1)

    if frame2 is not None:
        cv2.imshow('Capturing2', frame2)

    #time.sleep(.1)  # 0.1s to use less CPU
    
# - stop threads -

running = False

t0.join()
t1.join()
t2.join()

# - quit -

cv2.destroyAllWindows()
cap.release()

編輯: cv2的作者還創建了 class 以在單獨的Thread中運行VideoCapture

from imutils.video import WebcamVideoStream

請參閱使用 Python 和 OpenCV no PyImageSearch.com提高網絡攝像頭 FPS 中的詳細信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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