Saturday, October 22, 2011

Face Recognition using OpenCV2 and HaarCascade an Intro Part 2

After learning theory a bit in part1 now we lear how we can detect face in an image. Later we will extend this to detecting face from web cam and avi file. The code is very simple. We will load a image of a person in  IplImage structure. We also need to load haarcascader of frontal face will which enable us to detect the face in image. Opencv 2 provides many haar cascades of face, eye , nose etc which ever you want use. If you have installed openCV v2 in "C:/OpenCV2.0" ,you  find it in "C:/OpenCV2.0/data/haarcascades/ Location. Now will need to call "cvHaarDetectObjects" OpenCV Function to detect the faces.

Here is the program -

#include "cv.h"
#include "highgui.h"

#include 
#include 


#ifdef _EiC
#define WIN32
#endif

static CvMemStorage* storage_face = 0; //Memory Storage to Sore faces

static CvHaarClassifierCascade* cascade_face = 0; 

void detect_and_draw( IplImage* image );

//Haar cascade - if your openc CV is installed at location C:/OpenCV2.0/
const char* cascade_name_face ="C:/OpenCV2.0/data/haarcascades/haarcascade_frontalface_alt.xml";

/////////////////////////////////////////////////////////////////////////////////

int main()
{
 IplImage  *image =0;
 image = cvLoadImage("viv6v.jpg",1);
 if(!image)
 {
         printf("Error loading image\n");
         return -1;
    }
   
    cascade_face = (CvHaarClassifierCascade*)cvLoad( cascade_name_face, 0, 0, 0 );
    
    if( !cascade_face )
    {
        printf("ERROR: Could not load classifier of face  cascade\n" );
        return -1;
    }

    storage_face = cvCreateMemStorage(0);
    cvNamedWindow( "result", 1 );
    
    // Call function to detect and Draw rectagle around face
    detect_and_draw( image);

    // Wait for key event. 
    cvWaitKey(0);
               
    // release resourses
    cvReleaseImage( &image );
 cvReleaseHaarClassifierCascade(&cascade_face );
 cvReleaseMemStorage( &storage_face);
    cvDestroyWindow("result");

    return 0;
}

////////////////////////////  Function To detect face //////////////////////////

void detect_and_draw( IplImage* img )
{

    double scale = 2;
    
    // create a gray image for the input image
    IplImage* gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
    // Scale down the ie. make it small. This will increase the detection speed
    IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),cvRound (img->height/scale)),8, 1 );
    
    int i;

    cvCvtColor( img, gray, CV_BGR2GRAY );
    
 cvResize( gray, small_img, CV_INTER_LINEAR );
    
 // Equalise contrast by eqalizing histogram of image
    cvEqualizeHist( small_img, small_img );
    
 cvClearMemStorage( storage_face);

    if( cascade_face )
    {
         // Detect object defined in Haar cascade. IN our case it is face
         CvSeq* faces = cvHaarDetectObjects( small_img, cascade_face, storage_face,
                                            1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,
                                            cvSize(30, 30) );
        
        // Draw a rectagle around all detected face 
        for( i = 0; i < (faces ? faces->total : 0); i++ )
        {
            CvRect r = *(CvRect*)cvGetSeqElem( faces, i );
   cvRectangle( img, cvPoint(r.x*scale,r.y*scale),cvPoint((r.x+r.width)*scale,(r.y+r.height)*scale),CV_RGB(255,0,0),3,8,0 );
  
  }
    }

    cvShowImage( "result", img );
    cvReleaseImage( &gray );
    cvReleaseImage( &small_img );
}

/////////////////////////////////////////////////////////////////////////////////

Output - Image with 1 Face -

Output - Image with multiple Faces -

Face Recognition using OpenCV2 and HaarCascade an Intro Part 1

In this series of tutorial we will learn how to detect human face. OpenCV library provides very effictive method of object detection including face detection using  Haar Cascades.
The function -
CvSeq* cvHaarDetectObjects(const CvArr* image,CvHaarClassifierCascade* cascade,CvMemStorage* storage,double scale factor=1.1,int min neighbors=3,int flags=0,CvSize min size=cvSize(0,0) );

can detect objects in input image by using HaarCascade structure. But before we jump directly to program we first need to understand about it a bit.

Many approaches have been proposed for detecting and recognizing faces. One of them is a color based approach to face detection. Indeed, color is a low-level cue that can be implemented in a computationally fast and effective way for locating objects. Among the advantages of using color is the computational efficiency and robustness against some geometric changes, when the scene is observed under a uniform illumination field.

