如何使用 2 个线程访问 1 个网络摄像头
How to access 1 webcam with 2 threads
我正在使用 python 3.5 和 opencv。
我想使用 2 个线程:
- 线程 1:将视频保存到文件
- 线程 2:向用户显示视频
为了 view/capture 来自网络摄像头的视频,我正在使用来自以下网站的代码片段:opencv video docs
我可以使用以下代码捕获并保存视频:
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
while(True):
ret, frame = cap.read()
if ret==True:
frame = cv2.flip(frame,0)
# write the flipped frame
out.write(frame)
else:
break
out.release()
cv2.destroyAllWindows()
我可以使用以下代码观看视频:
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
这些代码中的每一个都在它们自己的函数中,称为捕获和显示。然后,我使用 pythons 线程库在单独的线程中调用它们,如下所示:
cap = cv2.VideoCapture(0)
Thread(target=capture).start()
Thread(target=display).start()
cap.release()
我收到一个错误,我认为这与两个想要同时访问视频缓冲区的线程有关。
我知道这可以在没有线程的情况下完成,但除了只能在单独的线程中完成之外,还有其他我想做的事情。
如何从两个线程访问 cap 视频捕获?
我的 flask/django 经验非常有限,所以我不确定具体该怎么做,但我会直接回答发布的问题。
首先你需要创建一个线程安全的对象,以避免在不同的线程中同时调用read函数。
import cv2
import threading
class VideoCamera(object):
# filename can be 0 to access the webcam
def __init__(self, filename):
self.lock = threading.Lock()
self.openVideo(filename)
def openVideo(self, filename):
self.lock.acquire()
self.videoCap = cv2.VideoCapture(filename)
self.lock.release()
有了这个,您应该能够创建一个带锁的对象并安全地打开一个视频(以防您想要打开另一个具有相同对象的视频)。
现在您有 2 个选项,要么创建一个线程来更新帧并在内部存储当前帧,要么以线程安全的方式更新获取下一帧函数。我会在这里做第二个给你看:
def getNextFrame(self):
self.lock.acquire()
img = None
# if no video opened return None
if self.videoCap.isOpened():
ret, img = self.videoCap.read()
self.lock.release()
return img
这样您应该能够访问具有 2 帧的视频上限...但是,每次调用该函数时帧都会不同。
希望对您有所帮助。
我正在使用 python 3.5 和 opencv。
我想使用 2 个线程:
- 线程 1:将视频保存到文件
- 线程 2:向用户显示视频
为了 view/capture 来自网络摄像头的视频,我正在使用来自以下网站的代码片段:opencv video docs
我可以使用以下代码捕获并保存视频:
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
while(True):
ret, frame = cap.read()
if ret==True:
frame = cv2.flip(frame,0)
# write the flipped frame
out.write(frame)
else:
break
out.release()
cv2.destroyAllWindows()
我可以使用以下代码观看视频:
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
这些代码中的每一个都在它们自己的函数中,称为捕获和显示。然后,我使用 pythons 线程库在单独的线程中调用它们,如下所示:
cap = cv2.VideoCapture(0)
Thread(target=capture).start()
Thread(target=display).start()
cap.release()
我收到一个错误,我认为这与两个想要同时访问视频缓冲区的线程有关。
我知道这可以在没有线程的情况下完成,但除了只能在单独的线程中完成之外,还有其他我想做的事情。
如何从两个线程访问 cap 视频捕获?
我的 flask/django 经验非常有限,所以我不确定具体该怎么做,但我会直接回答发布的问题。
首先你需要创建一个线程安全的对象,以避免在不同的线程中同时调用read函数。
import cv2
import threading
class VideoCamera(object):
# filename can be 0 to access the webcam
def __init__(self, filename):
self.lock = threading.Lock()
self.openVideo(filename)
def openVideo(self, filename):
self.lock.acquire()
self.videoCap = cv2.VideoCapture(filename)
self.lock.release()
有了这个,您应该能够创建一个带锁的对象并安全地打开一个视频(以防您想要打开另一个具有相同对象的视频)。
现在您有 2 个选项,要么创建一个线程来更新帧并在内部存储当前帧,要么以线程安全的方式更新获取下一帧函数。我会在这里做第二个给你看:
def getNextFrame(self):
self.lock.acquire()
img = None
# if no video opened return None
if self.videoCap.isOpened():
ret, img = self.videoCap.read()
self.lock.release()
return img
这样您应该能够访问具有 2 帧的视频上限...但是,每次调用该函数时帧都会不同。
希望对您有所帮助。