人脸识别源代码Open cv

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include "cv.h"
  4 #include "cvaux.h"
  5 #include "highgui.h"
  6 
  7 using namespace cv;
  8 
  9 //globle variables
 10 int nTrainFaces         = 0;    // number of trainning images
 11 int nEigens             = 0;    // number of eigenvalues
 12 IplImage** faceImgArr         = 0;     // array of face images
 13 CvMat* personNumTruthMat     = 0;    // array of person numbers
 14 IplImage* pAvgTrainImg         = 0;    // the average image
 15 IplImage** eigenVectArr     = 0;    // eigenvectors
 16 CvMat* eigenValMat         = 0;    // eigenvalues
 17 CvMat* projectedTrainFaceMat     = 0;    // projected training faces
 18 
 19 //// Function prototypes
 20 void learn();
 21 void recognize();
 22 void doPCA();
 23 void storeTrainingData();
 24 int loadTrainingData(CvMat** pTrainPersonNumMat);
 25 int findNearestNeighbor(float* projectedTestFace);
 26 int loadFaceImgArray(char* filename);
 27 void printUsage();
 28 
 29 int main( int argc, char** argv )
 30 {
 31     if((argc != 2) && (argc != 3)){
 32     printUsage();
 33     return -1;
 34     }
 35 
 36     if( !strcmp(argv[1], "train" )){
 37     learn();
 38     } else if( !strcmp(argv[1], "test") ){
 39     recognize();
 40     } else {
 41     printf("Unknown command: %s
", argv[1]);
 42     }
 43     return 0;
 44 }
 45 
 46 void printUsage(){
 47     printf("Usage: eigenface <command>
",
 48     "  Valid commands are
"
 49     "    train
"
 50     "    test
"
 51     );
 52 }
 53 
 54 void learn(){
 55     int i;
 56 
 57     // load training data
 58     nTrainFaces = loadFaceImgArray("train.txt");
 59     if( nTrainFaces < 2){
 60     fprintf(
 61         stderr,
 62         "Need 2 or more training faces
"
 63           "Input file contains only %d
",
 64         nTrainFaces   
 65     );
 66     return;
 67     }
 68 
 69     // do PCA on the training faces
 70     doPCA();
 71 
 72     // project the training images onto the PCA subspace
 73     projectedTrainFaceMat = cvCreateMat(nTrainFaces, nEigens, CV_32FC1);
 74     for(i = 0; i < nTrainFaces; i ++){
 75     cvEigenDecomposite(
 76         faceImgArr[i],
 77         nEigens,
 78         eigenVectArr,
 79         0, 0,
 80         pAvgTrainImg,
 81         projectedTrainFaceMat->data.fl + i*nEigens
 82     );
 83     }
 84 
 85     // store the recognition data as an xml file
 86     storeTrainingData();
 87 }
 88 
 89 int loadFaceImgArray(char* filename){
 90     FILE* imgListFile = 0;
 91     char imgFilename[512];
 92     int iFace, nFaces = 0;
 93 
 94     // open the input file
 95     imgListFile = fopen(filename, "r");
 96     
 97     // count the number of faces
 98     while( fgets(imgFilename, 512, imgListFile) ) ++ nFaces;
 99     rewind(imgListFile);
100 
101     // allocate the face-image array and person number matrix
102     faceImgArr = (IplImage **)cvAlloc( nFaces*sizeof(IplImage *) );
103     personNumTruthMat = cvCreateMat( 1, nFaces, CV_32SC1 );
104 
105     // store the face images in an array
106     for(iFace=0; iFace<nFaces; iFace++){
107     //read person number and name of image file
108       fscanf(imgListFile, "%d %s", personNumTruthMat->data.i+iFace, imgFilename);
109 
110     // load the face image
111     faceImgArr[iFace] = cvLoadImage(imgFilename, CV_LOAD_IMAGE_GRAYSCALE);
112     }
113 
114     fclose(imgListFile);
115 
116     return nFaces;
117 }
118 
119 void doPCA(){
120     int i;
121     CvTermCriteria calcLimit;
122     CvSize faceImgSize;
123 
124     // set the number of eigenvalues to use
125     nEigens = nTrainFaces - 1;
126 
127     // allocate the eigenvector images
128     faceImgSize.width = faceImgArr[0]->width;
129     faceImgSize.height = faceImgArr[0]->height;
130     eigenVectArr = (IplImage**)cvAlloc(sizeof(IplImage*) * nEigens);
131     for(i=0; i<nEigens; i++){
132     eigenVectArr[i] = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1);
133     }
134 
135     // allocate the eigenvalue array
136     eigenValMat = cvCreateMat( 1, nEigens, CV_32FC1 );
137 
138     // allocate the averaged image
139     pAvgTrainImg = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1);
140 
141     // set the PCA termination criterion
142     calcLimit = cvTermCriteria( CV_TERMCRIT_ITER, nEigens, 1);
143 
144     // compute average image, eigenvalues, and eigenvectors
145     cvCalcEigenObjects(
146     nTrainFaces,
147     (void*)faceImgArr,
148     (void*)eigenVectArr,
149     CV_EIGOBJ_NO_CALLBACK,
150     0,
151     0,
152     &calcLimit,
153     pAvgTrainImg,
154     eigenValMat->data.fl
155     );
156 }
157 
158 void storeTrainingData(){
159     CvFileStorage* fileStorage;
160     int i;
161    
162     // create a file-storage interface
163     fileStorage = cvOpenFileStorage( "facedata.xml", 0, CV_STORAGE_WRITE);
164 
165     // store all the data
166     cvWriteInt( fileStorage, "nEigens", nEigens);
167     cvWriteInt( fileStorage, "nTrainFaces", nTrainFaces );
168     cvWrite(fileStorage, "trainPersonNumMat", personNumTruthMat, cvAttrList(0, 0));
169     cvWrite(fileStorage, "eigenValMat", eigenValMat, cvAttrList(0,0));
170     cvWrite(fileStorage, "projectedTrainFaceMat", projectedTrainFaceMat, cvAttrList(0,0));
171     cvWrite(fileStorage, "avgTrainImg", pAvgTrainImg, cvAttrList(0,0));
172 
173     for(i=0; i<nEigens; i++){
174     char varname[200];
175     sprintf( varname, "eigenVect_%d", i);
176     cvWrite(fileStorage, varname, eigenVectArr[i], cvAttrList(0,0));
177     }
178 
179     //release the file-storage interface
180     cvReleaseFileStorage( &fileStorage );
181 }
182 
183 void recognize(){
184     int i, nTestFaces = 0;        // the number of test images
185     CvMat* trainPersonNumMat = 0;    // the person numbers during training    
186     float* projectedTestFace = 0;    
187 
188     // load test images and ground truth for person number
189     nTestFaces = loadFaceImgArray("test.txt");    
190     printf("%d test faces loaded
", nTestFaces);
191     
192     // load the saved training data
193     if( !loadTrainingData( &trainPersonNumMat ) ) return;
194 
195     // project the test images onto the PCA subspace
196     projectedTestFace = (float*)cvAlloc( nEigens*sizeof(float) );
197     for(i=0; i<nTestFaces; i++){
198     int iNearest, nearest, truth;
199 
200      // project the test image onto PCA subspace
201     cvEigenDecomposite(
202         faceImgArr[i],
203         nEigens,
204         eigenVectArr,
205             0, 0,
206         pAvgTrainImg,
207         projectedTestFace
208     );
209 
210     iNearest = findNearestNeighbor(projectedTestFace);
211     truth = personNumTruthMat->data.i[i];
212     nearest = trainPersonNumMat->data.i[iNearest];
213 
214     printf("nearest = %d, Truth = %d
", nearest, truth);
215     }
216 }
217 
218 int loadTrainingData(CvMat** pTrainPersonNumMat){
219     CvFileStorage* fileStorage;
220     int i;
221  
222     // create a file-storage interface
223     fileStorage = cvOpenFileStorage( "facedata.xml", 0, CV_STORAGE_READ );
224     if( !fileStorage ){
225     fprintf(stderr, "Can't open facedata.xml
");
226     return 0;
227     }
228 
229     nEigens = cvReadIntByName(fileStorage, 0, "nEigens", 0);
230     nTrainFaces = cvReadIntByName(fileStorage, 0, "nTrainFaces", 0);
231     *pTrainPersonNumMat = (CvMat*)cvReadByName(fileStorage, 0, "trainPersonNumMat", 0);
232     eigenValMat = (CvMat*)cvReadByName(fileStorage, 0, "eigenValMat", 0);
233     projectedTrainFaceMat = (CvMat*)cvReadByName(fileStorage, 0, "projectedTrainFaceMat", 0);
234     pAvgTrainImg = (IplImage*)cvReadByName(fileStorage, 0, "avgTrainImg", 0);
235     eigenVectArr = (IplImage**)cvAlloc(nTrainFaces*sizeof(IplImage*));
236     for(i=0; i<nEigens; i++){
237     char varname[200];
238     sprintf( varname, "eigenVect_%d", i );
239     eigenVectArr[i] = (IplImage*)cvReadByName(fileStorage, 0, varname, 0);
240     }
241 
242     // release the file-storage interface
243     cvReleaseFileStorage( &fileStorage );
244 
245     return 1;
246 }
247 
248 int findNearestNeighbor(float* projectedTestFace){
249     double leastDistSq = DBL_MAX;
250     int i, iTrain, iNearest = 0;
251 
252     for(iTrain=0; iTrain<nTrainFaces; iTrain++){
253     double distSq = 0;
254 
255     for(i=0; i<nEigens; i++){
256         float d_i = projectedTestFace[i] -
257         projectedTrainFaceMat->data.fl[iTrain*nEigens + i];
258         distSq += d_i*d_i;
259     }
260 
261     if(distSq < leastDistSq){
262         leastDistSq = distSq;
263         iNearest = iTrain;
264     }
265     }
266 
267     return iNearest;
268 }
原文地址:https://www.cnblogs.com/zzuyczhang/p/4346472.html