【问题标题】:Constant camera grabbing with OpenCV & Python multiprocessing使用 OpenCV 和 Python 多处理进行恒定摄像头抓取
【发布时间】:2022-06-08 01:37:13
【问题描述】:

我不断地从 Python 中的 OpenCV 相机读取图像并从主程序中读取最新图像。由于存在问题的硬件,因此需要这样做。

在搞乱线程并获得非常低的效率(呃!)之后,我想切换到多处理。

这是线程版本:

class WebcamStream:
    # initialization method
    def __init__(self, stream_id=0):
        self.stream_id = stream_id  # default is 0 for main camera

        # opening video capture stream
        self.camera = cv2.VideoCapture(self.stream_id)
        self.camera.set(cv2.CAP_PROP_FRAME_WIDTH, 3840)
        self.camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 2880)

        if self.camera.isOpened() is False:
            print("[Exiting]: Error accessing webcam stream.")
            exit(0)

        # reading a single frame from camera stream for initializing
        _, self.frame = self.camera.read()

        # self.stopped is initialized to False
        self.stopped = True

        # thread instantiation
        self.t = Thread(target=self.update, args=())
        self.t.daemon = True  # daemon threads run in background

    # method to start thread
    def start(self):
        self.stopped = False
        self.t.start()

    # method passed to thread to read next available frame
    def update(self):
        while True:
            if self.stopped is True:
                break
            _, self.frame = self.camera.read()
        self.camera.release()

    # method to return latest read frame
    def read(self):
        return self.frame

    # method to stop reading frames
    def stop(self):
        self.stopped = True

还有-

if __name__ == "__main__":
    main_camera_stream = WebcamStream(stream_id=0)
    main_camera_stream.start()
    frame = main_camera_stream.read()

有人可以帮我把它翻译成多进程土地吗?

谢谢!

【问题讨论】:

    标签: python multithreading opencv camera multiprocessing


    【解决方案1】:

    我已经写了几个类似问题的解决方案,但是已经有一段时间了,所以我们开始吧:

    我会使用shared_memory 作为缓冲区来读取帧,然后可以被另一个进程读取。我的第一个倾向是在子进程中初始化相机并读取帧,因为这似乎是一种“设置它并忘记它”的事情。

    import numpy as np
    import cv2
    from multiprocessing import Process, Queue
    from multiprocessing.shared_memory import SharedMemory
    
    def produce_frames(q):
        #get the first frame to calculate size of buffer
        cap = cv2.VideoCapture(0)
        success, frame = cap.read()
        shm = SharedMemory(create=True, size=frame.nbytes)
        framebuffer = np.ndarray(frame.shape, frame.dtype, buffer=shm.buf) #could also maybe use array.array instead of numpy, but I'm familiar with numpy
        framebuffer[:] = frame #in case you need to send the first frame to the main process
        q.put(shm) #send the buffer back to main
        q.put(frame.shape) #send the array details
        q.put(frame.dtype)
        try:
            while True:
                cap.read(framebuffer)
        except KeyboardInterrupt:
            pass
        finally:
            shm.close() #call this in all processes where the shm exists
            shm.unlink() #call this in at least one process
    
    def consume_frames(q):
        shm = q.get() #get the shared buffer
        shape = q.get()
        dtype = q.get()
        framebuffer = np.ndarray(shape, dtype, buffer=shm.buf) #reconstruct the array
        try:
            while True:
                cv2.imshow("window title", framebuffer)
                cv2.waitKey(100)
        except KeyboardInterrupt:
            pass
        finally:
            shm.close()
    
    if __name__ == "__main__":
        q = Queue()
        producer = Process(target=produce_frames, args=(q,))
        producer.start()
        consume_frames(q)
    

    【讨论】:

    • 非常感谢。问这一切中什么是绝对必要的会不会很粗鲁?
    • 绝对可以删减..我从其他答案中复制粘贴了一些,对于一次性实例,很少需要整个类。
    • @Gabe 我将示例缩减到更接近必要的最小值。我之前有点得意忘形:|
    • @Gabe 你指的是哪三行?该代码适用于我的直接复制粘贴...
    • @Gabe 这里只有一个可能的问题:cap.read() 失败。这将取决于您的相机设置。它对我来说很好。
    猜你喜欢
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 2013-11-16
    • 2020-05-14
    • 1970-01-01
    • 2015-12-22
    • 2011-12-14
    • 1970-01-01
    相关资源
    最近更新 更多