openCV 和线程问题

Posted

技术标签:

【中文标题】openCV 和线程问题【英文标题】:openCV and Threads issue 【发布时间】:2011-04-12 17:01:03 【问题描述】:

我正在尝试在我的 QT 代码上安装来自 openCV 的 facedetect,一切运行良好,直到我决定为我的 openCV 代码创建一个线程,这样我就可以在面部检测开启时运行其他东西。

问题是如果我调用 class->start();我的程序在 run() 的 while 循环中中断,但如果我调用 class.run(); (就像一个正常的功能)它像往常一样运行!有什么问题?

代码:

faceTracker::faceTracker()
 

qDebug("teste1");
filename = "/Users/marcomartins/Documents/QT/DisplUM/haarcascades/haarcascade_frontalface_alt_tree.xml";

/* load the classifier
    note that I put the file in the same directory with this code */
cascade = ( CvHaarClassifierCascade* )cvLoad( filename, 0, 0, 0 );

/* setup memory buffer; needed by the face detector */
storage = cvCreateMemStorage( 0 );

/* initialize camera */
capture = cvCaptureFromCAM( 0 );

/* always check */
assert( cascade && storage && capture );

/* create a window */
cvNamedWindow( "video DisplUM", 1 );




void faceTracker::detectFaces( IplImage *img )


/* detect faces */
        faces = cvHaarDetectObjects(
        img,
        cascade,
        storage,
        1.1,
        3,
        0 /*CV_HAAR_DO_CANNY_PRUNNING*/,
        cvSize( 40, 40 ) );

/* for each face found, draw a red box */
for( i = 0 ; i < ( faces ? faces->total : 0 ) ; i++ ) 
    CvRect *r = ( CvRect* )cvGetSeqElem( faces, i );
    cvRectangle( img,
                 cvPoint( r->x, r->y ),
                 cvPoint( r->x + r->width, r->y + r->height ),
                 CV_RGB( 255, 0, 0 ), 1, 8, 0 );
    qDebug("caras: %d", faces->total);


/* display video */
cvShowImage( "video", img );



void faceTracker::run( )

qDebug("teste2");

while( key != 'q' ) 
    /* get a frame */
    frame = cvQueryFrame( capture );
qDebug("teste3");
    /* always check */
    if( !frame ) break;

    /* 'fix' frame */
    cvFlip( frame, frame, 1 );
    frame->origin = 0;

    /* detect faces and display video */
    detectFaces( frame );

    /* quit if user press 'q' */
    key = cvWaitKey( 10 );



/* free memory */
cvReleaseCapture( &capture );
cvDestroyWindow( "video" );
cvReleaseHaarClassifierCascade( &cascade );
cvReleaseMemStorage( &storage );

主要代码:

int main(int argc, char *argv[])

  faceTracker * ft = new faceTracker();
  ft->start();

非常感谢!

【问题讨论】:

class->start() 在哪里以及是什么?如果您需要更多帮助,则需要共享更多代码。如果没有更多信息,我们无法判断出了什么问题。 “我的程序在 while 循环中中断”是什么意思? 代码已编辑以包含主要内容。关于 while 循环,我的意思是 qDebug("teste3");不显示所以问题出在 frame = cvQueryFrame( capture );这是我的想法 【参考方案1】:

只有当cvQueryFrame() 返回一个NULL 帧或用户在键盘上按下q 时,循环才会中断。

添加调试,以便您知道第一种情况何时发生:

frame = cvQueryFrame( capture );
if( !frame ) 
  
  qDebug("cvQueryFrame failed!");
  break;

你确定cvCaptureFromCAM(0) 有效吗?根据操作系统,我必须为此传递-1。但事实是,您永远不会知道cvCaptureFromCAM(0)succeeded 是否成功,因为您不检查退货,这可能就是问题所在!

capture = cvCaptureFromCAM(0);
if (!capture)

  qDebug("cvCaptureFromCAM failed!");
  //exit(0); or whatever

编辑:

请特别注意这一点:您正在创建一个名为“video DisplUM”的窗口,但您正试图在另一个名为“video”的窗口上显示帧。

无论如何,如果你更改窗口创建函数以使用适当的枚举也更好:

cvNamedWindow("video DisplUM", CV_WINDOW_AUTOSIZE);

现在在faceTracker::run( ) 上评论detectFaces() 并添加对 cvShowImage("video DisplUM", frame);

的调用

在添加花哨的东西(例如人脸检测)之前,请务必确保您的应用程序符合最低要求。我的最终建议是:编写足够的代码来从一个线程捕获图像并将它们显示在窗口上,然后从那里开始。

【讨论】:

我刚刚添加了它,调试时没有消息=/我发现有人有同样的问题但也没有答案:permalink.gmane.org/gmane.comp.lib.opencv.devel/278 您是否设法使用 OpenCV 运行了一个简单的应用程序?你能在窗口上看到捕获的帧吗?你看到它工作了吗? 出于测试目的,我将在执行cvQueryFrame() 的同一线程中执行cvCaptureFromCAM() 是的,如果我不使用线程,它会完美运行。如果我把我在 facetracker() 构造函数中所做的所有调用都放在运行中,那么会发生同样的情况 =/ 将相机的初始化移动到faceTracker::run( )的开头,在循环开始之前。我过去已经成功地从另一个线程中抓取帧。不幸的是,我现在没有那个代码。您使用的是哪个 OpenCV 版本?【参考方案2】:

解决方案: 我无法在主线程之外创建窗口,这就是它崩溃的原因。如果我评论窗口创建一切正常(包括人脸检测)

【讨论】:

【参考方案3】:

我遇到了类似的问题。我发现我必须重建 OpenCV 并包含 TBB 库。这为 OpenCV 添加了线程支持。一旦我这样做了,我就可以在我选择的任何线程中弹出窗口。我已经使用 C 和 C++ 实现在 2.1 和 2.2 版本上对此进行了测试。

【讨论】:

以上是关于openCV 和线程问题的主要内容,如果未能解决你的问题,请参考以下文章

如何编译openCV以保证单线程?

OpenCV 和 Python 多线程 - 在 VideoCapture 对象中搜索

Python OpenCV线程

如何使用线程通过 openCV 和 MFC 处理图像

使用 OpenCV、Boost 线程和多个摄像头

多线程 OpenCV 程序