source: level2/competencies/facedetect/FaceDetect.cpp @ 234

Revision 77, 6.5 KB checked in by amol, 11 years ago (diff)
Line 
1//----------------------------------------------
2// Heriot-Watt University
3// MACS
4// www.lirec.eu
5// author: Amol Deshmukh
6// Date: 17/03/2009
7//-----------------------------------------------
8
9
10
11#include "FaceDetect.h"
12#include <math.h>
13
14
15static CvMemStorage* storage = 0;
16static CvHaarClassifierCascade* cascade = 0;
17
18const char* cascade_name;
19CvCapture* capture = 0;
20IplImage *frame, *frame_copy = 0;
21IplImage *image = 0;
22
23
24//-------------------------------------------------------------
25
26FaceDetect::FaceDetect()
27{       
28        m_dScale = 1.20;
29        m_bflagShowResult = true;
30        m_dMidX = 0;
31        m_iNumFaces = 0;
32        m_bFaceDetected = false;
33        m_bUserProximicFlag = false;
34       
35       
36        cascade_name = "haarcascade_frontalface_alt.xml";
37        cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
38        storage = cvCreateMemStorage(0);
39                   
40        if( !cascade )
41        {
42           fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
43           fprintf( stderr,
44           "Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n" );
45        }
46
47        if(m_bflagShowResult)
48           cvNamedWindow( "result", 1 );
49
50
51}
52
53//-------------------------------------------------------------
54
55FaceDetect::~FaceDetect()
56{
57        cvDestroyWindow("result");
58               
59}
60
61//-------------------------------------------------------------
62
63void FaceDetect::StartFaceDetection(void)
64{
65        capture = cvCaptureFromCAM(0);
66
67       
68
69    if( capture )
70    {
71        for(;;)
72        {
73            frame = cvQueryFrame( capture );
74            if( !frame )
75                break;
76            if( !frame_copy )
77                frame_copy = cvCreateImage( cvSize(frame->width,frame->height),
78                                            IPL_DEPTH_8U, frame->nChannels );
79            if( frame->origin == IPL_ORIGIN_TL )
80                cvCopy( frame, frame_copy, 0 );
81            else
82                cvFlip( frame, frame_copy, 0 );
83
84            DetectAndDraw( frame_copy, m_dScale );
85       
86            if( cvWaitKey( 10 ) >= 0 )
87                goto _cleanup_;
88               
89        }
90
91        cvWaitKey(0);
92        _cleanup_:
93        cvReleaseImage( &frame_copy );
94        cvReleaseCapture( &capture );
95    }
96    else
97    {
98        printf("Failed to capture from camera\n");
99    }
100         
101}
102
103//-------------------------------------------------------------
104
105void FaceDetect::DetectAndDraw(IplImage* img, double m_dScale)
106{
107
108    IplImage *gray, *small_img;
109    int i, j;
110
111    gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
112    small_img = cvCreateImage( cvSize( cvRound (img->width/m_dScale),
113                         cvRound (img->height/m_dScale)), 8, 1 );
114
115    cvCvtColor( img, gray, CV_BGR2GRAY );
116    cvResize( gray, small_img, CV_INTER_LINEAR );
117    cvEqualizeHist( small_img, small_img );
118    cvClearMemStorage( storage );
119
120 
121
122   
123    if( cascade )
124    {
125        double t = (double)cvGetTickCount();
126        CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,
127                                            m_dScale, 3, 0
128                                            |CV_HAAR_FIND_BIGGEST_OBJECT
129                                            //|CV_HAAR_DO_ROUGH_SEARCH
130                                            //|CV_HAAR_DO_CANNY_PRUNING
131                                            //|CV_HAAR_SCALE_IMAGE
132                                            ,
133                                            cvSize(20, 20) );
134        t = (double)cvGetTickCount() - t;
135        //printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );
136
137        if(faces->total > 0)
138        {
139            CvRect* r = (CvRect*)cvGetSeqElem( faces, 0 );
140            int radius;
141            CvPoint center;
142            center.x = cvRound((r->x + r->width*0.5)*m_dScale);
143            center.y = cvRound((r->y + r->height*0.5)*m_dScale);
144            radius = cvRound((r->width + r->height)*0.25*m_dScale);
145
146            //cutout the portion which is detected as face
147         
148            cvSetImageROI(img, cvRect(cvRound(r->x*m_dScale),
149                        cvRound(r->y*m_dScale),cvRound(r->width*m_dScale),
150                        cvRound(r->height*m_dScale)));
151                       
152           
153                // redetect face for more accuracy
154                if(DetectSubFace(img))
155                {
156                       
157                        cvResetImageROI(img);
158                                       
159                                       
160                        m_dMidX = (img->width/2) - center.x;
161                        m_dMidY = (img->height/2) - center.y;
162               
163                        //face detect flag set to true
164                        m_bFaceDetected = true; 
165
166                        //calculate angles from detected face
167                        m_dAngleX = m_dMidX * (180.0/img->width);
168                        m_dAngleY = m_dMidY * (180.0/img->height);
169
170                        //std::cout << "Face Angle X " << m_dAngleX  << std::endl;
171                        //std::cout << "Face Angle Y " << m_dAngleY << std::endl;
172                       
173                        CvPoint pt1, pt2; //Create a point to represent the face locations
174                        pt1.x = r->x * m_dScale;
175                        pt2.x = (r->x + r->width) * m_dScale;
176                        pt1.y = r->y * m_dScale;
177                        pt2.y = (r->y + r->height) * m_dScale;
178
179                        cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
180
181                        // Calculate the area of the face bounding box
182                        int areaFace = 0;
183                        int areaImage = 0;
184                       
185                        //calculate difference in area of face bounding box and image size
186                        areaFace = r->height * r->width; 
187                        areaImage = img->width * img->height; 
188                        int areaDiff = areaImage - areaFace;
189 
190                        //std::cout << "Area difference "<< areaDiff << std::endl;
191                       
192                        // set flag if face  detected at threshold distance 80cm-100 cm (camera and resolution dependent)
193                        // resolution required 640 * 480 (can be modified acc to requirement)
194                        if(areaDiff < 297000)
195                        {                       
196                           m_bUserProximicFlag = true;
197                           std::cout << "User proximity 80cm to 100 cm "<< std::endl;
198                        }
199                        else
200                        {
201                            m_bUserProximicFlag = false;
202                           
203                        }
204                       
205                       
206                }
207               
208
209                cvResetImageROI(img); // ... and remove the ROI
210                m_iNumFaces = faces->total;
211
212        }
213       
214         
215    }
216
217  if(m_bflagShowResult)
218   cvShowImage( "result", img );
219
220    cvReleaseImage( &gray );
221    cvReleaseImage( &small_img );
222}
223
224//-------------------------------------------------------------
225
226int FaceDetect::DetectSubFace(IplImage* cvTempimage)
227{
228        //detect face in sub image
229        CvSeq* SubFaces = cvHaarDetectObjects( cvTempimage, cascade, storage,
230                                            m_dScale, 3, 0 |CV_HAAR_DO_CANNY_PRUNING,
231                                            cvSize(0, 0) );
232
233        //if face found                         
234        if(SubFaces->total == 1)
235           return 1;
236        else
237           return 0;
238
239}
240//-------------------------------------------------------------
241
242int main( int argc, char** argv )
243{
244 
245    FaceDetect face;
246   
247    //call face detection
248    face.StartFaceDetection();
249
250
251    printf("program working\n");
252    return 0;
253   
254}
255
Note: See TracBrowser for help on using the repository browser.