Monday, April 18, 2011

[Programming] OpenCV2.2 Face Detection Example for VC++ 2010 Express

If you are having trouble setting up VC++2010 Express for your face detection software, using opencv2.2.
Please download my project file here and add it to your solution.
Or create your own by going over my review here...

Setting up OpenCV Ver2.2 for FaceDetection

1.  Installing Opencv2.2
Please download and install OpenCV2.2 from here >>
I used the file says "OpenCV-2.2.0-win32-vs2010.exe ", which is windows installer...
Some of the software that use OpenCV require System pass, please mark the check box if it asks.

2.  Installing VC++ 2010 Express
If you do not have it, install it from here >>


3.  Create Empty project 
Start VC++ and go to "File" -> "New" -> "Project" ->  "VisualC++" -> "General" -> "Empty Project".
Enter a project name, "Test_HelloWorld", and solution name "OpenCV2.2 Examples".
and Click OK.

4.  Configure the Project
Right Click on Project which you created, and select "Property".

Please go to the installation guide here and read...
Do following steps as described in the guide
  1. Add 2 new Include Directories (it's the path where you installed OpenCV, include folder):
    • C:\Program Files\OpenCV2.2\include
    • C:\Program Files\OpenCV2.2\include\opencv
  2. Add 1 new Library Directory (it's the path where you installed OpenCV, lib folder):
    • C:\Program Files\OpenCV2.2\lib
  3. Go to Linker in the left menu and select Input option
  4. Add these entries on Additional Dependencies option:
    • C:\Program Files\OpenCV2.2\lib\opencv_core220d.lib
    • C:\Program Files\OpenCV2.2\lib\opencv_highgui220d.lib
    • C:\Program Files\OpenCV2.2\lib\opencv_video220d.lib
    • C:\Program Files\OpenCV2.2\lib\opencv_ml220d.lib
    • C:\Program Files\OpenCV2.2\lib\opencv_legacy220d.lib
    • C:\Program Files\OpenCV2.2\lib\opencv_imgproc220d.lib 
    • C:\Program Files\OpenCV2.2\lib\opencv_objdetect220d.lib (optional..., not listed in the guide, but required for face detect sample)
<!> The path to the OpenCV directory depends on your system and how you installed.  For my machine, it was installed under "C:\" instead of "Program Files".
<!> For Additional Dependency you can just type in the name of the files.
5.  Writing a Code
Create and add "main.cpp".
The code below is the modified version of "facedetect.cpp" in the sample on OpenCV

//Header file has been changed from v2.1
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <iostream>

using namespace std;
using namespace cv;

//change the path to the your haar file
const String haarcascade_face = "../Haarcascades/haarcascade_frontalface_alt.xml";
const String haarcascade_eye = "../Haarcascades/haarcascade_eye_tree_eyeglasses.xml";

//1.0 for 1:1 processing. use bigger number to increase the speed
//used as =>   smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );
const double scale = 3.0;

void detectAndDraw( Mat& img,
                   CascadeClassifier& cascade, CascadeClassifier& nestedCascade,
                   double scale);

void main (){
       
    CascadeClassifier cascade_face, cascade_eye;

    CvCapture* capture = 0;
    Mat frame, frameCopy, image;

    //load cascade file for face detection
    //If the load function returns false, set a break point before this call 
    //and see the contents inside "haarcascade_face".  
    //If it loading the contents of Haar cascade, but returning false, then check your additional dependency. 
    //If you are running under "debug", you have to use xxxxd.lib instead of xxxx.lib.
    if(!cascade_face.load(haarcascade_face)){
        cerr << "ERROR: Could not load classifier cascade" << endl;
        return;
    }   

    //load cascade file for eye detection
    if(!cascade_eye.load(haarcascade_eye)){
        cerr << "ERROR: Could not load classifier cascade" << endl;
        return;
    }
   
    //capture camera image
    capture = cvCaptureFromCAM(0);

    //create window
    cvNamedWindow("result", 1);  //arg2 = 1 for autosize

    //process captured image
    if( capture )
    {
        cout << "In capture ..." << endl;
        for(;;)
        {
            IplImage* iplImg = cvQueryFrame( capture );
            frame = iplImg;
            if( frame.empty() )
                break;
            if( iplImg->origin == IPL_ORIGIN_TL )
                frame.copyTo( frameCopy );
            else
                flip( frame, frameCopy, 0 );

            detectAndDraw( frameCopy, cascade_face, cascade_eye, scale );
            //Don't know why it needs wait call, but it always here...
            if( waitKey( 10 ) >= 0 )    //wait for 10msec before processing next frame
                                        //if the key entry is detected, it will break from the loop
                goto _cleanup_;
        }

        waitKey(0);
_cleanup_:
    //Do not forget release memory    
    cvReleaseCapture( &capture );
    }
}


void detectAndDraw( Mat& img,
                   CascadeClassifier& cascade, CascadeClassifier& nestedCascade,
                   double scale)
{
    int i = 0;
    double t = 0;
    vector<Rect> faces;
    const static Scalar colors[] =  { CV_RGB(0,0,255),
        CV_RGB(0,128,255),
        CV_RGB(0,255,255),
        CV_RGB(0,255,0),
        CV_RGB(255,128,0),
        CV_RGB(255,255,0),
        CV_RGB(255,0,0),
        CV_RGB(255,0,255)} ;

    Mat gray, smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );

    cvtColor( img, gray, CV_BGR2GRAY );
    resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );
    equalizeHist( smallImg, smallImg );

    t = (double)cvGetTickCount();
    cascade.detectMultiScale( smallImg, faces,
        1.1, 2, 0
        //|CV_HAAR_FIND_BIGGEST_OBJECT
        //|CV_HAAR_DO_ROUGH_SEARCH
        |CV_HAAR_SCALE_IMAGE
        ,
        Size(30, 30) );
    t = (double)cvGetTickCount() - t;
   
    printf( "detection time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );

    //Draw Circle on the output image
    for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++ )
    {
        Mat smallImgROI;
        vector<Rect> nestedObjects;
        Point center;
        Scalar color = colors[i%8];
        int radius;
        center.x = cvRound((r->x + r->width*0.5)*scale);
        center.y = cvRound((r->y + r->height*0.5)*scale);
        radius = cvRound((r->width + r->height)*0.25*scale);
        circle( img, center, radius, color, 3, 8, 0 );            
         /*  Commenting eye detection part out to make it faster...
        //detecting eye
        if( nestedCascade.empty() )
            continue;
        smallImgROI = smallImg(*r);
        nestedCascade.detectMultiScale( smallImgROI, nestedObjects,
            1.1, 2, 0
            //|CV_HAAR_FIND_BIGGEST_OBJECT
            //|CV_HAAR_DO_ROUGH_SEARCH
            //|CV_HAAR_DO_CANNY_PRUNING
            |CV_HAAR_SCALE_IMAGE
            ,
            Size(30, 30) );
       

        for( vector<Rect>::const_iterator nr = nestedObjects.begin(); nr != nestedObjects.end(); nr++ )
        {
            center.x = cvRound((r->x + nr->x + nr->width*0.5)*scale);
            center.y = cvRound((r->y + nr->y + nr->height*0.5)*scale);
            radius = cvRound((nr->width + nr->height)*0.25*scale);
            circle( img, center, radius, color, 3, 8, 0 );
        }
        */
    } 
    cv::imshow( "result", img );   
}


