Raspberry Pi cv2.VideoCapture在第二次使用相同ID初始化时卡住

时间:2019-01-09 04:27:27

标签: python opencv raspberry-pi

在将我的源代码构建到Raspberry Pi时遇到问题。

OpenCV无法初始化新实例,并停留在步骤调用cv2.VideoCapture上。

这是我的源代码:

import threading
import time
import cv2

CAPTURE_HZ = 30.0

class Person(object):
    def __init__(self, name, id):
        self._camera = cv2.VideoCapture(id)
        print("Debug")
        self.name = name
        self._capture_frame = None
        # Use a lock to prevent access concurrent access to the camera.
        self._capture_lock = threading.Lock()
        self._capture_thread = threading.Thread(target=self._grab_frames)
        self._capture_thread.daemon = True
        self._capture_thread.start()

    def _grab_frames(self):
        while True:
            with self._capture_lock:
                self._capture_frame = self.name
            time.sleep(1.0 / CAPTURE_HZ)

    def speak(self):
        print("Hi! My name is {self.name}.".format(self=self))

这是我正在测试的结果:

$ python3
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import camera
>>> camera1 = camera.Camera("Cam1", 0)
Debug
>>> camera2 = camera.Camera("Cam2", 0) <<<<< It's stuck at here

此过程占用100%的Raspberry CPU。我必须使用sudo kill

感谢您阅读我的问题!

1 个答案:

答案 0 :(得分:0)

我发现解决此问题的方法是使用:多处理

我们将创建用于管理摄像机的服务器,以确保一次仅运行一台摄像机,并且可以在进程之间共享摄像机。

例如:

manager.py

false

server.py

import threading
import time
import cv2
from multiprocessing import Process
from multiprocessing.managers import BaseManager

CAPTURE_HZ = 30.0

class Camera(object):
    def __init__(self, name, id):
        self._camera = cv2.VideoCapture(id)
        print("Debug")
        self.name = name
        self._capture_frame = None
        # Use a lock to prevent access concurrent access to the camera.
        self._capture_lock = threading.Lock()
        self._capture_thread = threading.Thread(target=self._grab_frames)
        self._capture_thread.daemon = True
        self._capture_thread.start()

    def _grab_frames(self):
        while True:
            with self._capture_lock:
                self._capture_frame = self.name
            time.sleep(1.0 / CAPTURE_HZ)

    def speak(self):
        return self.name

class CameraManager(BaseManager):
   def __init__(self, address=None, authkey=''):
      BaseManager.__init__(self, address, authkey)
      self.camera = {}

   def addCamera(self, name, texture):
      self.camera[name] = texture

   def hasCamera(self, name):
      return name in self.camera


client.py

from multiprocessing import Process
from multiprocessing.managers import BaseManager
from manager import Camera, CameraManager

manager = CameraManager(address=('127.0.0.1', 50000), authkey=b'hello')

def getCamera(name): # Client always call to one function is getCamera
    if manager.hasCamera(name): # If camera already running -> return that camera
        print("Exist Camera")
        return manager.camera[name]
    else: # If camera not exist -> create the new one
        print("Create New Camera")
        camera = Camera(name, 0)
        manager.addCamera(name, camera)
        manager.register(name, lambda: camera)
        return manager.camera[name]

CameraManager.register("getCamera", getCamera)

if __name__ == "__main__":
    server = manager.get_server()
    server.serve_forever()

这是我经过测试的结果:

from multiprocessing import Process
from multiprocessing.managers import BaseManager
from manager import Camera, CameraManager

if __name__ == "__main__":
    manager = CameraManager(address=('127.0.0.1', 50000), authkey=b'hello')
    manager.connect()
    CameraManager.register("getCamera")
    camera = manager.getCamera("camera01")
    print("data = %s" % (camera.speak()))

并为client.py运行两个过程

$ python3 server.py

那时我的server.py将是

$ python3 client.py

This Stackoverflow Thread了解到了本教程。非常感谢!