- Timestamp:
- 05/28/2009 03:52:09 PM (12 years ago)
- Location:
- foam/trunk/simple-faceident
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
foam/trunk/simple-faceident/README
r76 r84 13 13 face is given an ID based on it's closest match (within a given error 14 14 threshold) with the faces recorded during calibration. The boxes drawn around 15 the faces display the id and the confidence value of the match. When in this16 m ode the program sends the following YARP messages:15 the faces display the closest matched image, the id and confidence value of the 16 match. When in this mode the program sends the following YARP messages: 17 17 18 18 Output port Bottle contents Meaning … … 30 30 /faceident-ctrl "idle" Switch to idle mode, mostly frees up cpu 31 31 /faceident-ctrl "multiimages" 1/0 Turn on or off multiple images per face, experimental 32 /faceident-ctrl "errorthresh" value Set the error threshold (default 0.2) 33 /faceident-ctrl "newimagethresh" value Set the threshold greater than which new images are 34 stored in training (default 0.1) 32 35 33 Faces are saved in png format along with a textfile to map them to id numbers. The sessionname34 will be prepended onto the filenames for the textfile and the image files, so you can save36 Faces are saved in png format along with a xml file to map them to id numbers. The sessionname 37 will be prepended onto the filenames for the xml file and the image files, so you can save 35 38 multiple sessions. 36 39 … … 52 55 Todo: 53 56 * Try normalised cross correlation instead of image differencing 54 * Expose image size and error threshold via yarp 55 * Lighting is a problem 56 - Ignore the problem 57 - Try the edge image + blur trick 58 - LBP 59 - Store multiple faces per id, for different lighting conditions 57 * Expose image size via yarp 60 58 61 59 Questions to: … … 63 61 dave@fo.am 64 62 65 Notes66 -----67 68 Muliple face images69 -------------------70 71 Could works as normal but with additional:72 73 ----> "new lighting" or "new session"74 75 recalibration results in additional id images for users (leaves existing ones alone)76 search checks each image for each user77 images added to saved set - possible to build up lots of images of users78 79 would this work in some initial calibration with different lighting setups, or as it went along?80 81 Edge image & blur82 -----------------83 84 Remove low frequency lighting information from the face images85 Blur the resulting edge images to make them more forgiving86 - Would this just remove shape information? needs testing87 88 89 90 91 -
foam/trunk/simple-faceident/src/Face.h
r76 r84 26 26 ///////////////////////////////////////////////////////////////////////////////// 27 27 // A face representation 28 // 29 // Consists of a set of images representing an identity. 28 30 29 31 class Face -
foam/trunk/simple-faceident/src/FaceBank.cpp
r76 r84 31 31 ///////////////////////////////////////////////////////////////////////////////// 32 32 33 FaceBank::FaceBank(unsigned int FaceWidth, unsigned int FaceHeight, float ErrorThresh ) :33 FaceBank::FaceBank(unsigned int FaceWidth, unsigned int FaceHeight, float ErrorThresh, float NewImageThresh) : 34 34 m_FaceWidth(FaceWidth), 35 35 m_FaceHeight(FaceHeight), 36 36 m_ErrorThresh(ErrorThresh), 37 m_ MultiFaceImages(false)37 m_NewImageThresh(NewImageThresh) 38 38 { 39 39 } … … 67 67 { 68 68 // Check it doesn't look like any we have already recorded 69 unsigned int checkid=0;69 /*unsigned int checkid=0; 70 70 int imagenum=-1; 71 71 if (Identify(faceresized,checkid,imagenum)>0) … … 73 73 cerr<<"We've already seen this face: "<<checkid<<":"<<imagenum<<endl; 74 74 return 0; 75 } 75 }*/ 76 76 77 77 cerr<<"new face "<<ID<<endl; … … 86 86 if (error<m_ErrorThresh) 87 87 { 88 //cerr<<"adding to face:"<<ID<<" image:"<<facenum<<endl; 89 // Blend this face into the one we have already 90 i->second->Learn(faceresized,0.2,facenum); 91 cvReleaseImage(&faceresized); 92 ID=i->first; 88 if (error>m_NewImageThresh) 89 { 90 cerr<<"adding new image to face "<<error<<" "<<ID<<endl; 91 i->second->AddImage(faceresized); 92 } 93 else 94 { 95 //cerr<<"adding to face:"<<ID<<" image:"<<facenum<<endl; 96 // Blend this face into the one we have already 97 98 // removed this, as its potentially throwing away information 99 // multiple face images are better 100 //i->second->Learn(faceresized,0,facenum); 101 cvReleaseImage(&faceresized); 102 } 103 ID=i->first; 93 104 return 1-error; 94 }95 96 if (m_MultiFaceImages)97 {98 // Does it look like any we have already recorded for any face?99 unsigned int checkid=0;100 int imagenum=-1;101 if (Identify(faceresized,checkid,imagenum)>0)102 {103 cerr<<"We've already seen this face: "<<checkid<<":"<<imagenum<<endl;104 return 0;105 }106 107 cerr<<"too different - adding new image to face "<<error<<" "<<ID<<endl;108 i->second->AddImage(faceresized);109 105 } 110 106 … … 144 140 } 145 141 142 cvReleaseImage(&faceresized); 143 146 144 // if the error is less than the threshold, return the id 147 145 if (error<m_ErrorThresh) 148 146 { 149 // blend this face into the one we have already150 bestface->Learn(faceresized,0,imagenum);151 cvReleaseImage(&faceresized);152 147 ID=best; 153 148 return 1-error; … … 155 150 156 151 cerr<<"unrecognised face"<<endl; 157 158 152 return 0; 159 153 } -
foam/trunk/simple-faceident/src/FaceBank.h
r76 r84 27 27 ///////////////////////////////////////////////////////////////////////////////// 28 28 // A database of detected faces 29 // 30 // The facebank is mainly driven by calling Suggest() (which maps face images with 31 // id numbers) or Identify() which looks in it's current set of faces (and in the 32 // images contained in those faces) for the closest match. 33 // 34 // Thresholding explanations 35 // 36 // Suggest mode: 37 // 38 // Error -> 39 // 0 RelearnThresh ErrorThresh 1 40 // I----------------I------------------I------------------------------> 41 // Do nothing Add New Image Suggestion rejected 42 // 43 // In suggest mode, suggestions are also rejected if they are too similar 44 // to faces already in the bank - this is an attempt to make calibration 45 // possible while other people are in shot. 46 // 47 // Identify mode: 48 // 49 // Error -> 50 // 0 ErrorThresh 1 51 // I-----------------------------------I------------------------------> 52 // Match No match 53 // 54 // 29 55 30 56 class FaceBank … … 32 58 public: 33 59 // FaceWidth and FaceHeight are the size for the internal stored image of the face for 34 // comparison, ErrorThresh is the error amount which will trigger a new face to be stored 35 FaceBank(unsigned int FaceWidth, unsigned int FaceHeight, float ErrorThresh); 60 // comparison, ErrorThresh is the threshold at which a face will be considered as recognised, 61 // NewImageThresh is a threshold greater than which a suggested face will be stored as 62 // a new image. 63 FaceBank(unsigned int FaceWidth, unsigned int FaceHeight, float ErrorThresh, float NewImageThresh); 36 64 ~FaceBank(); 37 65 38 66 void Clear(); 67 68 void SetErrorThresh(float s) { m_ErrorThresh=s; } 69 void SetNewImageThresh(float s) { m_NewImageThresh=s; } 39 70 40 71 // Learn this face, the face may be a false positive, so we'll discard the … … 44 75 // Gives the id, given a face, and returns the confidence 45 76 float Identify(IplImage *face, unsigned int &ID, int &imagenum); 46 47 // Collect multiple images per user 48 void AllowMultiFaceImages(bool s) { m_MultiFaceImages=s; } 49 77 50 78 std::map<unsigned int, Face*> &GetFaceMap() { return m_FaceMap; } 51 79 … … 61 89 unsigned int m_FaceHeight; 62 90 float m_ErrorThresh; 63 bool m_MultiFaceImages;91 float m_NewImageThresh; 64 92 65 93 std::map<unsigned int, Face*> m_FaceMap; -
foam/trunk/simple-faceident/src/ImageUtils.cpp
r76 r84 63 63 { 64 64 cvSet2D(dstimage,y+pos.y,x+pos.x,cvGet2D(srcimage,y,x)); 65 } 66 } 67 } 68 } 69 70 ///////////////////////////////////////////////////////////// 71 // paste an image over the top of another, with transparency 72 73 void BlitImageAlpha(const IplImage *srcimage, IplImage *dstimage, CvPoint pos, float alpha) 74 { 75 CvSize size = cvGetSize(srcimage); 76 CvSize dstsize = cvGetSize(dstimage); 77 78 for(int y=0; y<size.height; y++) 79 { 80 for(int x=0; x<size.width; x++) 81 { 82 if (x+pos.x>0 && x+pos.x<dstsize.width && 83 y+pos.y>0 && y+pos.y<dstsize.height) 84 { 85 CvScalar sv = cvGet2D(srcimage,y,x); 86 CvScalar dv = cvGet2D(dstimage,y+pos.y,x+pos.x); 87 88 CvScalar out; 89 out.val[0]=sv.val[0]*alpha+dv.val[0]*(1-alpha); 90 out.val[1]=sv.val[1]*alpha+dv.val[1]*(1-alpha); 91 out.val[2]=sv.val[2]*alpha+dv.val[2]*(1-alpha); 92 93 cvSet2D(dstimage,y+pos.y,x+pos.x,out); 65 94 } 66 95 } -
foam/trunk/simple-faceident/src/ImageUtils.h
r76 r84 25 25 IplImage* SubImage(IplImage *image, CvRect roi); 26 26 void BlitImage(const IplImage *srcimage, IplImage *dstimage, CvPoint pos); 27 void BlitImageAlpha(const IplImage *srcimage, IplImage *dstimage, CvPoint pos, float alpha); 27 28 void SubMean(IplImage *image); 28 29 float Diff(const IplImage *imagea, const IplImage *imageb); -
foam/trunk/simple-faceident/src/main.cpp
r76 r84 66 66 ////////////////////////////////////////////////////////// 67 67 // These are the tweakable bits - see comments in FaceBank.h 68 FaceBank facebank(30, 40, 0. 15);68 FaceBank facebank(30, 40, 0.2, 0.1); //0.2 69 69 SceneState scenestate; 70 70 … … 104 104 ///////////////////////// 105 105 106 //facebank.Load("a"); 107 106 108 for( i = 1; i < argc; i++ ) 107 109 { … … 121 123 scale = 1; 122 124 } 125 else if( strncmp( argv[i], "--load=", 7 ) == 0 ) 126 { 127 cerr<<"loading "<<argv[i]+7<<endl; 128 facebank.Load(argv[i]+7); 129 } 123 130 else if( argv[i][0] == '-' ) 124 131 { … … 135 142 fprintf( stderr, "ERROR: Could not load classifier cascade\n" ); 136 143 fprintf( stderr, 137 "Usage: face detect [--cascade=\"<cascade_path>\"]\n"144 "Usage: faceident [--cascade=\"<cascade_path>\"]\n" 138 145 " [--nested-cascade[=\"nested_cascade_path\"]]\n" 139 146 " [--scale[=<image scale>\n" … … 242 249 243 250 CvFont font; 244 cvInitFont( &font, CV_FONT_HERSHEY_PLAIN, 2, 2, 0, 1, CV_AA );251 cvInitFont( &font, CV_FONT_HERSHEY_PLAIN, 0.75, 0.75, 0, 1, CV_AA ); 245 252 246 253 CvFont infofont; … … 333 340 facebank.Save(b->get(1).asString().c_str()); 334 341 } 335 else if (b->get(0).asString()=="multiimage") 336 { 337 facebank.AllowMultiFaceImages(b->get(1).asInt()); 342 else if (b->get(0).asString()=="errorthresh") 343 { 344 facebank.SetErrorThresh(b->get(1).asDouble()); 345 } 346 else if (b->get(0).asString()=="newimagethresh") 347 { 348 facebank.SetNewImageThresh(b->get(1).asDouble()); 338 349 } 339 350 } 340 351 341 352 /////////////////////////////////// 342 343 353 if (!idle) 344 354 { … … 372 382 char s[32]; 373 383 sprintf(s,"%d %0.2f",ID,confidence); 374 cvPutText(small_img, s, cvPoint(r->x,r->y+ 25), &font, color);375 int x=(facebank.GetFaceWidth()+ 1)*ID;384 cvPutText(small_img, s, cvPoint(r->x,r->y+r->height-5), &font, color); 385 int x=(facebank.GetFaceWidth()+8)*ID; 376 386 int y=imgsize.height-facebank.GetFaceHeight(); 377 y-=(facebank.GetFaceHeight()+2)*imagenum; 387 //y-=(facebank.GetFaceHeight()+2)*imagenum; 388 y-=5*imagenum; 389 378 390 cvLine(small_img, cvPoint(r->x+r->width/2,r->y+r->height/2), 379 cvPoint(x+facebank.GetFaceWidth()/2,y), color); 391 cvPoint(x+facebank.GetFaceWidth()/2,y+facebank.GetFaceHeight()/2), color); 392 393 cvRectangle(small_img,cvPoint(x-1,y-1),cvPoint(x+facebank.GetFaceWidth(),y+facebank.GetFaceHeight()), color); 394 395 if (imagenum>=0) 396 { 397 BlitImageAlpha(facebank.GetFaceMap()[ID]->m_ImageVec[imagenum],small_img,cvPoint(r->x,r->y),0.75); 398 } 380 399 381 400 if (!learn) … … 425 444 ii!=facebank.GetFaceMap().end(); ++ii) 426 445 { 427 int x=(facebank.GetFaceWidth()+ 1)*ii->first;446 int x=(facebank.GetFaceWidth()+8)*ii->first; 428 447 int y=imgsize.height-facebank.GetFaceHeight(); 429 448 for(vector<IplImage *>::iterator im=ii->second->m_ImageVec.begin(); 430 449 im!=ii->second->m_ImageVec.end(); im++) 431 450 { 451 //BlitImage(*im,small_img,cvPoint(x,y)); 432 452 BlitImage(*im,small_img,cvPoint(x,y)); 433 y-=facebank.GetFaceHeight()+2; 453 //y-=facebank.GetFaceHeight()+2; 454 y-=5; 434 455 } 435 456 } 436 457 #endif 437 458 459 438 460 cvShowImage( "result", small_img ); 439 461 framenum++; 440 462 #ifdef SAVE_FRAMES 441 463 char name[256]; 442 464 sprintf(name,"out-%0.4d.jpg",framenum); 465 cerr<<"saving "<<name<<endl; 443 466 cvSaveImage(name,small_img); 444 467 #endif
Note: See TracChangeset
for help on using the changeset viewer.