Ask Your Question
0

Face detection and mouth detection using OpenCV

asked 2014-05-26 01:00:15 -0600

ayu_id gravatar image

Hi everyone,

I mwant to make face detection and followed by mouth detection. Face detection working good, but mouth detection can't. I have false detection that detect not in the mouth area like i hope.

I'm using opencv 2.1 and visual studio 2008

Here is my code:

include "stdafx.h"

include <stdio.h>

include "cv.h"

include "highgui.h"

include "string.h"

include "stdlib.h"

include <iostream>

using namespace std; using namespace cv;

CvHaarClassifierCascade *cascade; CvHaarClassifierCascade *cascade_m;
CvMemStorage *storage;

void detectFaceandMouth( IplImage *img );

int _tmain(int argc, _TCHAR* argv[]) { CvCapture *capture = 0; IplImage *frame; int key = 0; const char *file1 = "C:/OpenCV2.1/data/haarcascades/haarcascade_frontalface_alt.xml";
const char *file2 = "C:/OpenCV2.1/data/haarcascades/haarcascade_mcs_mouth.xml";

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

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

/* initialize camera */
 capture = cvCaptureFromCAM( 0 );
 cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 320);
 cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 240 );

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

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

while( key != 'q' ) {
    /* get a frame */
    frame = cvQueryFrame( capture );

    /* always check */
    if( !frame ) break;

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

    /* detect face and mouth and display video */
    detectFaceandMouth( frame );

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

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

return 0;

}

void detectFaceandMouth( IplImage *img ) { int i;

/* detect faces */
CvSeq *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 *face = ( CvRect* )cvGetSeqElem( faces, i );
    cvRectangle( img,
                 cvPoint( face->x, face->y),
                 cvPoint( face->x + face->width, face->y + face->height ),
                 CV_RGB( 255, 0, 0 ), 1, 8, 0 );

    /* Set the Region of Interest*/  
    CvRect mouthROI = cvRect(face->x, face->y + (face->height/1.5), 
                      face->width, face->height/2.5);    
    CvRect *r;

/* detect mouth */
    CvSeq *mouth = cvHaarDetectObjects(
        img, 
        cascade_m, 
        storage, 
        1.1, 
        3, 
        0, 
        cvSize( 10, 10 ) );

 /* for each mouth found, draw a green box */
    for(i=0;i<(mouth ? mouth -> total: 0 ); i++ ) {  
                       int margin_left = 0;  
                       int margin_right = 0; 
                       r = (CvRect*)cvGetSeqElem( mouth, i );  
                       int x1 = r->x + mouthROI.x ;  
                       int y1 = r->y + mouthROI.y - 5;  
                          int x2 = x1 + r->width;  
                          int y2 = y1 + r->height; 
                          int x1c = x1 + margin_left;  
                          int y1c = (y1 + y2)/2 - 1;  
                          int x2c = x2 - margin_right;  
                          int y2c = (y1 + y2)/2 - 1;

                          cvRectangle(img,  
                          cvPoint(x1, y1),  
                          cvPoint(x2, y2),  
                          CV_RGB(0, 255, 0), 1, 8, 0); }
}
/* display video */
cvShowImage( "video", img );

}

Anyone could help me to fix my program?

Thank you

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2014-05-26 20:05:16 -0600

Witek gravatar image

updated 2014-05-26 20:08:15 -0600

You forgot to set ROI for mouth detection:

/* detect mouth */
    cvSetImageROI(img,mouthROI); //<-HERE
    CvSeq *mouth = cvHaarDetectObjects(
        img, 
        cascade_m, 
        storage, 
        1.1, 
        3, 
        0, 
        cvSize( 10, 10 ) );
    cvResetImageROI(img); //<-AND HERE

You should also change the second for loop index, as you have a loop inside a loop and you are using the same variable 'i' in both of them. With one face and one mouth it works fine, but with two or more faces it will fail.

Besides, stop using the old C interface. Your code in the new C++ interface would be much shorter and easier to read.

edit flag offensive delete link more

Comments

thanks for your answer :-) I'm a newbie using opencv so i dont know that my code is old C interface. Do you mean new c++ interface is like this?

http://docs.opencv.org/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html?highlight=haarcascade

What do you mean "You should also change the second for loop index" ? i still dont get it. I'm sorry to ask you back.

ayu_id gravatar imageayu_id ( 2014-05-27 00:58:22 -0600 )edit

Yes, the link you provided points to an example of new C++ interface. Change 'i' to 'j' in the last loop and the code will work for more than one face.

Witek gravatar imageWitek ( 2014-05-27 02:28:55 -0600 )edit

yes, it works for me!! yeaaay :-) Thanks a lot @Witek

ayu_id gravatar imageayu_id ( 2014-06-01 00:55:57 -0600 )edit
1

hi im a newbie in opencv,, im also facing that kind of problem,, but im using java,, how to implement that code in java,, thanks in advance

mockingjay05 gravatar imagemockingjay05 ( 2014-07-30 02:32:39 -0600 )edit

Question Tools

Stats

Asked: 2014-05-26 01:00:15 -0600

Seen: 5,649 times

Last updated: May 26 '14