2

我正在使用 OS X (10.8.4) 通过 cv2 python 绑定运行 OpenCV 2.4.5。我正在尝试通过多处理模块在单独的过程中从 USB 网络摄像头捕获图像。如果我使用笔记本电脑的(2011 macbook air)内部网络摄像头,一切似乎都可以工作,但是当我尝试从 USB 网络摄像头(Logitech C920)读取数据时,我遇到了崩溃(当我使用没有多处理封装的 USB 摄像头时没有崩溃) . 崩溃日志在这里。我正在使用的代码将可靠地重现崩溃如下。让这个工作对我来说是非常关键的任务,所以任何帮助都将不胜感激!

import multiprocessing
import cv2 #doesn't matter if you import here or in cam()

def cam():
    vc = cv2.VideoCapture(0) #modify 0/1 to toggle between USB and internal camera
    while True:
        junk,image = vc.read()

camProcess = multiprocessing.Process( target=cam )
camProcess.start()

while True:
    pass
4

1 回答 1

6

您的问题源于 python 使用 os.fork 跨越其子进程的方式。Mac 上的 OpenCV 视频后端使用使用 CoreFoundation 的 QTKit,MacOS 的这些部分不会保存在分叉子进程中运行,有时它们只是抱怨,有时它们会崩溃。

您需要在不使用 os.fork 的情况下创建子进程。这可以通过 python 2.7 来实现。

你需要使用台球(https://github.com/celery/billiard/tree/master/billiard)它可以替代 python 的多处理,并且有一些非常有用的改进。

from billiard import Process, forking_enable
import cv2 #does matter where this happens when you don't use fork

def cam():
    vc = cv2.VideoCapture(0) #modify 0/1 to toggle between USB and internal camera
    while True:
        junk,image = vc.read()

forking_enable(0) # Is all you need!
camProcess = Process( target=cam )
camProcess.start()

while True:
    pass

好吧,让我们添加一个更完整的示例:

from billiard import Process, forking_enable

def cam(cam_id):
    import cv2 #doesn't matter if you import here or in cam()
    vc = cv2.VideoCapture(cam_id) #modify 0/1 to toggle between USB and internal camera
    while True:
        junk,image = vc.read()
        cv2.imshow("test",image)
        k = cv2.waitKey(33)
        if k==27:    # Esc key to stop
            break

def start():

    forking_enable(0) # Is all you need!
    camProcess = Process(target=cam, args=(0,))
    camProcess.start()


if __name__ == '__main__':
    start()
    cam(1)

为此,您需要连接两个摄像头:它应该打开一个窗口并在单独的进程中运行每个摄像头(一个在主进程中,一个在生成的进程中)。我使用这种策略在自己的 python 进程中一次从多个摄像头流式传输图像。

于 2013-11-12T17:20:57.513 回答