【问题标题】:Raspberry Pi cv2.VideoCapture stuck at the second time init with same idRaspberry Pi cv2.VideoCapture 在第二次以相同的 id 初始化时卡住
【发布时间】:2019-06-03 19:41:36
【问题描述】:

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

OpenCV 无法初始化新实例并停留在 step call 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

而且这个过程占用了 Raspberry 的 100% CPU。我必须使用sudo kill

感谢您阅读我的问题!

【问题讨论】:

    标签: python opencv raspberry-pi


    【解决方案1】:

    我发现解决这个问题的方法是使用:Multiprocessing

    我们将创建一个服务器来管理摄像头,以确保一次只有一个摄像头在运行,并且可以在进程之间共享摄像头。

    例如:

    manager.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
    
    
    

    server.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()
    

    client.py

    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()))
    

    这是我测试的结果:

    $ python3 server.py
    
    

    并为client.py运行两个进程

    $ python3 client.py
    
    

    那时我的server.py会是

    python3 server.py
    Create New Camera
    Debug
    Exist Camera
    Exist Camera
    

    我是从This Stackoverflow Thread 学到的本教程。非常感谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-17
      • 1970-01-01
      • 2020-03-26
      相关资源
      最近更新 更多