Wednesday, April 27, 2011

[Programming] OpenCV2.2 on EclipseIDE C++ Face Detection Example

Overview
I will demonstrate how to create OpenCV projects on Eclipse IDE for C++.

Goal here is to create Face tracking example using Eclipse IDE!!!
I will follow the information on this page>> written by
It is written for OpenCV2.0, so the instruction should apply to the OpenCV2.2 also...

1.  Install MinGW
You can download "Automated MinGW Installer from this page>>.
If you have older version installed, uninstall it and delete all the contents inside your C:/MinGW folder.
The one I'm using in this demo is "mingw-get-inst-20110316.exe".
When the installer asks for components to install, I selected select...
 - C++ compiler
 - ObjC Compiler
 - MinGW Developer ToolKit
Select whatever you think you would need for your further development.
I think, we just need C++ compiler for this demonstration ...
<!> After the installation, check your system path to see if "C:\MinGW\bin" is included or not...
On my machine, even if I marked the checkbox for adding path to system during the installation, it did not add the path... So, I did it manually.
Here is a link to the page explains how to add the path...
Do not forget restarting your PC!!!

2.  Install Eclipse
You can download Eclipse IDE from this page >>.
The version I'm using is "eclipse-cpp-helios-SR2-win32.zip".
After finish downloading, extract it to the place that you want...
I placed eclipse folder like this =>  C:\eclipse-cpp-helios-SR2-win32\eclipse\eclipse.exe
Create shortcut of eclipse.exe and place it on your desktop.

3.  Install OpenCV 2.2
OpenCV2.2 does not support MinGW by default... you have to create it by yourself.

I used this page as a reference...It is written for a Code Block...

3.1  Install Cmake
You will need "Cmake" to build your OpenCV for MinGW...
You can download it from this page>>.

3.2  Download and Extract OpenCV2.2-win.zip
Download "OpenCV-2.2.0-win.zip" from this page.
Extract the file under "C:/" (this can be anywhere... but if you have a " "(space) in your path, you will get error later...).
I extracted into "C:\OpenCV-2.2.0-win\OpenCV-2.2.0".

3.3  Run Cmake (cmake-gui)
3.4  Set  the source code "C:\OpenCV-2.2.0-win\OpenCV-2.2.0"
3.5  Set where to build the binaries e.g. "C:\OpenCV2.2MinGW"
3.6  Press Configure
3.7  Let Cmake create the new folder
3.8  Specify the generator "Eclipse CDT 4 - MinGW Makefiles". 
3.9  Select "Specify native compilers" and click next
3.10  For C, set "C:/MinGW/bin/gcc.exe".
3.11  For C++, set "C:/MinGW/bin/g++.exe".

3.12  Click Finish
<!> If your MinGW/bin is not added to your system path, it will generate a error says missing dll

3.13  In the configulation screen
Look for "CMAKE_BUILD_TYPE" and type in "DEBUG" or "Release".
Select Build Examples if you want...

3.14  Click Configure Again
3.15  Click generate
3.16  Close cmake

3.17  Make OpenCV
Go to the command prompt and inside the folder "C:\OpenCV2.2MinGW" type "mingw32-make" and hit enter (takes some time)  => took me 10 min...

3.18  Then type "mingw32-make install" and hit enter again 
3.19 Add  "C:\OpenCV2.2MinGW\bin" to your system path


4.  Creating New Project on Eclipse

4.1 Run Eclipse
You can run eclipse by double clicking eclipse.exe or the shortcut you've created.

4.2 Set workspace
It will ask for your workspace location.
I created folder for workspace like this
C:\Documents and Settings\masahiro\My Documents\Eclipse C++
Then Click "OK"

4.3 Start creating new project
If it shows startup menu, click on "Go to Workbench".
Go to File -> New -> C++ Project, then type in your project name "OpenCV2.2 FaceDetection".
Select "Hello World", instead of "Empty Project"... It will creates "src" and "debug" folder automatically, and it helps organizing your project.

4.4 Set Toolchain
Make sure that the "MinGW" is selected in "Toolchains".  If you don't see it there, your MinGW is not installed correctly...
Then click "Next".

4.5 Set project info
Put your name in "Author" and fill in other sections if you want to..., then click on "Next".

4.6 Advanced setting
Next window will let you set your configulation.
Click on "Advanced Setting".

4.7 Add path to includes
Go to "C/C++ Build" -> "Settings" and select "Tool Settings".
Under GCC C++ Compiler folder, look for "Includes" and click on it.
In the "Include paths (-l)", add OpenCV include directory.
Click on "Add" button and select from your "File System".
My OpenCV for MinGW is installed under C:/ and the include directory is "C:\OpenCV2.2MinGW\include".

4.8 Add Libraries
Under MinGW Linker, select "Libraries" and add following files to "Libraries (-l)"
- libopencv_highgui220d
- libopencv_ml220d
- libopencv_core220d
- libopencv_video220d
- libopencv_legacy220d
- libopencv_imgproc220d
- libopencv_objdetect220d
<!> xxxxd.lib is made for debug... for release build, use xxx.lib.  If you do not see xxxd.lib, you may forgot to configure cmake for debug at step 3.13.

4.9 Add Library Path
Add OpenCV Library folder to "Library search path (-L)".
"C:\OpenCV2.2MinGW\lib"

 4.10 Finishing up
Click "Apply", then click "OK". Finally, Click "Finish".

5.  Writing a Code

//=============================================
// Name        : OpenCV2.2 Face Detection.cpp
// Author      : Masahiro
// Version     :
// Copyright   : Open to anyone...
// Description : Face Detection example on OpenCV version 2.2
//=============================================

#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

using namespace std;
using namespace cv;


const String haarcascade_face = "C:/OpenCV2.2/data/haarcascades/haarcascade_frontalface_alt.xml";
const String haarcascade_eye = "C:/OpenCV2.2/data/haarcascades/haarcascade_eye_tree_eyeglasses.xml";

const double scale = 3.0;  //1.0 for 1:1 processing. use bigger number to increase the speed


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


int main (){
    CascadeClassifier cascade_face, cascade_eye;

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

    //load cascade file for face detection
    if(!cascade_face.load(haarcascade_face)){
        cerr << "ERROR: Could not load classifier cascade" << endl;
        return -1;
    }

    //load cascade file for eye detection
    if(!cascade_eye.load(haarcascade_eye)){
        cerr << "ERROR: Could not load classifier cascade" << endl;
        return -1;
    }

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

            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_:
        cvReleaseCapture( &capture );
    }

    return 0;
}


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



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



1 comment:

  1. Good post and Smart Blog
    Thanks for your good information and i hope to subscribe and visit my blog STD Symptoms and more Scabies Symptoms thanks again admin

    ReplyDelete