[英]OpenCV python 3.7 handle cv2.VideoCapture(0) asynchronously
I am new to python and openCV.我是 python 和 openCV 的新手。 I hope this question makes sense.
我希望这个问题是有道理的。 I want to use a asyncio/multithreading in python in order process cv2.VideoCapture(0) in openCV asynchronously.
我想在 python 中使用异步/多线程,以便异步处理 openCV 中的 cv2.VideoCapture(0)。
The reason: I can only create one cv2.VideoCapture(0) object and I cannot copy it - as far as I know.原因:据我所知,我只能创建一个 cv2.VideoCapture(0) object 并且无法复制它。 Here the errors I got.
这是我得到的错误。
TypeError: cannot pickle 'cv2.VideoCapture' object
类型错误:无法腌制“cv2.VideoCapture”object
TypeError: 'cv2.VideoCapture' object is not subscriptable
TypeError: 'cv2.VideoCapture' object 不可下标
First I want to show the video capturing by the PCs cam in a window:首先,我想在 window 中展示 PC 摄像头拍摄的视频:
cap = cv2.VideoCapture(0)
def one():
while cv2.waitKey(1) < 0:
hasFrame, frame = cap.read()
cv2.imshow('Capturing1', frame)
While I process the same frames in a different function:虽然我在不同的 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)
I want to do this, because the我想这样做,因为
cv2.imshow('Capturing1', frame)
in def one()
is slown down by the code in def two()
if I would combine those two functions in one.如果我将这两个函数合二为一,则
def one()
中的代码会减慢def two()
中的代码。
Many thanks for help.非常感谢您的帮助。 I hope it makes sense to you.
我希望这对你有意义。
You don't have to copy VideoCapture
and probably you couldn't use two copies to read camera because only one VideoCapture
can access camera.您不必复制
VideoCapture
并且可能无法使用两个副本来读取相机,因为只有一个VideoCapture
可以访问相机。
You can use threads to run two or more processes at the same time - and because threads share memory so you don't have to use queue
or pickle
to send frame from one thread to another.您可以使用线程同时运行两个或多个进程 - 因为线程共享 memory 所以您不必使用
queue
或pickle
将帧从一个线程发送到另一个线程。
You can create one VideoCapture
in main thread and use one thread to read frame and other threads to run few processes which create few frames, but GUI (displayng frame) you have to run in main thread.您可以在主线程中创建一个
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()
EDIT: Author of cv2
created also class to run VideoCapture
in separated Thread
.编辑:
cv2
的作者还创建了 class 以在单独的Thread
中运行VideoCapture
。
from imutils.video import WebcamVideoStream
See details in Increasing webcam FPS with Python and OpenCV no PyImageSearch.com
请参阅使用 Python 和 OpenCV no
PyImageSearch.com
提高网络摄像头 FPS 中的详细信息
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.