However, the main limitation with the use of color lies in its sensitivity to illumination changes. To overcome the limitations of the color based approach, well-known face detection algorithm was proposed by Paul Viola and Michel J.Jhones in 2001 (Paul Viola and Michel J.Jhones “Rapid Object Detection Using Haar-like Features with Cascade of Boosted Classifiers”,IEEE CVPR 2001.)

 It uses Haar-like features and AdaBoost learning algorithm. The Haar-like features are extracted using the notion of integral image which allows very fast feature extraction at different scales, while AdaBoost is used to select the most prominent features among a large number of extracted features and construct a strong classifier from boosting a set of weak classifiers. The use of a cascade of classifiers made this approach one of the first real-time frontal-view face detection methods.
First, a classifier (namely a cascade of boosted classifiers working with haar-like features) is trained with a few hundreds of sample views of a particular object (i.e., a face or a car), called positive examples, that are scaled to the same size (say, 20x20), and negative examples - arbitrary images of the same size.


After a classifier is trained, it can be applied to a region of interest (of the same size as used during the training) in an input image. The classifier gives outputs as "1" if the region is likely to show the object (i.e., face/car), and "0" otherwise. To search for the object in the whole image one can move the search window across the image and check every location using the classifier. The classifier is designed so that it can be easily "resized" in order to be able to find the objects of interest at different sizes, which is more efficient than resizing the image itself. So, to find an object of an unknown size in the image the scan procedure should be done several times at different scales.


The word "cascade" in the classifier name means that the resultant classifier consists of several simpler classifiers (stages) that are applied subsequently to a region of interest until at some stage the candidate is rejected or all the stages are passed. The word "boosted" means that the classifiers at every stage of the cascade are complex themselves and they are built out of basic classifiers using one of four different boosting techniques (weighted voting). Currently Discrete Adaboost, Real Adaboost, Gentle Adaboost and Logitboost are supported. The basic classifiers are decision-tree classifiers with at least 2 leaves. Haar-like features are the input to the basic classifers, and are calculated as described below. The current algorithm uses the following Haar-like features:


In part 2 we will write a C program to detect faces in an image.




Monday, August 1, 2011

Linking OpenCV 2 library in DEVC++

In my earlier post I have discussed how to link OpenCV 1.x with devC++. But with latest release of OpenCV version ie. OpenCV 2 or higher the earlier method will not work. This because, OpenCV have changed the directory structure. So lets learn how to link OpenCV 2 or higher library version in DevC++ IDE.
  • Goto Tools -> Compiler option 
  • In the pop up click on the plus button. This means you are adding new compiler setting. Add your fav. name eg - OpenCV2
  • Now you need to add compiler commands. Add -L"C:\OpenCV2.X\lib" -lcxcore2X0 -lcv2X0 -lcvaux2X0 -lhighgui2X0 -lml2X0  where X stands for version. Eg For open CV 2.0 add --L"C:\OpenCV2.0\lib" -lcxcore200 -lcv200 -lcvaux200 -lhighgui200 -lml200 . Similarly for OpenCV2.1 add -L"C:\OpenCV2.1\lib" -lcxcore210 -lcv210 -lcvaux210 -lhighgui210 -lml210
  • Add linker command similarly as above. -lcxcore2X0 -lcv2X0 -lcvaux2X0 -lhighgui2X0 -lml2X0 For open CV 2.0 add --L"C:\OpenCV2.0\lib" -lcxcore200 -lcv200 -lcvaux200 -lhighgui200 -lml200 . Similarly for OpenCV2.1 add -L"C:\OpenCV2.1\lib" -lcxcore210 -lcv210 -lcvaux210 -lhighgui210 -lml210
  • Goto Directories -> C includes. Add  C:\OpenCV2.0\include or C:\OpenCV2.1\include or C:\OpenCV2.2\include what ever version you have. I assume that you have installed openCV in C:\
  •  Goto Directories -> Library. Add  C:\OpenCV2.0\lib or C:\OpenCV2.1\libor C:\OpenCV2.2\lib what ever version you have.
  • Goto Directories -> Library. Add  C:\OpenCV2.0\bin or C:\OpenCV2.1\bin or C:\OpenCV2.2\bin what ever version you have. 
  • Now lets write a sample project for OpenCV. Open New project window  and select "Console Application".
  • Non in Project Option > Compiler chose "OpenCV2".
Thus you have successfully integrated OpenCV with DevC++.