在单独的过程中读取USB摄像头时,OpenCV在OS X上崩溃



我使用OS X(10.8.4)通过cv2 python绑定运行OpenCV 2.4.5。我试图通过多处理模块在单独的过程中从USB网络摄像头捕获图像。如果我使用笔记本电脑(2011 macbook air)的内部网络摄像头,一切似乎都能正常工作,但当我尝试从usb网络摄像头(罗技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

您的问题源于python使用os.fork跨越其子流程的方式。Mac上的OpenCV视频后端使用QTKit,该QTKit使用CoreFoundation。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进程。

最新更新