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

Revision 95, 5.1 KB checked in by dave, 10 years ago (diff)

eigenface user classification seems to work on the test video

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
21//#define SAVE_FRAMES
22
23using namespace std;
24
25int w=20;
26int h=30;
27
28App::App(const string &filename) :
29m_Capture(NULL),
30m_Cascade(NULL),
31m_Storage(NULL),
32m_Classifier(NULL),
33m_FaceBank(NULL),
34m_FaceNum(1),
35m_Learn(true),
36frame(NULL),
37frame_copy(NULL),
38m_FrameNum(0)
39{
40        m_CtrlPort.open("/faceident-ctrl");
41        m_Cascade = (CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_alt.xml", 0, 0, 0);
42        assert(m_Cascade);
43        m_Storage = cvCreateMemStorage(0);
44       
45        if (filename=="")
46        {
47                m_Capture = cvCaptureFromCAM(0);
48        }
49        else
50        {
51                m_Capture = cvCaptureFromAVI(filename.c_str());
52        }
53       
54        assert(m_Capture);
55       
56        PCA pca(w*h);
57        //FILE *f=fopen("../data/eigenspaces/spacek-50x80.pca", "rb");
58        FILE *f=fopen("../data/eigenspaces/spacek-20x30.pca", "rb");
59        pca.Load(f);
60        fclose(f);
61        pca.Compress(3,30);
62       
63        m_Classifier = new PCAClassifier(pca);
64        m_FaceBank = new FaceBank(w,h,0.2,0.1,m_Classifier);
65        cvInitFont( &m_Font, CV_FONT_HERSHEY_PLAIN, 0.5, 0.5, 0, 1, CV_AA );
66   
67        cvNamedWindow( "face classifier", 1 );
68}
69
70App::~App()
71{
72}
73
74static CvScalar colors[] =
75    {
76        {{255,255,255}},
77        {{0,128,255}},
78        {{0,255,255}},
79        {{0,255,0}},
80        {{255,128,0}},
81        {{255,255,0}},
82        {{255,0,0}},
83        {{255,0,255}}
84    };
85
86void App::Update()
87{       
88        frame = cvQueryFrame( m_Capture );
89    if( !frame )
90        {
91                cerr<<"no frame captured"<<endl;
92                return;
93        }
94       
95    if( !frame_copy )
96        frame_copy = cvCreateImage( cvSize(frame->width,frame->height),
97                                    IPL_DEPTH_8U, frame->nChannels );
98    if( frame->origin == IPL_ORIGIN_TL )
99        cvCopy( frame, frame_copy, 0 );
100    else
101        cvFlip( frame, frame_copy, 0 );
102       
103        /////////////////////////
104       
105        Image camera(frame_copy);
106       
107        cvClearMemStorage(m_Storage);
108
109        CvSeq* faces = cvHaarDetectObjects( camera.m_Image, m_Cascade, m_Storage,
110                        1.1, 2, 0
111                        //|CV_HAAR_FIND_BIGGEST_OBJECT
112                        //|CV_HAAR_DO_ROUGH_SEARCH
113                        //|CV_HAAR_DO_CANNY_PRUNING
114                        //|CV_HAAR_SCALE_IMAGE
115                        ,
116                        cvSize(30, 30) );
117               
118        ///////////////////////////////////
119        // dispatch from input
120
121        int key=cvWaitKey(10);
122               
123        switch (key)
124        {
125                case 'd': m_Learn=false; break;
126                case '1': m_FaceNum=1; m_Learn=true; break;
127                case '2': m_FaceNum=2; m_Learn=true; break;
128                case '3': m_FaceNum=3; m_Learn=true; break;
129                case '4': m_FaceNum=4; m_Learn=true; break;
130                case '5': m_FaceNum=5; m_Learn=true; break;
131                case '6': m_FaceNum=6; m_Learn=true; break;
132                case '7': m_FaceNum=7; m_Learn=true; break;
133                case '8': m_FaceNum=8; m_Learn=true; break;
134                case '9': m_FaceNum=9; m_Learn=true; break;
135                case '0': m_FaceNum=0; m_Learn=true; break;
136                case 'c': m_FaceBank->Clear(); break;
137        }
138                       
139        for(int i = 0; i < (faces ? faces->total : 0); i++ )
140        {
141                CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
142                CvMat small_img_roi;
143
144                unsigned int ID=999;
145                int imagenum=-1;
146                float confidence=0;
147                // get the face area as a sub image
148                Image face = camera.SubImage(r->x, r->y, r->width, r->height);
149               
150                //face.SubMean();
151                //camera.Blit(face.Scale(w,h).RGB2GRAY(),100,100);
152               
153                // pass it into the face bank
154                if (m_Learn)
155                {
156                        confidence=m_FaceBank->Suggest(face,m_FaceNum);
157                        ID=m_FaceNum;
158                }
159                else
160                {       
161                        confidence=m_FaceBank->Identify(face,ID,imagenum);
162                }                               
163
164                // if it's recognised the face (should really check the confidence)
165                if (ID!=999)
166                {
167                        char s[32];
168                        sprintf(s,"%d %0.2f",ID,confidence);
169                        cvPutText(camera.m_Image, s, cvPoint(r->x,r->y+r->height-5), &m_Font, colors[0]);
170
171                        if (!m_Learn)
172                        {
173                                m_SceneState.AddPresent(ID, SceneState::User(confidence));
174                        }
175                }
176
177                cvRectangle(camera.m_Image, cvPoint(r->x,r->y), cvPoint(r->x+r->width,r->y+r->height), colors[0]);
178        }
179
180        char info[256];
181        if (m_Learn)
182        {
183                snprintf(info,256,"Learning user :%d",m_FaceNum);
184               
185                PCAClassifier *c = static_cast<PCAClassifier*>(m_FaceBank->GetClassifier());
186                if (c->GroupExists(m_FaceNum))
187                {
188                        Vector<float> p = c->GetGroupMean(m_FaceNum);
189                        cerr<<p.Magnitude()<<endl;
190                        Vector<float> r = c->GetPCA().Synth(p);
191                        camera.Blit(Image(w,h,1,r),0,100);
192                }
193        }
194        else
195        {
196                snprintf(info,256,"Detecting users");
197        }
198       
199        cvPutText(camera.m_Image, info, cvPoint(10,10), &m_Font, colors[0]);
200
201        m_SceneState.Update();
202       
203    m_FrameNum++;
204#ifdef SAVE_FRAMES
205        char name[256];
206        sprintf(name,"out-%0.4d.jpg",m_FrameNum);
207        cerr<<"saving "<<name<<endl;
208        cvSaveImage(name,camera.m_Image);
209#endif
210
211        cvShowImage("face classifier", camera.m_Image);
212
213}
214
Note: See TracBrowser for help on using the repository browser.