source: QMUL/trunk/DistanceCheck/src/Face.cpp @ 21

Revision 21, 7.6 KB checked in by ginevra, 11 years ago (diff)
Line 
1/*
2AUTHOR: Ginevra Castellano
3Queen Mary University of London
4DATE: 03/2009
5VERSION: 1.0
6*/
7
8// This code is based on the face detection code provided by OpenCV
9
10#include "stdafx.h"
11
12#include "cv.h"
13#include "highgui.h"
14
15#include <stdio.h>
16
17#include <stdlib.h>
18#include <string.h>
19#include <assert.h>
20#include <math.h>
21#include <float.h>
22#include <limits.h>
23#include <time.h>
24#include <ctype.h>
25
26#include <vector>
27
28#include "distanceCheck.h"
29
30#ifdef _EiC
31#define WIN32
32#endif
33
34// Create memory for calculations
35static CvMemStorage* storage = 0;
36
37// Create a new Haar classifier
38static CvHaarClassifierCascade* cascade = 0;
39
40// Function prototype for detecting and drawing an object from an image
41// and returning the area of the bounding box
42
43int detect_and_draw(IplImage* image);
44
45// Create a string that contains the cascade name
46const char* cascade_name =
47    "haarcascade_frontalface_alt.xml";
48
49// Main function, defines the entry point for the program
50
51
52int main( int argc, char** argv )
53{
54        // Structure for getting video from camera or avi
55        CvCapture* capture = 0;
56
57        // Images to capture the frame from video or camera or from file
58    IplImage *frame, *frame_copy = 0;
59
60        // Used for calculations
61    int optlen = strlen("--cascade=");
62
63        // Input file name for avi or image file
64    const char* input_name;
65
66        // Check for the correct usage of the command line
67        if( argc > 1 && strncmp( argv[1], "--cascade=", optlen ) == 0 )
68    {
69        cascade_name = argv[1] + optlen;
70        input_name = argc > 2 ? argv[2] : 0;
71    }
72    else
73    {
74        cascade_name = "C:/Program Files/OpenCV/data/haarcascades/haarcascade_frontalface_alt.xml";
75       input_name = argc > 1 ? argv[1] : 0;
76    }
77
78        // Load the HaarClassifierCascade
79    cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
80
81         // Check whether the cascade has loaded successfully. Else report an error and quit
82    if( !cascade )
83    {
84        fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
85        fprintf( stderr,
86        "Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n" );
87        return -1;
88    }
89
90        // Allocate the memory storage
91    storage = cvCreateMemStorage(0);
92   
93        // Find whether to detect the object from file or from camera
94    if( !input_name || (isdigit(input_name[0]) && input_name[1] == '\0') )
95        capture = cvCaptureFromCAM( !input_name ? 0 : input_name[0] - '0' );
96    else
97        capture = cvCaptureFromAVI( input_name );
98
99        // Create a new named window with title: result
100    cvNamedWindow( "result", 1 );
101
102        // Object distanceCheck of the class "DistanceCheck"
103    DistanceCheck *distanceCheck = new DistanceCheck(4);
104       
105        int area = 0; // Area of the face bounding box
106       
107    // Find if the capture is loaded successfully or not
108        // If loaded succesfully, then:
109
110    if( capture )
111    {
112                // Capture from the camera (or avi file)
113        for(;;)
114        {
115
116                        // Capture the frame and load it in IplImage
117            if( !cvGrabFrame( capture ))
118                break;
119            frame = cvRetrieveFrame( capture );
120
121           
122                        // If the frame does not exist, quit the loop
123                        if( !frame )
124                break;
125
126                        // Allocate framecopy as the same size of the frame
127            if( !frame_copy )
128                frame_copy = cvCreateImage( cvSize(frame->width,frame->height),
129                                            IPL_DEPTH_8U, frame->nChannels );
130
131                        // Check the origin of image. If top left, copy the image frame to frame_copy.
132            if( frame->origin == IPL_ORIGIN_TL )
133                cvCopy( frame, frame_copy, 0 );
134           
135                        // Else flip and copy the image
136                        else
137                cvFlip( frame, frame_copy, 0 );
138           
139            // Call the function to detect and draw the face and return the area of the face bounding box
140            area = detect_and_draw(frame_copy);
141
142            // Call the function "addFaceVal" of the class "DistanceCheck" to store the values of the area of the bounding box in a vector
143                        distanceCheck->addFaceVal(area);
144
145                        // Call the function "getMovementType" of the class "DistanceCheck" to predict whether the user is staying still, approaching the camera or withdrawing
146                        switch (distanceCheck->getMovementType())
147                        {       
148                                case UNDEFINED:
149                                        printf("\nUndefined");
150                                        break;
151                            case STAYING_STILL:
152                                        printf("\nStaying still");
153                                        break;
154                            case APPROACHING:
155                                        printf("\nApproaching");
156                                        break;
157                                case WITHDRAWING:
158                                        printf("\nWithdrawing");
159                                        break;
160                        }
161
162
163                        // Wait for a while before proceeding to the next frame
164            if( cvWaitKey( 10 ) >= 0 )
165                break;
166        }
167
168                // Release the images, and capture memory
169        cvReleaseImage( &frame_copy );
170        cvReleaseCapture( &capture );
171    }
172
173        delete distanceCheck;
174
175    // Destroy the window previously created with filename: "result"
176    cvDestroyWindow("result");
177
178    return 0;
179}
180
181
182
183// Function to detect and draw any faces that is present in an image
184// It returns the area of the face bounding box
185
186int detect_and_draw( IplImage* img )
187
188{
189    int area = 0;
190
191    static CvScalar colors[] =
192    {
193        {{0,0,255}},
194        {{0,128,255}},
195        {{0,255,255}},
196        {{0,255,0}},
197        {{255,128,0}},
198        {{255,255,0}},
199        {{255,0,0}},
200        {{255,0,255}}
201    };
202
203    double scale = 1.3;
204
205       
206        // Create a new image based on the input image
207
208    IplImage* gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
209    IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),
210                         cvRound (img->height/scale)), 8, 1 );
211    int i;
212
213    cvCvtColor( img, gray, CV_BGR2GRAY );
214    cvResize( gray, small_img, CV_INTER_LINEAR );
215    cvEqualizeHist( small_img, small_img );
216   
217       
218        // Clear the memory storage which was used before
219        cvClearMemStorage( storage );
220
221
222        // Find whether the cascade is loaded, to find the faces. If yes, then:
223    if( cascade )
224    {
225        double t = (double)cvGetTickCount();
226
227
228                // There can be more than one face in an image. So create a growable sequence of faces.
229        // Detect the objects and store them in the sequence
230       CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,
231                                            1.1, 2, CV_HAAR_FIND_BIGGEST_OBJECT,
232                                            cvSize(30, 30) );
233               
234
235
236        t = (double)cvGetTickCount() - t;
237                int radius = 0;
238        printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );
239
240                // Loop the number of faces found.
241        for( i = 0; i < (faces ? faces->total : 0); i++ )
242        {
243                        // Create a new rectangle for drawing the face
244            CvRect* r = (CvRect*)cvGetSeqElem( faces, i ); 
245           
246                        // Create a point to represent the face locations
247                        CvPoint center;
248            radius = 0;
249
250                        CvPoint pt1, pt2; //Create a point to represent the face locations
251
252                        // Find the dimensions of the face,and scale it if necessary
253       
254
255                        pt1.x = r->x * scale;
256            pt2.x = (r->x + r->width) * scale;
257            pt1.y = r->y * scale;
258            pt2.y = (r->y + r->height) * scale;
259
260            cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
261
262                        // Calculate the area of the face bounding box
263
264                        area = abs(pt2.x-pt1.x)*abs(pt2.y-pt1.x); 
265        }
266    }
267
268        // Show the image in the window named "result"
269    cvShowImage( "result", img );
270   
271        // Release the images created.
272        cvReleaseImage( &gray );
273    cvReleaseImage( &small_img );
274       
275        return area; 
276}
Note: See TracBrowser for help on using the repository browser.