繁体   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