Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用2个线程访问1个网络摄像头_Python_Multithreading_Opencv_Video Capture - Fatal编程技术网

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

Python 如何使用2个线程访问1个网络摄像头,python,multithreading,opencv,video-capture,Python,Multithreading,Opencv,Video Capture,我正在使用python 3.5和opencv 我想使用2个线程: 线程1:将视频保存到文件 线程2:向用户显示视频 要从网络摄像头查看/捕获视频,我正在使用以下网站的代码片段: 我可以使用以下代码捕获和保存视频: # Define the codec and create VideoWriter object fourcc = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter('output.avi',fourcc, 20.0, (6

我正在使用python 3.5和opencv

我想使用2个线程:

  • 线程1:将视频保存到文件
  • 线程2:向用户显示视频
要从网络摄像头查看/捕获视频,我正在使用以下网站的代码片段:

我可以使用以下代码捕获和保存视频:

# 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()
我可以使用以下代码查看视频:

# 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个选项,要么创建一个更新帧并在内部存储当前帧的线程,要么以线程安全的方式更新get next frame函数。我将在这里做第二个,向您展示:

  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帧。。。但是,每次调用函数时,帧都会不同


我希望这能对你有所帮助。

你为什么不等到你找到“其他事情”再问呢?@KlausD。我已经说到了这一点,但我简化了上面的示例。错误是什么?你会尝试实现什么,可能是线程是不必要的?您需要一个线程安全的对象,当您试图获取一个帧时,它有一个互斥体或类似的东西that@api55我的目标是让一个线程在视频中等待移动,然后在有移动时录制。然后,另一个线程只是查看视频捕获我即将进入睡眠状态,但这里是:创建一个对象,该对象具有UpdateName函数,该函数以线程安全的方式更新内部帧对象。然后另一个函数返回当前帧(同样,以线程安全的方式),然后您可以将所有线程连接到此对象,并且只有一个帧获取新帧。明天我可以举一个更详细的例子作为答案。帮助很大。非常感谢
ret,img=self.camVid.read()
应该是基于上述示例的
ret,img=self.videoCap.read()