OpenCV

Learning OpenCV

Face detection, Image warping, and trackbar

Posted by rmehran on February 9, 2008

This is a sample program that demonstrates the how to use face detection, image warping, and trackbar GUI in OpenCV. Thanks to Bilal Orhan for providing his example code for image warping.

(Download Source)

// simple_face_detect_warp_trackbar.cpp : Defines the entry point for the console application.
//

#include “stdafx.h”

#include <cv.h>
#include <highgui.h>
#include <math.h>
#include <string>

static const double pi = 3.14159265358979323846;
#define N 500

inline static double square(int a)
{
return a * a;
}

int thresh = 11;
double scale = 1;

// define a trackbar callback
void on_trackbar(int h)
{
int b = h-11;
if(b<0)
scale = -1.0/(b-1);
else if(b>0)
scale = b*1.0+1;
else
scale = 1.0;
printf(“scale %d\n”,b);
}

// Create a string that contains the exact cascade name
const char* cascade_name =
“C:/Program Files/OpenCV/data/haarcascades/haarcascade_frontalface_alt.xml”;
/*    “haarcascade_profileface.xml”;*/

// Function prototype for detecting and drawing an object from an image
void detect_and_draw( IplImage* image , int scale,int min_neighbors,int min_size,IplImage* faceimg,  CvRect* tmprect );
/*
This will pop up a small box with “Hello World” as the text.
@author: Gavin Page, gsp8334@cs.rit.edu
@date: 28 November 2005
*/
int main( int argc, char** argv ) {

CvCapture* cap  = cvCaptureFromAVI(“C:\\Documents and Settings\\Ramin\\Desktop\\AVIPlayer\\VeryFunny_NEW.avi”);
int count = 1;

IplImage* img1 = cvQueryFrame(cap);
IplImage* img2 = cvQueryFrame(cap);
IplImage* gim1 = cvCreateImage(cvSize(img1->width,img1->height),IPL_DEPTH_8U, 1);
IplImage* gim2 = cvCreateImage(cvSize(img2->width,img2->height),IPL_DEPTH_8U, 1);

cvNamedWindow(“transformed”, 0);
cvNamedWindow(“org”, 0);
// create a toolbar
cvCreateTrackbar(“param”, “org”, &thresh, 21, on_trackbar);
on_trackbar(11);
int number_of_features = N;

img1 = cvQueryFrame(cap);
IplImage* sframe;
sframe = cvCreateImage(cvSize(img1->width/1,img1->height/1),img1->depth,img1->nChannels);

cvResize(img1,sframe);
cvFlip(sframe,sframe,0);
IplImage * faceimg = cvCreateImage(cvSize(sframe->width,sframe->height),sframe->depth,sframe->nChannels);
CvRect * tmprect = new CvRect();

while(1){

img1 = cvQueryFrame(cap);
cvResize(img1,sframe);
cvFlip(sframe,sframe,0);
detect_and_draw( sframe,1,1,0,faceimg,tmprect);

cvConvertImage( img1, gim1, CV_CVTIMG_FLIP );
cvWaitKey(1);
/*    img2 = cvQueryFrame(cap);
cvConvertImage( img2, gim2, CV_CVTIMG_FLIP );
*/

//feature points to track
/*    if( 0 ){ //save the image
char name[] = “c:\\flow\000.jpg”;

//name += 2*11;
name[11] = (char)(count % 10+48);
if(count >= 10 )
name[10] =(char)(count / 10+48);
if(count >= 100 )
name[9] =(char)(count / 100+48);

printf(“%s\n”,name);
cvSaveImage(name,gim1 );
count++;
}
*/    // map matrix for WarpAffine, stored in array

CvMat* map_matrix = cvCreateMat(2, 3, CV_32F);

int w = gim1->width;
int h = gim1->height;
double moveC = (scale-1)/2;

cvmSet(map_matrix ,0,0, scale);
cvmSet(map_matrix ,0,1, 0);
cvmSet(map_matrix ,0,2, -moveC*w);

cvmSet(map_matrix ,1,0, 0);
cvmSet(map_matrix ,1,1, scale);
cvmSet(map_matrix ,1,2, -moveC*h);

cvWarpAffine(gim1,gim2,map_matrix);

cvShowImage(“transformed”, gim2);

CvPoint p1,p2,q1,q2;

p1.x = (int)w/2-w/scale/2;
p1.y = (int) h/2 + h/scale/2;

p2.x = (int)w/2+w/scale/2;
p2.y = (int) h/2 + h/scale/2;

q1.x = (int)w/2-w/scale/2;
q1.y = (int) h/2 – h/scale/2;

q2.x = (int)w/2+w/scale/2;
q2.y = (int) h/2 – h/scale/2;

CvScalar color = CV_RGB(50,0,250);
cvLine( img1, p1, q1, color, 1, CV_AA, 0 );
cvLine( img1, p2, q2, color, 1, CV_AA, 0 );
cvLine( img1, p1, p2, color, 1, CV_AA, 0 );
cvLine( img1, q1, q2, color, 1, CV_AA, 0 );

cvShowImage(“org”, img1);
//cvResizeWindow( “HelloWorld”, 800, 800 );
//cvMoveWindow( “HelloWorld”, 200, 0 );

//if((cvWaitKey(100) & 255) == 27) break;
}

return 0;
}
// Function to detect and draw any faces that is present in an image
void detect_and_draw( IplImage* img, int scale,int min_neighbors,int min_size,IplImage* faceimg,  CvRect* tmprect )
{

// Create memory for calculations
static CvMemStorage* storage = 0;

// Create a new Haar classifier
static CvHaarClassifierCascade* cascade = 0;

//int scale = 1;

// Create a new image based on the input image
IplImage* temp = cvCreateImage( cvSize(img->width/scale,img->height/scale), 8, 3 );

// Create two points to represent the face locations
CvPoint pt1, pt2;
int i;

// Load the HaarClassifierCascade
cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );

