如何使用 2 个线程访问 1 个网络摄像头

How to access 1 webcam with 2 threads

我正在使用 python 3.5 和 opencv。

我想使用 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 帧的视频上限...但是,每次调用该函数时帧都会不同。

希望对您有所帮助。