在单独的过程中读取USB cam时,OS X上的OpenCV崩溃 [英] OpenCV crash on OS X when reading USB cam in separate process

查看:83
本文介绍了在单独的过程中读取USB cam时,OS X上的OpenCV崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用OS X(10.8.4)通过cv2 python绑定运行OpenCV 2.4.5.我正在尝试通过多处理模块在一个单独的过程中从USB网络摄像头捕获图像.如果我使用笔记本电脑的(2011 macbook air)内部网络摄像头,一切似乎都可以正常工作,但是当我尝试从USB网络摄像头(Logitech C920)读取数据时,会发生崩溃(当我使用不带多处理封装的USB cam时,不会崩溃) .崩溃日志位于此处.我正在使用的代码将可靠地重现崩溃,如下所示.对于我来说,完成这项工作非常关键,因此,我们将不胜感激!

I'm running OpenCV 2.4.5 via the cv2 python bindings, using OS X (10.8.4). I'm trying to capture images from a USB webcam in a separate process via the multiprocessing module. Everything seems to work if I use my laptop's (2011 macbook air) internal webcam, but when I attempt to read from a usb webcam (Logitech C920), I get a crash (no crash when I use the USB cam without the multiprocessing encapsulation). The crash log is here. Code I'm using that will reliably reproduce the crash is below. Getting this working is pretty mission-critical for me, so any help would be greatly appreciated!

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,后者使用CoreFoundation,而MacOS的这些部分并没有保存在分叉的子进程中运行,有时它们只是抱怨,有时会崩溃.

Your problem stems from the way python spans its subprocess using os.fork. The OpenCV video backend on Mac uses QTKit which uses CoreFoundation these parts of MacOS are not save to run in a forked subprocess, sometimes they just complain, sometimes they crash.

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

You need to create the subprocess without using os.fork. This can be achieved with python 2.7.

您需要使用台球( https://github.com/celery/billiard/树/大师/台球) 它可以替代python的多处理功能,并且有一些非常有用的改进.

You need to use billiard (https://github.com/celery/billiard/tree/master/billiard) It serves as a replacement for pythons multiprocessing and has some very useful improvements.

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

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

alright, lets add a more complete example:

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进程中一次从多台相机流式传输图像.

You need two cameras attached for this:It should open a window and run each camera in a separate process (one on the main process one in a spawned one). I use this strategy to stream images form multiple cameras at once each in its own python process.

这篇关于在单独的过程中读取USB cam时,OS X上的OpenCV崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