Changeset 76


Ignore:
Timestamp:
04/23/2009 05:05:31 PM (11 years ago)
Author:
dave
Message:

changed file format to xml, experimental multiple image/face matching, better makefile

Location:
foam/trunk/simple-faceident
Files:
7 added
8 edited

Legend:

Unmodified
Added
Removed
  • foam/trunk/simple-faceident/CHANGES

    r27 r76  
     1* load/save works via xml 
     2* added tinyxml 
     3* multiple face images 
     4* new makefile 
     5 
     6- version for used by INESC-ID at first review 
     7 
     8* added load and save 
     9* added yarp control interface 
     10* scene logic to create appear and disappear messages 
    111* added a simple yarp interface 
    212* help text 
  • foam/trunk/simple-faceident/Makefile

    r58 r76  
     1TARGET  := faceident 
     2 
     3SRCS    := src/main.cpp\ 
     4        src/FaceBank.cpp\ 
     5        src/Face.cpp\ 
     6        src/ImageUtils.cpp\ 
     7        src/SceneState.cpp\ 
     8        src/tinyxml.cpp\ 
     9        src/tinyxmlerror.cpp\ 
     10        src/tinyxmlparser.cpp 
     11 
     12CCFLAGS = `pkg-config --cflags opencv` -ggdb -Wall -O3 -ffast-math -Wno-unused -DTIXML_USE_STL  
     13LDFLAGS =  
     14LIBS    = `pkg-config --libs opencv` -lYARP_dev -lYARP_sig -lYARP_OS -lACE 
     15 
    116CC = g++ 
    2 CXXFLAGS = `pkg-config --cflags opencv` -ggdb -Wall -O3 -ffast-math -Wno-unused  
    3 LDFLAGS =  `pkg-config --libs opencv` -lYARP_dev -lYARP_sig -lYARP_OS -lACE 
     17OBJS    := ${SRCS:.cpp=.o}  
     18DEPS    := ${SRCS:.cpp=.dep}  
     19XDEPS   := $(wildcard ${DEPS})  
    420 
    5 all: simple-faceident 
     21.PHONY: all clean distclean  
     22all:: ${TARGET}  
    623 
    7 simple-faceident: main.o FaceBank.o ImageUtils.o SceneState.o 
    8         $(CC) main.o FaceBank.o ImageUtils.o SceneState.o -rdynamic -o simple-faceident $(LDFLAGS) 
     24ifneq (${XDEPS},)  
     25include ${XDEPS}  
     26endif  
    927 
    10 main.o: src/main.cpp 
    11         $(CC) $(CXXFLAGS) -c src/main.cpp 
     28${TARGET}: ${OBJS}  
     29        ${CC} ${LDFLAGS} -o $@ $^ ${LIBS} 
    1230 
    13 FaceBank.o: src/FaceBank.cpp 
    14         $(CC) $(CXXFLAGS) -c src/FaceBank.cpp 
     31${OBJS}: %.o: %.cpp %.dep  
     32        ${CC} ${CCFLAGS} -o $@ -c $<  
    1533 
    16 ImageUtils.o: src/ImageUtils.cpp 
    17         $(CC) $(CXXFLAGS) -c src/ImageUtils.cpp 
     34${DEPS}: %.dep: %.cpp Makefile  
     35        ${CC} ${CCFLAGS} -MM $< > $@  
    1836 
    19 SceneState.o: src/SceneState.cpp 
    20         $(CC) $(CXXFLAGS) -c src/SceneState.cpp 
     37clean::  
     38        -rm -f *~ src/*.o ${TARGET}  
    2139 
    22 clean: 
    23         rm -rf *.o simple-faceident 
    24  
    25  
     40distclean:: clean 
  • foam/trunk/simple-faceident/README

    r72 r76  
    2929/faceident-ctrl "clear"                         Clears all faces 
    3030/faceident-ctrl "idle"                          Switch to idle mode, mostly frees up cpu 
     31/faceident-ctrl "multiimages" 1/0               Turn on or off multiple images per face, experimental 
    3132 
    3233Faces are saved in png format along with a text file to map them to id numbers. The sessionname  
     
    5253* Try normalised cross correlation instead of image differencing 
    5354* Expose image size and error threshold via yarp 
    54 * Use tinyxml or something better for the serialisation 
    5555* Lighting is a problem 
    5656   - Ignore the problem 
    57    - Try the edge image trick 
     57   - Try the edge image + blur trick 
    5858   - LBP 
     59   - Store multiple faces per id, for different lighting conditions 
    5960 
    6061Questions to: 
     
    6263dave@fo.am 
    6364 
     65Notes 
     66----- 
     67 
     68Muliple face images 
     69------------------- 
     70 
     71Could works as normal but with additional: 
     72 
     73----> "new lighting" or "new session" 
     74 
     75recalibration results in additional id images for users (leaves existing ones alone) 
     76search checks each image for each user 
     77images added to saved set - possible to build up lots of images of users 
     78 
     79would this work in some initial calibration with different lighting setups, or as it went along? 
     80 
     81Edge image & blur 
     82----------------- 
     83 
     84Remove low frequency lighting information from the face images 
     85Blur the resulting edge images to make them more forgiving 
     86- Would this just remove shape information? needs testing 
     87 
     88 
     89 
     90 
     91 
  • foam/trunk/simple-faceident/src/FaceBank.cpp

    r64 r76  
    1818#include "ImageUtils.h" 
    1919#include "highgui.h" 
     20#include "tinyxml.h" 
    2021 
    2122#include <vector> 
     
    2930 
    3031///////////////////////////////////////////////////////////////////////////////// 
    31 // util for loading 
    32  
    33 int SplitString(const string& input, const string& delimiter, vector<string>& results, bool includeEmpties) 
    34 { 
    35     int iPos = 0; 
    36     int newPos = -1; 
    37     int sizeS2 = (int)delimiter.size(); 
    38     int isize = (int)input.size(); 
    39  
    40     if(isize == 0 || sizeS2 == 0) 
    41     { 
    42         return 0; 
    43     } 
    44  
    45     vector<int> positions; 
    46     newPos = input.find (delimiter, 0); 
    47  
    48     if( newPos < 0 ) return 0;  
    49  
    50     int numFound = 0; 
    51  
    52     while( newPos >= iPos ) 
    53     { 
    54         numFound++; 
    55         positions.push_back(newPos); 
    56         iPos = newPos; 
    57         newPos = input.find (delimiter, iPos+sizeS2); 
    58     } 
    59  
    60     if( numFound == 0 ) return 0; 
    61  
    62     for( int i=0; i <= (int)positions.size(); ++i ) 
    63     { 
    64         string s(""); 
    65         if( i == 0 )  
    66         {  
    67             s = input.substr( i, positions[i] );  
    68         } 
    69                 else 
    70                 { 
    71                 int offset = positions[i-1] + sizeS2; 
    72                 if( offset < isize ) 
    73                 { 
    74                     if( i == (int)positions.size() ) 
    75                     { 
    76                         s = input.substr(offset); 
    77                     } 
    78                     else if( i > 0 ) 
    79                     { 
    80                         s = input.substr( positions[i-1] + sizeS2,  
    81                               positions[i] - positions[i-1] - sizeS2 ); 
    82                     } 
    83                 } 
    84                 } 
    85                  
    86         if( includeEmpties || ( s.size() > 0 ) ) 
    87         { 
    88             results.push_back(s); 
    89         } 
    90     } 
    91     return numFound; 
    92 } 
    93  
    94 ///////////////////////////////////////////////////////////////////////////////// 
    95  
    96 Face::Face(IplImage *image) :  
    97 m_Image(image)  
    98 { 
    99 } 
    100  
    101 Face::~Face()  
    102 { 
    103         cvReleaseImage(&m_Image); 
    104 } 
    105  
    106 void Face::Learn(const IplImage *image, float blend) 
    107 { 
    108         CvSize sizea = cvGetSize(image); 
    109         CvSize sizeb = cvGetSize(m_Image); 
    110  
    111         assert(sizea.width == sizeb.width); 
    112         assert(sizea.height == sizeb.height); 
    113  
    114         float ret=0; 
    115  
    116     for(int y=0; y<sizea.height; y++) 
    117         { 
    118         for(int x=0; x<sizea.width; x++) 
    119                 { 
    120                         cvSet2D(m_Image,y,x,cvScalar( 
    121                                                 cvGet2D(m_Image,y,x).val[0]*(1 - blend) + cvGet2D(image,y,x).val[0]*blend, 
    122                                                 cvGet2D(m_Image,y,x).val[1]*(1 - blend) + cvGet2D(image,y,x).val[1]*blend, 
    123                                                 cvGet2D(m_Image,y,x).val[2]*(1 - blend) + cvGet2D(image,y,x).val[2]*blend)); 
    124                 } 
    125         } 
    126 } 
    127  
    128 ///////////////////////////////////////////////////////////////////////////////// 
    12932         
    13033FaceBank::FaceBank(unsigned int FaceWidth, unsigned int FaceHeight, float ErrorThresh) :  
    13134m_FaceWidth(FaceWidth), 
    13235m_FaceHeight(FaceHeight), 
    133 m_ErrorThresh(ErrorThresh) 
     36m_ErrorThresh(ErrorThresh), 
     37m_MultiFaceImages(false) 
    13438{ 
    13539} 
     
    14751        } 
    14852        m_FaceMap.clear(); 
    149 } 
    150  
    151 void FaceBank::Save(const std::string &filename) const 
    152 { 
    153         char fn[256]; 
    154         snprintf(fn,256,"%s.dat",filename.c_str()); 
    155         FILE *f=fopen(fn,"w"); 
    156          
    157         if (f==NULL) 
    158         { 
    159                 cerr<<"could not open file for saving: "<<filename<<endl; 
    160                 return; 
    161         } 
    162  
    163         char header[1024]; 
    164         snprintf(header,1024,"%d\n%d\n",0,m_FaceMap.size()); 
    165         fwrite(header,strlen(header),1,f); 
    166          
    167         for(map<unsigned int,Face*>::const_iterator i=m_FaceMap.begin(); i!=m_FaceMap.end(); ++i) 
    168         { 
    169                 char fn[256]; 
    170                 snprintf(fn,256,"%d\n%s-%d.png\n",i->first,filename.c_str(),i->first); 
    171                 fwrite(fn,strlen(fn),1,f); 
    172         } 
    173         fclose(f); 
    174          
    175         for(map<unsigned int,Face*>::const_iterator i=m_FaceMap.begin(); i!=m_FaceMap.end(); ++i) 
    176         { 
    177                 char fn[256]; 
    178                 snprintf(fn,256,"%s-%d.png",filename.c_str(),i->first); 
    179                 cvSaveImage(fn,i->second->m_Image); 
    180         } 
    181 } 
    182  
    183 void FaceBank::Load(const std::string &filename) 
    184 { 
    185         Clear(); 
    186  
    187         char fn[256]; 
    188         snprintf(fn,256,"%s.dat",filename.c_str()); 
    189         FILE *f=fopen(fn,"r"); 
    190          
    191         if (f==NULL) 
    192         { 
    193                 cerr<<"file not found: "<<filename<<endl; 
    194                 return; 
    195         } 
    196          
    197         fseek(f,0,SEEK_END); 
    198         unsigned int size=ftell(f); 
    199         fseek(f,0,SEEK_SET); 
    200          
    201         if (size==0) 
    202         { 
    203                 fclose(f); 
    204                 cerr<<"empty file: "<<filename<<endl; 
    205                 return; 
    206         } 
    207  
    208         if (size<0) 
    209         { 
    210                 fclose(f); 
    211                 cerr<<"error loading file: "<<filename<<" size: "<<size<<"??"<<endl; 
    212                 return; 
    213         } 
    214  
    215         char *data=new char[size+1];             
    216         fread(data,1,size,f); 
    217         data[size]='\0'; 
    218         fclose(f); 
    219          
    220         vector<string> items; 
    221         SplitString(data,"\n",items,true); 
    222  
    223         if (items.size()>3) 
    224         { 
    225                 int version=(int)atoi(items[0].c_str()); 
    226                 int count=(int)atoi(items[1].c_str()); 
    227                 for (int i=2; i<count*2+2; i+=2) 
    228                 { 
    229                         int ID=(int)atoi(items[i].c_str()); 
    230                         m_FaceMap[ID]=new Face(cvLoadImage(items[i+1].c_str())); 
    231                 } 
    232         } 
    23353} 
    23454 
     
    24868                // Check it doesn't look like any we have already recorded 
    24969                unsigned int checkid=0; 
    250                 if (Identify(faceresized,checkid)>0) 
    251                 { 
    252                         cerr<<"We've already seen this face: "<<checkid<<endl;   
     70                int imagenum=-1; 
     71                if (Identify(faceresized,checkid,imagenum)>0) 
     72                { 
     73                        cerr<<"We've already seen this face: "<<checkid<<":"<<imagenum<<endl;    
    25374                        return 0; 
    25475                } 
     
    26081         
    26182        // Does this face look like the one we already have for this id? 
    262         float error = Diff(faceresized,i->second->m_Image); 
     83        int facenum; 
     84        float error = i->second->FindSimilar(faceresized,facenum); 
    26385 
    26486        if (error<m_ErrorThresh)  
    26587        { 
    266                 cerr<<"adding to face "<<ID<<endl; 
     88                //cerr<<"adding to face:"<<ID<<" image:"<<facenum<<endl; 
    26789                // Blend this face into the one we have already 
    268                 i->second->Learn(faceresized,0.2); 
     90                i->second->Learn(faceresized,0.2,facenum); 
    26991                cvReleaseImage(&faceresized); 
    27092                ID=i->first; 
     
    27294        } 
    27395         
    274         cerr<<"false positive? "<<error<<" "<<ID<<endl; 
     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        } 
    275110         
    276111        return 0; 
    277112} 
    278113 
    279 float FaceBank::Identify(IplImage *face, unsigned int &ID) 
     114float FaceBank::Identify(IplImage *face, unsigned int &ID, int &imagenum) 
    280115{ 
    281116        IplImage *faceresized = cvCreateImage(cvSize(m_FaceWidth,m_FaceHeight),IPL_DEPTH_8U, face->nChannels); 
     
    293128        unsigned int best=0; 
    294129        Face* bestface=NULL; 
     130        imagenum=-1; 
    295131         
    296132        // look for the lowest error in the map of faces 
    297133        for(map<unsigned int,Face*>::iterator i=m_FaceMap.begin(); i!=m_FaceMap.end(); ++i) 
    298134        { 
    299                 float tmp = Diff(faceresized,i->second->m_Image); 
     135                int similarfacenum; 
     136                float tmp = i->second->FindSimilar(faceresized,similarfacenum); 
    300137                if (tmp<error) 
    301138                { 
     
    303140                        best=i->first; 
    304141                        bestface=i->second; 
     142                        imagenum=similarfacenum; 
    305143                } 
    306144        } 
     
    310148        { 
    311149                // blend this face into the one we have already 
    312                 bestface->Learn(faceresized,0); 
     150                bestface->Learn(faceresized,0,imagenum); 
    313151                cvReleaseImage(&faceresized); 
    314152                ID=best; 
     
    320158        return 0; 
    321159} 
     160 
     161void FaceBank::Save(const std::string &filename) const 
     162{ 
     163        char fn[256]; 
     164        snprintf(fn,256,"%s.xml",filename.c_str()); 
     165        FILE *f=fopen(fn,"w"); 
     166         
     167        if (f==NULL) 
     168        { 
     169                cerr<<"could not open file for saving: "<<filename<<endl; 
     170                return; 
     171        } 
     172         
     173        TiXmlElement facebank("facebank"); 
     174        facebank.SetAttribute("version", 1); 
     175 
     176        for(map<unsigned int,Face*>::const_iterator i=m_FaceMap.begin(); i!=m_FaceMap.end(); ++i) 
     177        { 
     178                TiXmlElement face("face"); 
     179                face.SetAttribute("id", i->first); 
     180                int imagenum=0; 
     181                 
     182                for(vector<IplImage *>::iterator im=i->second->m_ImageVec.begin(); 
     183                        im!=i->second->m_ImageVec.end(); im++) 
     184                { 
     185                        TiXmlElement image("image"); 
     186                        char fn[256]; 
     187                        snprintf(fn,256,"%s-id%04d-image%04d.png",filename.c_str(),i->first,imagenum); 
     188                         
     189                        cvSaveImage(fn,*im); 
     190                         
     191                        image.SetAttribute("filename", fn); 
     192                        face.InsertEndChild(image); 
     193                        imagenum++; 
     194                } 
     195                 
     196                facebank.InsertEndChild(face); 
     197        } 
     198 
     199        facebank.Print(f,0); 
     200        fclose(f); 
     201} 
     202 
     203void FaceBank::Load(const std::string &filename) 
     204{ 
     205        Clear(); 
     206        char fn[256]; 
     207        snprintf(fn,256,"%s.xml",filename.c_str()); 
     208         
     209        TiXmlDocument doc(fn); 
     210        if (!doc.LoadFile()) 
     211        { 
     212                cerr<<"could not load "<<fn<<" error:"<<doc.ErrorDesc()<<endl; 
     213                return; 
     214        } 
     215         
     216        TiXmlNode* root = doc.FirstChild("facebank"); 
     217        if(root!=NULL) 
     218        { 
     219                // loop over faces 
     220                TiXmlNode* face = root->FirstChild(); 
     221                while(face!=NULL) 
     222                {        
     223                        TiXmlElement* faceelem = face->ToElement(); 
     224                        if(faceelem) 
     225                        { 
     226                                unsigned int ID = atoi(faceelem->Attribute("id")); 
     227                                int count=0; 
     228                                // loop over images 
     229                                TiXmlNode* image = face->FirstChild(); 
     230                                while(image!=NULL) 
     231                                { 
     232                                        TiXmlElement* imageelem = image->ToElement(); 
     233                                        if(imageelem) 
     234                                        { 
     235                                                string filename=imageelem->Attribute("filename"); 
     236                                                if(count==0) m_FaceMap[ID]=new Face(cvLoadImage(filename.c_str())); 
     237                                                else m_FaceMap[ID]->AddImage(cvLoadImage(filename.c_str())); 
     238                                                count++; 
     239                                                image = image->NextSibling(); 
     240                                        } 
     241                                } 
     242                                face = face->NextSibling(); 
     243                        } 
     244                } 
     245        } 
     246        else 
     247        { 
     248                cerr<<"error parsing xml in "<<fn<<endl; 
     249        } 
     250} 
  • foam/trunk/simple-faceident/src/FaceBank.h

    r59 r76  
    1717#include <iostream> 
    1818#include <map> 
     19#include <vector> 
    1920#include <assert.h> 
    2021#include "cv.h" 
     22#include "Face.h" 
    2123 
    2224#ifndef FACE_BANK 
    2325#define FACE_BANK 
    24  
    25 ///////////////////////////////////////////////////////////////////////////////// 
    26 // A face representation for the facebank 
    27  
    28 class Face 
    29 { 
    30 public: 
    31         Face(IplImage *image); 
    32         ~Face(); 
    33  
    34         // Blends a newly detected face into this image, 
    35         // an attempt at making it a little more dynamic 
    36         // needs more testing. 
    37         void Learn(const IplImage *image, float blend); 
    38  
    39         IplImage *m_Image; 
    40 }; 
    4126 
    4227///////////////////////////////////////////////////////////////////////////////// 
     
    4934        // comparison, ErrorThresh is the error amount which will trigger a new face to be stored 
    5035        FaceBank(unsigned int FaceWidth, unsigned int FaceHeight, float ErrorThresh); 
    51          
    5236        ~FaceBank(); 
    5337 
     
    5943 
    6044        // Gives the id, given a face, and returns the confidence 
    61         float Identify(IplImage *face, unsigned int &ID); 
     45        float Identify(IplImage *face, unsigned int &ID, int &imagenum); 
     46         
     47        // Collect multiple images per user 
     48        void AllowMultiFaceImages(bool s) { m_MultiFaceImages=s; } 
    6249         
    6350        std::map<unsigned int, Face*> &GetFaceMap() { return m_FaceMap; } 
     
    7461        unsigned int m_FaceHeight; 
    7562        float m_ErrorThresh; 
     63        bool m_MultiFaceImages; 
    7664         
    7765        std::map<unsigned int, Face*> m_FaceMap; 
  • foam/trunk/simple-faceident/src/ImageUtils.cpp

    r72 r76  
    3434 
    3535///////////////////////////////////////////////////////////// 
     36// safe accessor, which returns 0 if out of range 
     37 
     38unsigned char SafeGet2D(const IplImage *image, int y, int x, int c) 
     39{ 
     40        CvSize size = cvGetSize(image); 
     41        if (x<0 || x>=size.width || y<0 || y>=size.height) 
     42        { 
     43                return 0; 
     44        } 
     45         
     46        return cvGet2D(image,y,x).val[c]; 
     47} 
     48 
     49///////////////////////////////////////////////////////////// 
    3650// paste an image over the top of another 
    3751 
    38 void BlitImage(IplImage *srcimage, IplImage *dstimage, CvPoint pos) 
     52void BlitImage(const IplImage *srcimage, IplImage *dstimage, CvPoint pos) 
    3953{ 
    4054        CvSize size = cvGetSize(srcimage); 
     
    95109// return a diff metric between two images (works in RGB) 
    96110 
    97 float Diff(IplImage *imagea, IplImage *imageb) 
     111float Diff(const IplImage *imagea, const IplImage *imageb) 
    98112{ 
    99113        CvSize sizea = cvGetSize(imagea); 
     
    123137// return a local binary patterns image of the src image 
    124138 
    125 unsigned char SafeGet2D(IplImage *image, int y, int x, int c) 
    126 { 
    127         CvSize size = cvGetSize(image); 
    128         if (x<0 || x>=size.width || y<0 || y>=size.height) 
    129         { 
    130                 return 0; 
    131         } 
    132          
    133         return cvGet2D(image,y,x).val[c]; 
    134 } 
    135  
    136 void LBPImage(IplImage *srcimage, IplImage *dstimage) 
     139 
     140void LBPImage(const IplImage *srcimage, IplImage *dstimage) 
    137141{ 
    138142        CvSize srcsize = cvGetSize(srcimage); 
     
    143147        assert(srcimage->nChannels == dstimage->nChannels); 
    144148 
     149    // for each pixel 
    145150    for(int y=0; y<srcsize.height; y++) 
    146151        { 
     
    148153                { 
    149154                        CvScalar sc; 
    150  
     155                         
     156                        // for each channel 
    151157                        for(int c=0; c<dstimage->nChannels; c++) 
    152158                        { 
     
    154160                                unsigned char o=cvGet2D(srcimage,y,x).val[c]; 
    155161                                unsigned char b=0; 
     162 
     163                                // loop through a 3x3 kernel 
    156164                                for (int kx=-1; kx<=1; kx++) 
    157165                                { 
     
    161169                                                if (!(kx==0 && ky==0)) 
    162170                                                { 
     171                                                        // threshold 
    163172                                                        if (o>SafeGet2D(srcimage,y+ky,x+kx,c)) 
    164173                                                        { 
    165                                                                 v&=1<<b; 
     174                                                                // bit magic 
     175                                                                v|=(1<<b); 
    166176                                                        } 
    167177                                                        b++; 
     
    175185        } 
    176186} 
     187 
     188///////////////////////////////////////////////////////////// 
     189// calculate a histogram 
     190 
     191unsigned int *HistMono8Bit(const IplImage *image) 
     192{ 
     193        assert(image->nChannels == 1); 
     194        assert(image->depth == 8); 
     195        CvSize size = cvGetSize(image); 
     196 
     197        unsigned int *h=new unsigned int[256]; 
     198 
     199        for(int i=0; i<256; i++) 
     200        { 
     201                h[i]=0; 
     202        } 
     203 
     204    // for each pixel 
     205    for(int y=0; y<size.height; y++) 
     206        { 
     207        for(int x=0; x<size.width; x++) 
     208                { 
     209                        h[(unsigned char)cvGet2D(image,y,x).val[0]]++; 
     210                } 
     211        } 
     212         
     213        return h; 
     214} 
     215 
     216///////////////////////////////////////////////////////////// 
     217// draw a histogram 
     218 
     219void DrawHistogram8(int x, int y, float scale, CvScalar colour, unsigned int *h, IplImage *img) 
     220{ 
     221        for(int i=0; i<256; i++) 
     222        { 
     223                cvLine(img, cvPoint(x+i,y),cvPoint(x+i,y+h[i]*-scale), colour);  
     224        } 
     225} 
  • foam/trunk/simple-faceident/src/ImageUtils.h

    r72 r76  
    1616 
    1717#include "cv.h" 
     18#include "highgui.h" 
    1819 
    1920#ifndef IMAGE_UTILS 
     
    2324 
    2425IplImage* SubImage(IplImage *image, CvRect roi); 
    25 void BlitImage(IplImage *srcimage, IplImage *dstimage, CvPoint pos); 
     26void BlitImage(const IplImage *srcimage, IplImage *dstimage, CvPoint pos); 
    2627void SubMean(IplImage *image); 
    27 float Diff(IplImage *imagea, IplImage *imageb); 
    28 void LBPImage(IplImage *srcimage, IplImage *dstimage); 
     28float Diff(const IplImage *imagea, const IplImage *imageb); 
     29void LBPImage(const IplImage *srcimage, IplImage *dstimage); 
     30unsigned int *HistMono8Bit(const IplImage *image); 
     31 
     32void DrawHistogram8(int x, int y, float scale, CvScalar colour, unsigned int *h, IplImage *img); 
    2933 
    3034#endif 
  • foam/trunk/simple-faceident/src/main.cpp

    r64 r76  
    3030#include <time.h> 
    3131#include <ctype.h> 
    32  
    33 //#include <unistd.h>  -iolanda commented this 
    3432 
    3533#include "FaceBank.h" 
     
    335333                                facebank.Save(b->get(1).asString().c_str()); 
    336334                        } 
     335                        else if (b->get(0).asString()=="multiimage") 
     336                        { 
     337                                facebank.AllowMultiFaceImages(b->get(1).asInt()); 
     338                        } 
    337339                } 
    338340 
     
    347349 
    348350                                unsigned int ID=999; 
     351                                int imagenum=-1; 
    349352                                float confidence=0; 
    350353                                // get the face area as a sub image 
     
    358361                                else 
    359362                                {        
    360                                         confidence=facebank.Identify(face,ID); 
     363                                        confidence=facebank.Identify(face,ID,imagenum); 
    361364                                } 
    362365 
     
    372375                                        int x=(facebank.GetFaceWidth()+1)*ID; 
    373376                                        int y=imgsize.height-facebank.GetFaceHeight(); 
     377                                        y-=(facebank.GetFaceHeight()+2)*imagenum; 
    374378                                        cvLine(small_img, cvPoint(r->x+r->width/2,r->y+r->height/2), 
    375379                                                cvPoint(x+facebank.GetFaceWidth()/2,y), color);                  
     
    423427                int x=(facebank.GetFaceWidth()+1)*ii->first; 
    424428                int y=imgsize.height-facebank.GetFaceHeight(); 
    425                 BlitImage(ii->second->m_Image,small_img,cvPoint(x,y)); 
     429                for(vector<IplImage *>::iterator im=ii->second->m_ImageVec.begin(); 
     430                        im!=ii->second->m_ImageVec.end(); im++) 
     431                { 
     432                        BlitImage(*im,small_img,cvPoint(x,y)); 
     433                        y-=facebank.GetFaceHeight()+2; 
     434                } 
    426435        } 
    427436#endif 
Note: See TracChangeset for help on using the changeset viewer.