www.pudn.com > Eigenface.rar > eigenface.cpp
// eigenface.c, by Robin Hewitt, 2007 // edited by Xin QIao, AUG 2007 // // Example program showing how to implement eigenface with OpenCV // Usage: // // First, you need some face images. I used the ORL face database. // You can download it for free at // www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html // // List the training and test face images you want to use in the // input files train.txt and test.txt. (Example input files are provided // in the download.) To use these input files exactly as provided, unzip // the ORL face database, and place train.txt, test.txt, and eigenface.exe // at the root of the unzipped database. // // To run the learning phase of eigenface, enter // eigenface train // at the command prompt. To run the recognition phase, enter // eigenface test #include#include #include #include "cv.h" #include "cvaux.h" #include "highgui.h" //// Global variables IplImage ** faceImgArr = 0; // array of face images CvMat * personNumTruthMat = 0; // array of person numbers int nTrainFaces = 0; // the number of training images int nEigens = 0; // the number of eigenvalues IplImage * pAvgTrainImg = 0; // the average image IplImage ** eigenVectArr = 0; // eigenvectors CvMat * eigenValMat = 0; // eigenvalues CvMat * projectedTrainFaceMat = 0; // projected training faces //// Function prototypes void learn(); void recognize(); void doPCA(); void storeTrainingData(); int loadTrainingData(CvMat ** pTrainPersonNumMat); double * findNearestNeighbor(float * projectedTestFace); int loadFaceImgArray(char * filename); void printUsage(); ////////////////////////////////// // main() // int main( int argc, char** argv ) { // validate that an input was specified if( argc != 2 ) { printUsage(); return -1; } if( !strcmp(argv[1], "train") ) learn(); else if( !strcmp(argv[1], "test") ) recognize(); else { printf("Unknown command: %s\n", argv[1]); printUsage(); } return 0; } ////////////////////////////////// // learn() // void learn() { int i, j, k, offset; // load training data nTrainFaces = loadFaceImgArray("train.txt"); if( nTrainFaces < 2 ) { fprintf(stderr, "Need 2 or more training faces\n" "Input file contains only %d\n", nTrainFaces); return; } // do PCA on the training faces doPCA(); // project the training images onto the PCA subspace projectedTrainFaceMat = cvCreateMat( nTrainFaces, nEigens, CV_32FC1 ); offset = projectedTrainFaceMat->step / sizeof(float); for(i=0; i data.fl + i*nEigens); projectedTrainFaceMat->data.fl + i*offset); } // store the projectedTrainFaceMat as TrainFace.txt FILE * TrainfaceFile = 0; if( TrainfaceFile = fopen("TrainFace.txt", "w") ) { for(j = 0 ; j < nTrainFaces ; j++){ fprintf(TrainfaceFile,"%d ", j); for(k = 0; k < nEigens ; k++){ fprintf(TrainfaceFile, " %d : %f ", k, (projectedTrainFaceMat->data.fl + j*offset)[k] ); } fprintf(TrainfaceFile," -1 : ? \n"); } } // store the recognition data as an xml file storeTrainingData(); } ////////////////////////////////// // recognize() // void recognize() { int i, j, nTestFaces = 0; // the number of test images CvMat * trainPersonNumMat = 0; // the person numbers during training float * projectedTestFace = 0; // load test images and ground truth for person number nTestFaces = loadFaceImgArray("test.txt"); printf("%d test faces loaded\n", nTestFaces); // load the saved training data if( !loadTrainingData( &trainPersonNumMat ) ) return; // project the test images onto the PCA subspace projectedTestFace = (float *)cvAlloc( nEigens*sizeof(float) ); double * sim = (double *)cvAlloc( nEigens*sizeof(double) );; for(i=0; i data.i; //nearest = trainPersonNumMat->data.i[iNearest]; /* //sort int order[nTrainFaces]; order[0] = iNearest; double temp[nTrainFaces]; for ( j = 0; j < nTrainFaces; j++){ temp[j] = sim[j]; } for ( k = 0; k < nTrainFaces; k++){ //??tempñéõÌá³êªáÈîÜindex int result=0; double leastSim = DBL_MAX; //?ÓðtempñéõÌá³êªáÈîÜindex£¬??ìýresult for ( j = 0; j < nTrainFaces; j++){ if( temp[j] < leastSim ){ leastSim = temp[j]; result = j; } } order = result; //?tempñé?ÓðîÜõÌá³êªáÈöÇ?Ùé?ÓÞ temp[result] = DBL_MAX; //} */ printf("%d test image : \n",i+1); for ( k = 0; k < nTrainFaces; k++) printf("star : %d, simility : %f\n", k, sim[ k ]); //printf("nearest = %d, Truth = %d\n\n", nearest, truth); } } ////////////////////////////////// // loadTrainingData() // int loadTrainingData(CvMat ** pTrainPersonNumMat) { CvFileStorage * fileStorage; int i; // create a file-storage interface fileStorage = cvOpenFileStorage( "./data/facedata.xml", 0, CV_STORAGE_READ ); if( !fileStorage ) { fprintf(stderr, "Can't open facedata.xml\n"); return 0; } nEigens = cvReadIntByName(fileStorage, 0, "nEigens", 0); nTrainFaces = cvReadIntByName(fileStorage, 0, "nTrainFaces", 0); *pTrainPersonNumMat = (CvMat *)cvReadByName(fileStorage, 0, "trainPersonNumMat", 0); eigenValMat = (CvMat *)cvReadByName(fileStorage, 0, "eigenValMat", 0); projectedTrainFaceMat = (CvMat *)cvReadByName(fileStorage, 0, "projectedTrainFaceMat", 0); pAvgTrainImg = (IplImage *)cvReadByName(fileStorage, 0, "avgTrainImg", 0); eigenVectArr = (IplImage **)cvAlloc(nTrainFaces*sizeof(IplImage *)); for(i=0; i data.fl[iTrain*nEigens + i]; //distSq += d_i*d_i / eigenValMat->data.fl; // Mahalanobis distSq += d_i*d_i; // Euclidean /* ///////////////////////////////////////////////////////////////// double d_i = projectedTestFace * projectedTrainFaceMat->data.fl[iTrain*nEigens + i]; distSq += d_i; double d_x = projectedTestFace * projectedTestFace; double d_y = projectedTrainFaceMat->data.fl[iTrain*nEigens + i] * projectedTrainFaceMat->data.fl[iTrain*nEigens + i]; distSx += d_x; distSy += d_y; ///////////////////////////////////////////////////////////////// */ } sim[iTrain] = distSq; /* ///////////////////////////////////////////////////////////////// sim[iTrain] = fabs ( (double) (distSq / ( sqrt(distSx) * sqrt(distSy) ))); ///////////////////////////////////////////////////////////////// */ //if(distSq < leastDistSq) //{ // leastDistSq = distSq; // iNearest = iTrain; //} } return sim; } ////////////////////////////////// // doPCA() // void doPCA() { int i; CvTermCriteria calcLimit; CvSize faceImgSize; // set the number of eigenvalues to use nEigens = nTrainFaces-1; // allocate the eigenvector images faceImgSize.width = faceImgArr[0]->width; faceImgSize.height = faceImgArr[0]->height; eigenVectArr = (IplImage**)cvAlloc(sizeof(IplImage*) * nEigens); for(i=0; i data.fl); cvNormalize(eigenValMat, eigenValMat, 1, 0, CV_L1, 0); } ////////////////////////////////// // loadFaceImgArray() // int loadFaceImgArray(char * filename) { FILE * imgListFile = 0; char imgFilename[512]; int iFace, nFaces=0; // open the input file if( !(imgListFile = fopen(filename, "r")) ) { fprintf(stderr, "Can\'t open file %s\n", filename); return 0; } // count the number of faces while( fgets(imgFilename, 512, imgListFile) ) ++nFaces; rewind(imgListFile); // allocate the face-image array and person number matrix faceImgArr = (IplImage **)cvAlloc( nFaces*sizeof(IplImage *) ); personNumTruthMat = cvCreateMat( 1, nFaces, CV_32SC1 ); // store the face images in an array for(iFace=0; iFace data.i+iFace, imgFilename); */ fscanf(imgListFile, "%s", imgFilename); ///////////////////////////////////////////////////////////////////// // load the face image faceImgArr[iFace] = cvLoadImage(imgFilename, CV_LOAD_IMAGE_ANYCOLOR); IplImage* dst = cvCreateImage( cvSize(92,112), faceImgArr[iFace]->depth, faceImgArr[iFace]->nChannels); cvResize(faceImgArr[iFace], dst, CV_INTER_LINEAR); //strcat(FileName,".pgm"); //faceImgArr[iFace] = dst; cvSaveImage(imgFilename, dst); cvReleaseImage(&dst); faceImgArr[iFace] = cvLoadImage(imgFilename, CV_LOAD_IMAGE_GRAYSCALE); ///////////////////////////////////////////////////////////////////// if( !faceImgArr[iFace] ) { fprintf(stderr, "Can\'t load image from %s\n", imgFilename); return 0; } } fclose(imgListFile); return nFaces; } ////////////////////////////////// // printUsage() // void printUsage() { printf("Usage: eigenface \n", " Valid commands are\n" " train\n" " test\n"); } /*ïïßí?ú¼??ÍÅõÌîñØüîÜñ¼?¡£õÌ??î¤ÔÒÙÍ?ù»ßæà÷TrainFace.txtûúTestFace.txtÍêì¤ý¨ÞÅéÄ¡£ åýÍýßÌÞÅéÄåùú×Ëå?£¬???findNearestNeighborùÞ???ñéù¬ä²éÄñ¼?ÓüîÜݻݡ£ ?õóîÜËå?£¬Ê¦ì¤íÂ?ôøÜÆîÜÓøÕᣬÊ×Ê×üùÍýåýù¼£¬íÂ?ì¤ý¨ð«ÍÔîÜbaseline¡£ ù»ìéÜÆ£¬ä²?é©ÞÅéÄÌÚÊ¥êóüùîÜÝÂ?ß©Ûö£¬ð«ÍÔÝÂ?îÜõÌ?üùáãûúñ×Óø¡£*/