6.  Build and Run the Project
Just build and run the project as you do on regular C++ project...


Trouble Shooting.....
  • Program fails to build... -> Linker error... First check to see if all the required library is included or not.
  • Program compiles and runs but breaks at fanction call to OpenCV faunctions -> library specified in Additional dependency is wrong... xxxxxd.lib for debug, and xxxxx.lib for release... if you are building the project under debug mode, you have to use library that the name ends with "d".
  • CV functions return error result eaven if it's getting correct input (result) -> same as above....
  • "Cannot find or open the PDB file" -> Change Setting for debug -> option -> symbol ... Google it... For win7, you need to run as administrator.
  • Nothing happens -> check the path to the Haar Cascade files.

3 comments:

  1. Everything seems great, except for this part when I compile the project:


    error LNK2019: unresolved external symbol "public: void __thiscall Tserial::disconnect(void)" (?disconnect@Tserial@@QAEXXZ) referenced in function _main c:\Users\Morgan\documents\visual studio 2010\Projects\DeteccaoFacialv6\DeteccaoFacialv6\DeteccaoFacialv6.obj DeteccaoFacialv6

    I am using, above the code, this header file:
    -> #include "Tserial.h"

    Any hint?

    Much appreciated, pal!

    ReplyDelete
  2. sorry for distrubing you, but i just want to share the article about face detection,
    let's check this link http://repository.gunadarma.ac.id/bitstream/123456789/3365/1/Automed%20Face%20Detection%20and%20Feature%20Extraction%20Using%20Color%20Feret%20Image%20Database.pdf
    i wish that article can be usefull

    ReplyDelete
  3. the web cam window appears and disappears
    i dont understand the problem .
    im new to open cv.

    ReplyDelete