source: libs/libSamgar/examples/SamgarFaceDetect.cpp @ 445

Revision 445, 6.3 KB checked in by lmalek, 10 years ago (diff)

Samgar edition by WRUT. Based on Qt. Initial import.

Line 
1//----------------------------------------------
2// Heriot-Watt University
3// MACS
4// www.lirec.eu
5// author: Amol Deshmukh
6// Date: 10/03/2010
7//-----------------------------------------------
8
9#include <memory>
10#include <stdlib.h>
11#include <string.h>
12#include <assert.h>
13#include <math.h>
14#include <float.h>
15#include <limits.h>
16#include <time.h>
17#include <ctype.h>
18#include <iostream>
19#include "cv.h"
20#include "highgui.h"
21#include "cvaux.h"
22#include <Samgar.h>
23
24static CvMemStorage* storage = 0;
25static CvHaarClassifierCascade* cascade = 0;
26
27const char* cascade_name;
28CvCapture* capture = 0;
29IplImage *frame, *frame_copy = 0;
30IplImage *image = 0;
31
32bool m_bflagShowResult = true;
33int m_dMidX = 0;
34int m_dMidY = 0;
35int m_iNumFaces = 0;
36bool m_bFaceDetected = false;
37int m_bUserProximicFlag = 0;
38double m_dScale = 1.2;
39
40int DetectSubFace(IplImage* cvTempimage);
41void DetectAndDraw(IplImage* img, double m_dScale);
42
43
44int main()
45{
46  Network yarp;
47  Samgar::SamgarModule CameraRecive("FaceDetect", "FaceDetect",
48                                    "FaceDetect", Samgar::ModeRun);
49  // Cant have spaces or underscores
50  CameraRecive.SetupImagePort("VideoIn");
51  CameraRecive.AddPortS("Out");
52
53  cvNamedWindow( "result", CV_WINDOW_AUTOSIZE );
54   
55  cascade_name = "/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml";
56  cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
57  storage = cvCreateMemStorage(0);
58                           
59  if( !cascade )
60    {
61      fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
62      fprintf( stderr,"Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n" );
63    }
64
65  Bottle bot1;
66
67  while( 1 )
68  {
69    if (CameraRecive.getCurrentState() == Samgar::StateRunning)
70    {
71      IplImage *frame = CameraRecive.RecivePictureOCVNative();
72
73      if(frame!=false) // if there is no image available (one hasn't been sent) then the image will be false
74      {
75        if( !frame_copy )
76          frame_copy = cvCreateImage(cvSize(frame->width,frame->height) ,
77                                       IPL_DEPTH_8U, frame->nChannels );
78        if( frame->origin == IPL_ORIGIN_TL )
79          cvCopy( frame, frame_copy, 0 );
80        else
81          cvFlip( frame, frame_copy, 0 );
82
83        DetectAndDraw( frame_copy, m_dScale );
84
85        bot1.addInt(m_bFaceDetected);
86        bot1.addInt(m_bUserProximicFlag);
87        bot1.addDouble(m_dMidX);
88        CameraRecive.SendBottleData("Out",bot1);
89                       
90        //if( cvWaitKey( 50 ) >= 0 )
91        //  break;
92        //goto _cleanup_;
93
94        bot1.clear();
95      }
96    }
97    if( (cvWaitKey(50) & 255) == 27 ) break;
98    CameraRecive.SucceedFail(true,0);
99  }
100  // cvWaitKey(0);
101  //_cleanup_:
102  cvReleaseImage( &frame_copy );
103
104  cvDestroyWindow( "result" );
105  return 0;
106}
107
108
109void DetectAndDraw(IplImage* img, double m_dScale)
110{
111  m_bFaceDetected = false;
112  m_bUserProximicFlag = 0;
113  m_dMidX = 0;
114  m_dMidY = 0;
115
116  IplImage *gray, *small_img;
117  int i, j;
118
119  gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
120  small_img = cvCreateImage( cvSize( cvRound (img->width/m_dScale),
121                                     cvRound (img->height/m_dScale)), 8, 1 );
122
123  cvCvtColor( img, gray, CV_BGR2GRAY );
124  cvResize( gray, small_img, CV_INTER_LINEAR );
125  cvEqualizeHist( small_img, small_img );
126  cvClearMemStorage( storage );
127
128  double t = (double)cvGetTickCount();
129           
130  if( cascade )
131    {
132      double t = (double)cvGetTickCount();
133      CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,
134                                          m_dScale, 3, 0
135                                          |CV_HAAR_FIND_BIGGEST_OBJECT
136                                          //|CV_HAAR_DO_ROUGH_SEARCH
137                                          //|CV_HAAR_DO_CANNY_PRUNING
138                                          //|CV_HAAR_SCALE_IMAGE
139                                          , cvSize(20, 20) );
140
141      t = (double)cvGetTickCount() - t;
142      //printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );
143
144      if(faces->total > 0)
145        {
146          CvRect* r = (CvRect*)cvGetSeqElem( faces, 0 );
147          int radius;
148          CvPoint center;
149          center.x = cvRound((r->x + r->width*0.5)*m_dScale);
150          center.y = cvRound((r->y + r->height*0.5)*m_dScale);
151          radius = cvRound((r->width + r->height)*0.25*m_dScale);
152
153          //cutout the portion which is detected as face
154         
155          cvSetImageROI(img, cvRect(cvRound(r->x*m_dScale),
156                                    cvRound(r->y*m_dScale),cvRound(r->width*m_dScale),
157                                    cvRound(r->height*m_dScale)));
158                       
159           
160          // redetect face for more accuracy
161          if(DetectSubFace(img))
162            {
163                               
164              cvResetImageROI(img);
165                               
166              //face detected x,y positions on image
167              m_dMidX = (img->width/2) - center.x;
168              m_dMidY = (img->height/2) - center.y;
169                       
170              //face detect flag set to true
171              m_bFaceDetected = true; 
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              int facepercentage =  (areaFace * 100) / areaImage;
190         
191              printf("Face Percentage %d \n",facepercentage);
192
193              // set flag (m_bUserProximicFlag) if face  detected at threshold distance 80cm-100 cm
194              //(camera and resolution dependent) may have to change the facepercentage according to camera
195
196              if(facepercentage > 12)
197                m_bUserProximicFlag = 1;
198              else
199                m_bUserProximicFlag = 0;
200
201              printf("Face proxemics %d \n",m_bUserProximicFlag);
202              printf("Face side %d \n",m_dMidX);
203            }
204          cvResetImageROI(img); // ... and remove the ROI
205        }
206    }
207  cvShowImage( "result", img );
208
209  cvReleaseImage( &gray );
210  cvReleaseImage( &small_img );
211}
212
213//-------------------------------------------------------------
214
215int DetectSubFace(IplImage* cvTempimage)
216{
217  //detect face in sub image, to have more confidence in detected face
218  CvSeq* SubFaces = cvHaarDetectObjects( cvTempimage, cascade, storage,
219                                         m_dScale, 3, 0 |CV_HAAR_DO_CANNY_PRUNING,
220                                         cvSize(0, 0) );
221
222  //if face found                         
223  if(SubFaces->total == 1)
224    return 1;
225  else
226    return 0;
227
228}
229
Note: See TracBrowser for help on using the repository browser.