source: level2/competencies/FaceFinderUH/facedetect.cpp @ 230

Revision 230, 8.3 KB checked in by KDucasse, 10 years ago (diff)
Line 
1
2/*
3        Not a Very good face detector
4        Taken from an example of face detection from open cv, it uses more patterns to match (increasting CPU useage)
5        but has a system of calculating where the patterns converge to estimate likelyhood of a face, can work to a side
6        face as ears and faces in profile have been addid , if more side face patterns are added then im reasonably sure it
7        would be able to recognise the front,angle and side of face.
8
9        Has been used with YARP/SAMGAR etc, this will be changed shortly to co-inside with V3 samgar
10        K Du Casse ,20th july 09
11
12        ToDo : more patterns, more efficiency (this was a quick proto)
13
14*/
15
16
17        #include "cv.h"
18        #include "highgui.h"
19
20        #include <stdio.h>
21        #include <stdlib.h>
22        #include <string.h>
23        #include <assert.h>
24        #include <math.h>
25        #include <float.h>
26        #include <limits.h>
27        #include <time.h>
28        #include <ctype.h>
29        #include <list>
30        #include <yarp/os/all.h>
31
32        using namespace yarp::os;
33        using namespace std;
34
35
36        #ifdef _EiC
37        #define WIN32
38        #endif
39
40        static CvMemStorage* storage = 0;
41        static CvHaarClassifierCascade* cascade[13]; // we add alot more cascades and put them into an array
42        static float BestScore[20];
43        void detect_and_draw( IplImage* image );
44        void SendData(int x);
45        BufferedPort<Bottle> ctrlport;   
46
47        double scale = 1;
48
49        struct KStuff
50        {
51        int x,y,r;
52
53
54        };
55
56        using namespace std;
57
58
59        int main( int argc, char** argv )
60        {
61
62                CvCapture* capture = 0;
63                IplImage *frame, *frame_copy = 0;
64                IplImage *image = 0;
65
66                ctrlport.open("/CameraFace");
67                Network::connect("/CameraFace"  ,"/VirtualRobot","tcp",true);
68                Network::connect("/VirtualRobot","/CameraFace"  ,"tcp",true);
69
70
71                /* Load up a load of patterns, each patten addid will increase reliablity but increase time taken to recognise a face */
72
73                cascade[0] = (CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_alt.xml", 0, 0, 0 );
74                cascade[1] = (CvHaarClassifierCascade*)cvLoad("haarcascade_eye.xml", 0, 0, 0 );
75                cascade[2] = (CvHaarClassifierCascade*)cvLoad("haarcascade_eye_tree_eyeglasses.xml", 0, 0, 0 );
76                cascade[3] = (CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_alt2.xml", 0, 0, 0 );
77                cascade[4] = (CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_alt_tree.xml", 0, 0, 0 );
78                cascade[5] = (CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_default.xml", 0, 0, 0 );
79                cascade[6] = (CvHaarClassifierCascade*)cvLoad("haarcascade_profileface.xml", 0, 0, 0 );
80                cascade[7] = (CvHaarClassifierCascade*)cvLoad("ojoD.xml", 0, 0, 0 );
81                cascade[8] = (CvHaarClassifierCascade*)cvLoad("ojoI.xml", 0, 0, 0 );
82                cascade[9] = (CvHaarClassifierCascade*)cvLoad("parojos.xml", 0, 0, 0 );
83                cascade[10] = (CvHaarClassifierCascade*)cvLoad("parojosG.xml", 0, 0, 0 );
84                cascade[11] = (CvHaarClassifierCascade*)cvLoad("Mouth.xml", 0, 0, 0 );
85                cascade[12] = (CvHaarClassifierCascade*)cvLoad("Nariz.xml", 0, 0, 0 );
86
87
88         
89                storage = cvCreateMemStorage(0);
90                capture = cvCaptureFromCAM( 0);
91                cvNamedWindow( "result", 1 );
92                frame = cvRetrieveFrame( capture );
93                frame_copy = cvCreateImage( cvSize(frame->width,frame->height),IPL_DEPTH_8U, frame->nChannels );
94
95               
96                /*Main loop basicly initiate, look for faces and escape */
97                if( capture )
98                {
99                        for(;;)
100                        {
101                                frame = cvRetrieveFrame( capture );
102                                if( !frame ) break;
103
104                                if( frame->origin == IPL_ORIGIN_TL ){  cvCopy( frame, frame_copy, 0 );}
105                                else                                                            {       cvFlip( frame, frame_copy, 0 );}
106                   
107                                detect_and_draw( frame_copy );
108
109                                if( cvWaitKey( 10 ) >= 0 ){  goto _cleanup_;}
110                        }
111
112                        cvWaitKey(0);
113        _cleanup_:
114                        cvReleaseImage( &frame_copy );
115                        cvReleaseCapture( &capture );
116                }
117         
118           
119           
120                cvDestroyWindow("result");
121
122                return 0;
123        }
124
125        void SendData( int x)
126        {
127                puts("sending data");
128                Bottle& output = ctrlport.prepare();
129                output.clear();
130                output.addString("FaceLOC");
131                output.addInt(x);
132                ctrlport.write();
133        }
134
135        void detect_and_draw( IplImage* img )
136        {
137                static CvScalar colors[] =
138                {
139                        {{0,0,255}},
140                        {{0,128,255}},
141                        {{0,255,255}},
142                        {{0,255,0}},
143                        {{255,128,0}},
144                        {{255,255,0}},
145                        {{255,0,0}},
146                        {{255,0,255}}
147                };
148
149                IplImage *gray, *small_img;
150                int i,ii,count;
151                int radius,DisScore;
152                float PastBest;
153                int TempScore;
154                double Score;
155                double tolerance =0;
156                int totalpatternmatch=0;
157                double xdis,ydis,totaldis;
158                list<KStuff>::iterator it;
159                list<KStuff>::iterator it2;
160                 CvScalar color;
161        //      int Maxsize;
162                list <KStuff> ManyFaces;
163                KStuff BestFace;
164                KStuff Temp,Temp2;
165                CvPoint center;
166
167                char bufff[50];
168
169
170                gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
171                small_img = cvCreateImage( cvSize( cvRound (img->width/scale),
172                                                         cvRound (img->height/scale)), 8, 1 );
173
174                cvCvtColor( img, gray, CV_BGR2GRAY );
175                cvResize( gray, small_img, CV_INTER_LINEAR );
176                cvEqualizeHist( small_img, small_img );
177                cvClearMemStorage( storage );
178
179
180                ManyFaces.erase(ManyFaces.begin(),ManyFaces.end()); // erase the whole list
181
182         /* for each of the patterns */
183          for(ii=0;ii<7;ii++)
184          {
185                        // get the faces for that pattern
186                        CvSeq* faces = cvHaarDetectObjects( small_img, cascade[ii], storage,1.1, 2, 0|/*CV_HAAR_FIND_BIGGEST_OBJECT|*/CV_HAAR_DO_CANNY_PRUNING,cvSize(30, 30) );
187                        // for each face
188                        for( i = 0; i < (faces ? faces->total : 0); i++ ) // (faces ? faces->total : 0) think this is just the max so the colors mean nothing
189                        {
190                               
191                                CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
192
193                                if(cvRound(r->x + (r->width/2))>0&&cvRound(r->x + (r->width/2))<img->width&&cvRound(r->y + (r->height/2))>0&&cvRound(r->y + (r->height/2))<img->height)
194                                        {
195                                                // get its location
196                                                Temp.x=cvRound(r->x + (r->width/2));
197                                                Temp.y=cvRound(r->y + (r->height/2));
198                                                Temp.r=cvRound((r->width + r->height)*0.25);
199                                                ManyFaces.push_front(Temp);
200                                        }
201                         }
202          }
203        Score=0;
204        BestScore[0]=5000000;
205        DisScore=0;
206
207        // we now have a list of all the faces for each pattern,
208        // this enables us to check each face against each other face,
209        // they calculate the distance for each face, compared to each other face
210        // then gets the total distance/number of faces, this gives the average distance
211        // if this distance is low then it gets put in a placeholder for later
212          for ( it=ManyFaces.begin() ; it !=ManyFaces.end(); it++ )
213          {
214                  Score=0;
215                for ( it2=ManyFaces.begin() ; it2 !=ManyFaces.end(); it2++ )
216                {
217                Temp=*it;
218                Temp2=*it2;
219           
220                xdis=abs(Temp.x-Temp2.x)^2;
221                ydis=abs(Temp.y-Temp2.y)^2;
222                totaldis=sqrt(xdis+ydis);
223                Score+=totaldis-ManyFaces.size();///(ManyFaces.size()^8); // have to divide it otherwise if only one pattern matched then would have the best score
224                }
225                center.x=Temp.x;
226                center.y=Temp.y;
227                if(Temp.x>0&&Temp.x<img->width&&Temp.y>0&&Temp.y<img->height&&Temp.r<100)
228                        {
229                        cvCircle(img, center, Temp.r, color, 3, 8, 0 );
230                        }
231                if(Score<BestScore[0])
232                {
233                BestScore[0]=Score;
234                BestFace.r=Temp.r;
235                BestFace.x=Temp.x;
236                BestFace.y=Temp.y;
237                //sprintf(bufff,"Ave Best %d ",PastBest); // seems ok here
238                //puts(bufff);
239                }
240          }
241                PastBest=0;
242
243                // we know know the best distance, we make sure its not a invalid number
244                // we then average this against the past 19 values, so we can make sure that this reading isn't a blip
245
246                if(BestScore[0]!=5000000)
247                {
248                //      if(ManyFaces.size()<10){BestScore[0]+=50;}
249                //      BestScore[0]/=ManyFaces.size()^3;
250                        for(i=19;i>0;i--)
251                                {
252                                BestScore[i]=BestScore[i-1];
253                                }
254                        for(i=0;i<19;i++)
255                                {
256                                PastBest+=BestScore[i];
257                                }
258
259                // we then take this number and divide it by 20 (the amount of patterns)
260                // this gives us a nice number normally, plus when the patterns are far away from each other
261                // but if there close then we have a minus number.
262                PastBest/=20;
263
264                center.x=BestFace.x;
265                center.y=BestFace.y;
266                sprintf(bufff,"Ave Best %f ",PastBest);
267                //sprintf(bufff,"totalnum of faces %d ",ManyFaces.size());
268                puts(bufff);
269                }
270               
271                // if are number is less than zero, we draw a green circle on the pattern which is closest to all others.
272                tolerance+=PastBest/100;
273                if(BestFace.r>1 && PastBest<0+tolerance)
274                {
275                color=colors[3];
276                cvCircle(img, center, BestFace.r, color, 3, 8, 0 );
277                if(BestFace.x>(img->width/3)*2){SendData(-2);}
278                else                                               {SendData(2);}
279               
280                }
281       
282
283                cvShowImage( "result", img );
284                cvReleaseImage( &gray );
285                cvReleaseImage( &small_img );
286        }
Note: See TracBrowser for help on using the repository browser.