source: level2/competencies/DistanceCheck/src/Main.cpp @ 233

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