1

I'm trying to fit facedetect from openCV on my QT code, all run fine until i decided to create a thread for my openCV code so I can run another things while the face detect is on.

the problem is if i call class->start(); my program breaks in the while loop in the run() but if i call the class.run(); (like a normal function) it runs as usual! what can be wrong?

code:

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 );
}

main code:

int main(int argc, char *argv[])
{
  faceTracker * ft = new faceTracker();
  ft->start();
}

thanks a lot!

karlphillip
  • 92,053
  • 36
  • 243
  • 426
Marco Martins
  • 359
  • 1
  • 5
  • 15
  • Where and what is class->start()? If you want more help you'll need to share more code. We can't tell what's wrong without any more information. – karlphillip Apr 12 '11 at 17:15
  • What do you mean by "my program breaks in the while loop"? – Zuljin Apr 12 '11 at 17:26
  • code edited to include the main. about the while loop I mean that the qDebug("teste3"); don't show so the problem is in frame = cvQueryFrame( capture ); this is what i think – Marco Martins Apr 12 '11 at 17:29

3 Answers3

0

The loop will only break if cvQueryFrame() returns a NULL frame or if the user presses q on the keyboard.

Add a debug so you know when the first situation happens:

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

Are you sure cvCaptureFromCAM(0) works ? Depending on the OS I have to pass -1 for it. But the fact is that you'll never know if cvCaptureFromCAM(0)succeeded because you don't check the return, and this might be the problem!

capture = cvCaptureFromCAM(0);
if (!capture)
{
  qDebug("cvCaptureFromCAM failed!");
  //exit(0); or whatever
}

EDIT:

Pay huge attention to this: you are creating a window named "video DisplUM" but you are trying to display the frames on a different window, named "video".

Anyway, it's also better if you change the window creation function to use the appropriate enum:

cvNamedWindow("video DisplUM", CV_WINDOW_AUTOSIZE);

and on faceTracker::run( ) comment detectFaces() for now and add a call to cvShowImage( "video DisplUM", frame );

Always be sure your application works with the minimum requirements before adding fancy stuffs, like face detection. My final suggestion is: write enough code just to capture the images from one thread and display them on a window, and then go from there.

karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • i've just added it and no message on the debug =/ i've found someone with same issue but no answer too: http://permalink.gmane.org/gmane.comp.lib.opencv.devel/278 – Marco Martins Apr 12 '11 at 17:48
  • Have you managed to run a simple application using OpenCV? Could you see the captured frames on a window? Have you seen it work? – karlphillip Apr 12 '11 at 17:59
  • For testing purposes I would execute `cvCaptureFromCAM()` from the same thread that is doing `cvQueryFrame()`. – karlphillip Apr 12 '11 at 18:01
  • yes it runs flawless if I don't use thread. and If i put all the calls I do in the facetracker() constructor in the run happens the same =/ – Marco Martins Apr 12 '11 at 18:04
  • Move the initialization of the camera to the beginning of `faceTracker::run( )`, before the loop starts. I have already succeeded grabbing frames from another thread in the past. Unfortunately I don't have that code right now. Which OpenCV version are you using? – karlphillip Apr 12 '11 at 18:09
  • Make sure you also remove **capture** from `assert()`. I trust that you already knew that. – karlphillip Apr 12 '11 at 18:12
  • nothing changes beside the fact that the qDebug("teste 2.5") inside the loop before frame = cvQueryFrame( capture ); now isn't called – Marco Martins Apr 12 '11 at 18:13
  • Which OpenCV version and which OS are you using? – karlphillip Apr 12 '11 at 18:16
  • opencv 2.0 osx snow leopard 10.6 – Marco Martins Apr 12 '11 at 18:16
  • OpenCV is already on version 2.2. You should at least be using v2.1, which I know it works on Mac. – karlphillip Apr 12 '11 at 18:25
  • 2.0 works too, i've downloaded from their site a dmg... that is not the problem, as i've said before in single thread works great – Marco Martins Apr 12 '11 at 18:27
  • Then you have a problem on your code. I updated the answer, you should have another look. – karlphillip Apr 12 '11 at 18:29
  • i've noticed that bug already and fixed, it created 2 windows instead of one. commenting the detect faces don't solve nothing =/ – Marco Martins Apr 12 '11 at 18:41
  • You have to fix that in the code you pasted here too so others don't get mislead. – karlphillip Apr 12 '11 at 18:50
  • I think that qt threads are somehow limited in memory. if I put on a while(1) loop an i++ and print it, if i use threads it stops at +- 17000 and if don't use threads it goes unlimited! – Marco Martins Apr 12 '11 at 19:07
  • it was missing the ft->wait(); in the main thread!! that was the problem, the thread was terminating because main was terminating – Marco Martins Apr 12 '11 at 21:27
  • ah my mistake, after all that wait was mising but I still have a crash =/ – Marco Martins Apr 12 '11 at 23:33
  • using qDebugs my problem is in the detectFaces function in the faces = cvHaarDetectObjects(...) (qDebug again) – Marco Martins Apr 12 '11 at 23:49
0

Solution: I can't create windows outside the main thread, that is why it was crashing. If i comment the window creation all works good (face detection included)

Marco Martins
  • 359
  • 1
  • 5
  • 15
0

I ran into a similar issue. What I found is that I had to rebuild OpenCV and include the TBB libraries. This adds threading support to OpenCV. Once I did this, I was able to pop up windows in any thread I chose. I've tested this on versions 2.1 and 2.2, using both C and C++ implementations.

Ryan
  • 470
  • 4
  • 15