// Check whether the cascade has loaded successfully. Else report and error and quit
if( !cascade )
{
fprintf( stderr, “ERROR: Could not load classifier cascade\n” );
return;
}

// Allocate the memory storage
storage = cvCreateMemStorage(0);

// Create a new named window with title: result
cvNamedWindow( “result”, 1 );

// Clear the memory storage which was used before
cvClearMemStorage( storage );

// Find whether the cascade is loaded, to find the faces. If yes, then:
if( cascade )
{

// There can be more than one face in an image. So create a growable sequence of faces.
// Detect the objects and store them in the sequence
CvSeq* faces = cvHaarDetectObjects( img, cascade, storage,
1.1, min_neighbors, CV_HAAR_DO_CANNY_PRUNING,
cvSize(min_size, min_size) );

// Loop the number of faces found.
for( i = 0; i < (faces ? faces->total : 0); i++ )
{
// Create a new rectangle for drawing the face
// CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
tmprect = (CvRect*)cvGetSeqElem( faces, i );
if (tmprect->height<= 0 ) continue;
cvSetImageROI( img, cvRect(tmprect->x*scale,tmprect->y*scale,tmprect->width*scale,tmprect->height*scale) );
//sprintf(file_num,”G:\\faces_from_movie\\%d.jpg”,int(framenum));
//cvReleaseImage(faceimg);
faceimg = cvCreateImage(cvSize(tmprect->width*scale,tmprect->height*scale),img->depth,img->nChannels);
//faceimg = cvCloneImage(img);
cvCopyImage(img,faceimg);
cvNamedWindow(“The Face”, 0);
cvShowImage(“The Face”, faceimg);

cvResetImageROI(img);

// Find the dimensions of the face,and scale it if necessary
pt1.x = tmprect->x*scale;
pt2.x = (tmprect->x+tmprect->width)*scale;
pt1.y = tmprect->y*scale;
pt2.y = (tmprect->y+tmprect->height)*scale;

// Draw the rectangle in the input image
cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
}
}

// Show the image in the window named “result”
cvShowImage( “result”, img );
//IplROI roi =  cvRectToROI(&r

// Release the temp image created.
cvReleaseImage( &temp );
}

Sample Image

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: