source: QMUL/DistanceCheck/Face.cpp @ 7

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