python - 使用 OpenCV 和 Python 多处理进行持续相机抓取

标签 python multithreading opencv camera multiprocessing

我一直在用 Python 从 OpenCV 相机读取图像并从主程序读取最新图像。这是必需的,因为有问题的硬件。

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

这是线程版本:

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

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

谢谢!

最佳答案

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

我会使用 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 from only 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)

关于python - 使用 OpenCV 和 Python 多处理进行持续相机抓取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72469003/

相关文章:

python - 重叠的正则表达式匹配

python - 比较两个同种格式日期时间字符串是否可靠?

c# - 如何有效地异步登录?

python - python opencv检测图像完全白

python - 如何为 Python 和 Ubuntu 安装 OpenCV 2.4.7

Python - 时间数据不匹配格式

python - 如何从包含整数和其他对象的列表中随机选择一个整数?

c# - 生产者-消费者同步问题

java - Servlet线程调度

c++ - 如何绘制场方位图?我有渐变。 OpenCV C++