www.pudn.com > pca_face_dectect.rar > pca_face_dectect.cpp


// pca_face_dectect.cpp : Defines the entry point for the console application. 
// 
 
#include "stdafx.h" 
 
#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(); 
 
int _tmain(int argc, char** argv) 
{ 
	    // validate that an input was specified 
 
    learn(); 
    recognize(); 
	system("pause"); 
	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; idata.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; idata.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; idata.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; idata.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; iFacedata.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"); 
}