source: foam/trunk/faceclassifier/src/App.cpp @ 96

Revision 96, 6.5 KB checked in by dave, 10 years ago (diff)

Benchmark testing added for the eigen face recognition

Line 
1// Copyright (C) 2009 foam
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation; either version 2 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16
17#include <assert.h>
18#include "App.h"
19#include "PCAClassifier.h"
20#include "FileTools.h"
21
22//#define SAVE_FRAMES
23
24using namespace std;
25
26//int w=50;
27//int h=80;
28
29int w=20;
30int h=30;
31
32App::App(const string &filename) :
33m_Capture(NULL),
34m_Cascade(NULL),
35m_Storage(NULL),
36m_Classifier(NULL),
37m_FaceBank(NULL),
38m_FaceNum(1),
39m_Learn(true),
40frame(NULL),
41frame_copy(NULL),
42m_FrameNum(0)
43{
44        m_CtrlPort.open("/faceident-ctrl");
45        m_Cascade = (CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_alt.xml", 0, 0, 0);
46        assert(m_Cascade);
47        m_Storage = cvCreateMemStorage(0);
48       
49        if (filename=="")
50        {
51                m_Capture = cvCaptureFromCAM(0);
52        }
53        else
54        {
55                m_Capture = cvCaptureFromAVI(filename.c_str());
56        }
57       
58        assert(m_Capture);
59       
60        PCA pca(w*h);
61        //FILE *f=fopen("../data/eigenspaces/spacek-50x80.pca", "rb");
62        FILE *f=fopen("../data/eigenspaces/spacek-20x30.pca", "rb");
63        pca.Load(f);
64        fclose(f);
65        pca.Compress(20,300);
66       
67        m_Classifier = new PCAClassifier(pca);
68        m_FaceBank = new FaceBank(w,h,0.4,0.1,m_Classifier);
69        cvInitFont( &m_Font, CV_FONT_HERSHEY_PLAIN, 0.5, 0.5, 0, 1, CV_AA );
70   
71        cvNamedWindow( "face classifier", 1 );
72       
73        Benchmark();
74}
75
76App::~App()
77{
78}
79
80static CvScalar colors[] =
81    {
82        {{255,255,255}},
83        {{0,0,0}},
84        {{0,128,255}},
85        {{0,255,255}},
86        {{0,255,0}},
87        {{255,128,0}},
88        {{255,255,0}},
89        {{255,0,0}},
90        {{255,0,255}}
91    };
92
93void App::Run()
94{
95        frame = cvQueryFrame( m_Capture );
96    if( !frame )
97        {
98                cerr<<"no frame captured"<<endl;
99                return;
100        }
101       
102        if( !frame_copy )
103        frame_copy = cvCreateImage( cvSize(frame->width,frame->height),
104                                    IPL_DEPTH_8U, frame->nChannels );
105    if( frame->origin == IPL_ORIGIN_TL )
106        cvCopy( frame, frame_copy, 0 );
107    else
108        cvFlip( frame, frame_copy, 0 );
109       
110        Image camera(frame_copy);
111        Update(camera);
112       
113        m_FrameNum++;
114#ifdef SAVE_FRAMES
115        char name[256];
116        sprintf(name,"out-%0.4d.jpg",m_FrameNum);
117        cerr<<"saving "<<name<<endl;
118        cvSaveImage(name,camera.m_Image);
119#endif
120
121        cvShowImage("face classifier", camera.m_Image);
122}
123
124void App::Update(Image &camera)
125{       
126        cvClearMemStorage(m_Storage);
127
128        int flags=0;
129        if (m_Learn) flags|=CV_HAAR_FIND_BIGGEST_OBJECT;
130
131        CvSeq* faces = cvHaarDetectObjects( camera.m_Image, m_Cascade, m_Storage,
132                        1.1, 2, flags
133                        //|CV_HAAR_FIND_BIGGEST_OBJECT
134                        //|CV_HAAR_DO_ROUGH_SEARCH
135                        //|CV_HAAR_DO_CANNY_PRUNING
136                        //|CV_HAAR_SCALE_IMAGE
137                        ,
138                        cvSize(30, 30) );
139               
140        ///////////////////////////////////
141        // dispatch from input
142
143        int key=cvWaitKey(10);
144               
145        switch (key)
146        {
147                case 'd': m_Learn=false; break;
148                case '1': m_FaceNum=1; m_Learn=true; break;
149                case '2': m_FaceNum=2; m_Learn=true; break;
150                case '3': m_FaceNum=3; m_Learn=true; break;
151                case '4': m_FaceNum=4; m_Learn=true; break;
152                case '5': m_FaceNum=5; m_Learn=true; break;
153                case '6': m_FaceNum=6; m_Learn=true; break;
154                case '7': m_FaceNum=7; m_Learn=true; break;
155                case '8': m_FaceNum=8; m_Learn=true; break;
156                case '9': m_FaceNum=9; m_Learn=true; break;
157                case '0': m_FaceNum=0; m_Learn=true; break;
158                case 'c': m_FaceBank->Clear(); break;
159        }
160                       
161        for(int i = 0; i < (faces ? faces->total : 0); i++ )
162        {
163                CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
164                CvMat small_img_roi;
165
166                unsigned int ID=999;
167                int imagenum=-1;
168                float confidence=0;
169                // get the face area as a sub image
170                Image face = camera.SubImage(r->x, r->y, r->width, r->height);
171               
172                //face.SubMean();
173                //camera.Blit(face.Scale(w,h).RGB2GRAY(),100,100);
174               
175                // pass it into the face bank
176                if (m_Learn)
177                {
178                        confidence=m_FaceBank->Suggest(face,m_FaceNum);
179                        ID=m_FaceNum;
180                }
181                else
182                {       
183                        confidence=m_FaceBank->Identify(face,ID,imagenum);
184                }                               
185
186                // if it's recognised the face (should really check the confidence)
187                if (ID!=999)
188                {
189                        char s[32];
190                        map<int,string>::iterator d = m_DebugNames.find(ID);
191                        if (d!=m_DebugNames.end())
192                        {
193                                sprintf(s,"%s %0.2f",d->second.c_str(),confidence);
194                        }
195                        else
196                        {
197                                sprintf(s,"%d %0.2f",ID,confidence);
198                        }
199                       
200                        cvPutText(camera.m_Image, s, cvPoint(r->x,r->y+r->height-5), &m_Font, colors[0]);
201
202                        if (!m_Learn)
203                        {
204                                m_SceneState.AddPresent(ID, SceneState::User(confidence));
205                        }
206                }
207
208                cvRectangle(camera.m_Image, cvPoint(r->x,r->y), cvPoint(r->x+r->width,r->y+r->height), colors[0]);
209        }
210
211        char info[256];
212        if (m_Learn)
213        {
214                snprintf(info,256,"Learning user :%d",m_FaceNum);
215               
216                PCAClassifier *c = static_cast<PCAClassifier*>(m_FaceBank->GetClassifier());
217                if (c->GroupExists(m_FaceNum))
218                {
219                        Vector<float> p = c->GetGroupMean(m_FaceNum);
220                        cerr<<p.Magnitude()<<endl;
221                        Vector<float> r = c->GetPCA().Synth(p);
222                        camera.Blit(Image(w,h,1,r),0,100);
223                }
224        }
225        else
226        {
227                snprintf(info,256,"Detecting users");
228        }
229       
230        cvPutText(camera.m_Image, info, cvPoint(10,10), &m_Font, colors[0]);
231
232        m_SceneState.Update();
233
234}
235
236void App::Benchmark()
237{
238        cerr<<"Running benchmark test"<<endl;
239        vector<string> people=Glob("../data/benchmark/trek/training/*");
240        int ID=0;
241        m_Learn=true;
242       
243        for(vector<string>::iterator pi=people.begin(); pi!=people.end(); ++pi)
244        {
245                m_DebugNames[ID]=pi->substr(pi->find_last_of("/")+1,pi->length());
246                vector<string> images=Glob(*pi+"/*.jpg");
247                for(vector<string>::iterator ii=images.begin(); ii!=images.end(); ++ii)
248                {
249                        cerr<<ID<<" "<<*ii<<endl;
250                        m_FaceNum=ID;
251                        Image image(*ii);
252                        Update(image);
253                        string fn=*ii+"-out.png";
254                        cvSaveImage(fn.c_str(),image.m_Image);
255                }
256                ID++;
257        }
258       
259        m_Learn=false;
260       
261        vector<string> images=Glob("../data/benchmark/trek/control/*.jpg");
262        for(vector<string>::iterator ti=images.begin(); ti!=images.end(); ++ti)
263        {       
264                cerr<<*ti<<endl;
265                Image test(*ti);       
266                Update(test);
267                string fn=*ti+"-out.png";
268                cvSaveImage(fn.c_str(),test.m_Image);
269        }
270
271        images=Glob("../data/benchmark/trek/test/*.jpg");
272        for(vector<string>::iterator ti=images.begin(); ti!=images.end(); ++ti)
273        {       
274                cerr<<*ti<<endl;
275                Image test(*ti);       
276                Update(test);
277                string fn=*ti+"-out.png";
278                cvSaveImage(fn.c_str(),test.m_Image);
279        }
280}
Note: See TracBrowser for help on using the repository browser.