source: level2/competencies/faceclassifier/src/App.cpp @ 146

Revision 113, 6.3 KB checked in by dave, 10 years ago (diff)

first pass expression recgn

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_Classifier(NULL),
35m_FaceBank(NULL),
36m_FaceNum(1),
37m_Learn(true),
38frame(NULL),
39frame_copy(NULL),
40m_FrameNum(0)
41{
42        m_CtrlPort.open("/faceident-ctrl");
43       
44        if (filename=="")
45        {
46                m_Capture = cvCaptureFromCAM(0);
47        }
48        else
49        {
50                m_Capture = cvCaptureFromAVI(filename.c_str());
51        }
52       
53        assert(m_Capture);
54       
55        PCA pca(w*h);
56        //FILE *f=fopen("../no-redist/eigenspaces/spacek-50x80.pca", "rb");
57        FILE *f=fopen("../data/eigenspaces/spacek-20x30.pca", "rb");
58        pca.Load(f);
59        fclose(f);
60        pca.Compress(10,500);
61       
62        m_Classifier = new PCAClassifier(pca);
63        m_FaceBank = new FaceBank(w,h,0.4,0.1,m_Classifier);
64        cvInitFont( &m_Font, CV_FONT_HERSHEY_PLAIN, 0.5, 0.5, 0, 1, CV_AA );
65        cvInitFont( &m_LargeFont, CV_FONT_HERSHEY_PLAIN, 25, 25, 0, 10, CV_AA );
66   
67        cvNamedWindow( "face classifier", 1 );
68       
69        Benchmark("yale");
70}
71
72App::~App()
73{
74}
75
76static CvScalar colors[] =
77    {
78        {{0,0,255}},
79        {{0,128,255}},
80        {{0,255,255}},
81        {{0,255,0}},
82        {{255,128,0}},
83        {{255,255,0}},
84        {{255,0,0}},
85        {{255,0,255}},
86    };
87
88void App::Run()
89{
90        frame = cvQueryFrame( m_Capture );
91    if( !frame )
92        {
93                cerr<<"no frame captured"<<endl;
94                return;
95        }
96       
97        if( !frame_copy )
98        frame_copy = cvCreateImage( cvSize(frame->width,frame->height),
99                                    IPL_DEPTH_8U, frame->nChannels );
100    if( frame->origin == IPL_ORIGIN_TL )
101        cvCopy( frame, frame_copy, 0 );
102    else
103        cvFlip( frame, frame_copy, 0 );
104       
105        Image camera(frame_copy);
106        Update(camera);
107       
108        m_FrameNum++;
109#ifdef SAVE_FRAMES
110        char name[256];
111        sprintf(name,"out-%0.4d.jpg",m_FrameNum);
112        cerr<<"saving "<<name<<endl;
113        cvSaveImage(name,camera.m_Image);
114#endif
115
116        cvShowImage("face classifier", camera.m_Image);
117}
118
119void App::Update(Image &camera)
120{       
121        ///////////////////////////////////
122        // dispatch from input
123
124        int key=cvWaitKey(10);
125               
126        switch (key)
127        {
128                case 'd': m_Learn=false; break;
129                case '1': m_FaceNum=1; m_Learn=true; break;
130                case '2': m_FaceNum=2; m_Learn=true; break;
131                case '3': m_FaceNum=3; m_Learn=true; break;
132                case '4': m_FaceNum=4; m_Learn=true; break;
133                case '5': m_FaceNum=5; m_Learn=true; break;
134                case '6': m_FaceNum=6; m_Learn=true; break;
135                case '7': m_FaceNum=7; m_Learn=true; break;
136                case '8': m_FaceNum=8; m_Learn=true; break;
137                case '9': m_FaceNum=9; m_Learn=true; break;
138                case '0': m_FaceNum=0; m_Learn=true; break;
139                case 'c': m_FaceBank->Clear(); break;
140        }
141                       
142        vector<Rect> rects = m_FaceFinder.Find(camera,m_Learn);
143        for(vector<Rect>::iterator i = rects.begin(); i!=rects.end(); i++ )
144        {
145                unsigned int ID=999;
146                int imagenum=-1;
147                float confidence=0;
148                // get the face area as a sub image
149                Image face = camera.SubImage(*i);
150               
151                //face.SubMean();
152                //camera.Blit(face.Scale(w,h).RGB2GRAY(),100,100);
153               
154                // pass it into the face bank
155                if (m_Learn)
156                {
157                        confidence=m_FaceBank->Suggest(face,m_FaceNum);
158                        ID=m_FaceNum;
159                }
160                else
161                {       
162                        confidence=m_FaceBank->Identify(face,ID,imagenum);
163                }                               
164
165                // if it's recognised the face (should really check the confidence)
166                if (ID!=999)
167                {
168                        char s[32];
169                        map<int,string>::iterator d = m_DebugNames.find(ID);
170                        if (d!=m_DebugNames.end())
171                        {
172                                sprintf(s,"%s",d->second.c_str());
173                        }
174                        else
175                        {
176                                sprintf(s,"%d",ID);
177                        }
178                       
179                        cvPutText(camera.m_Image, s, cvPoint(i->x,i->y+i->h-5), &m_LargeFont, colors[ID]);
180
181                        if (!m_Learn)
182                        {
183                                m_SceneState.AddPresent(ID, SceneState::User(confidence));
184                        }
185                }
186
187                cvRectangle(camera.m_Image, cvPoint(i->x,i->y), cvPoint(i->x+i->w,i->y+i->h), colors[0]);
188        }
189
190        char info[256];
191        if (m_Learn)
192        {
193                snprintf(info,256,"Learning user :%d",m_FaceNum);
194               
195                PCAClassifier *c = static_cast<PCAClassifier*>(m_FaceBank->GetClassifier());
196                if (c->GroupExists(m_FaceNum))
197                {
198                        Vector<float> p = c->GetGroupMean(m_FaceNum);
199                        Vector<float> r = c->GetPCA().Synth(p);
200                        camera.Blit(Image(w,h,1,r),0,100);
201                }
202        }
203        else
204        {
205                snprintf(info,256,"Detecting users");
206        }
207       
208        cvPutText(camera.m_Image, info, cvPoint(10,10), &m_Font, colors[0]);
209
210        m_SceneState.Update();
211
212}
213
214void App::Benchmark(const string &test)
215{
216        cerr<<"Running benchmark test"<<endl;
217        string path(string("../data/benchmark/")+test);
218        vector<string> people=Glob(path+string("/training/*"));
219        int ID=0;
220        m_Learn=true;
221       
222        for(vector<string>::iterator pi=people.begin(); pi!=people.end(); ++pi)
223        {
224                m_DebugNames[ID]=pi->substr(pi->find_last_of("/")+1,pi->length());
225                vector<string> images=Glob(*pi+"/*.jpg");
226                for(vector<string>::iterator ii=images.begin(); ii!=images.end(); ++ii)
227                {
228                        cerr<<ID<<" "<<*ii<<endl;
229                        m_FaceNum=ID;
230                        Image image(*ii);
231                        Update(image);
232                        //string fn=*ii+"-out.png";
233                        //cvSaveImage(fn.c_str(),image.m_Image);
234                }
235                ID++;
236        }
237       
238        m_Learn=false;
239       
240        /*vector<string> images=Glob(path+string("/control/*.jpg"));
241        for(vector<string>::iterator ti=images.begin(); ti!=images.end(); ++ti)
242        {       
243                cerr<<*ti<<endl;
244                Image test(*ti);       
245                Update(test);
246                string fn=*ti+"-out.png";
247                cvSaveImage(fn.c_str(),test.m_Image);
248        }*/
249
250        int imgw=1024;
251        int imgh=768;
252        Image out(imgw,imgh,8,3);
253        int across=13;
254        int down=13;
255        int w=imgw/across;
256        int h=imgh/down;
257
258        int i=0;
259        vector<string> images=Glob(path+string("/test/*.jpg"));
260        for(vector<string>::iterator ti=images.begin(); ti!=images.end(); ++ti)
261        {       
262                cerr<<*ti<<endl;
263                Image test(*ti);       
264                Update(test);
265                int x=i%across;
266                int y=i/across;
267                out.Blit(test.Scale(w,h),x*w,y*h);
268                cerr<<x*w<<" "<<y*h<<endl;
269                i++;
270        }
271       
272        char fn[256];
273        snprintf(fn,256,"%s/out.jpg",path.c_str());
274        cvSaveImage(fn,out.m_Image);
275}
Note: See TracBrowser for help on using the repository browser.