1. 程式人生 > >機器視覺學習總結(二)—— LDA,PCA演算法與應用

機器視覺學習總結(二)—— LDA,PCA演算法與應用

//***************************** Face Recognize ***********************************
void train(){   
    // load training data  
    nTrainFaces = loadFaceImgArray("faceSample\\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);  
    for(int i = 0; i < nTrainFaces; i ++){  
		cvEigenDecomposite(  
			faceImgArr[i],  
			nEigens,  
			eigenVectArr,  
			0, 0,  
			pAvgTrainImg,  
			projectedTrainFaceMat->data.fl + i*nEigens  
		);  
	}  
    // store the recognition data as an xml file  
    storeTrainingData();  
} 

int loadFaceImgArray(char* filename){  
    FILE* imgListFile = 0;  
    char imgFilename[512];  
    int iFace, nFaces = 0;  

    // open the input file  
    imgListFile = fopen(filename, "r");  
      
    // 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<nFaces; iFace++){  
    //read person number and name of image file  
    fscanf(imgListFile, "%d %s", personNumTruthMat->data.i+iFace, imgFilename);  
  
    // load the face image  
    faceImgArr[iFace] = cvLoadImage(imgFilename, CV_LOAD_IMAGE_GRAYSCALE);  
    }  
	
    fclose(imgListFile);  
  
    return nFaces;  
}  

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<nEigens; i++){  
    eigenVectArr[i] = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1);  
    }  
    // allocate the eigenvalue array  
    eigenValMat = cvCreateMat( 1, nEigens, CV_32FC1 );  
    // allocate the averaged image  
    pAvgTrainImg = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1);    
    // set the PCA termination criterion  
    calcLimit = cvTermCriteria( CV_TERMCRIT_ITER, nEigens, 1);   
    // compute average image, eigenvalues, and eigenvectors  
    cvCalcEigenObjects(  
    nTrainFaces,  
    (void*)faceImgArr,  
    (void*)eigenVectArr,  
    CV_EIGOBJ_NO_CALLBACK,  
    0,  
    0,  
    &calcLimit,  
    pAvgTrainImg,  
    eigenValMat->data.fl  
    );  
}

void storeTrainingData(){  
    CvFileStorage* fileStorage;  
    int i;  
     
    // create a file-storage interface  
    fileStorage = cvOpenFileStorage( "facedata.xml", 0, CV_STORAGE_WRITE);  
  
    // store all the data  
    cvWriteInt( fileStorage, "nEigens", nEigens);  
    cvWriteInt( fileStorage, "nTrainFaces", nTrainFaces );  
    cvWrite(fileStorage, "trainPersonNumMat", personNumTruthMat, cvAttrList(0, 0));  
    cvWrite(fileStorage, "eigenValMat", eigenValMat, cvAttrList(0,0));  
    cvWrite(fileStorage, "projectedTrainFaceMat", projectedTrainFaceMat, cvAttrList(0,0));  
    cvWrite(fileStorage, "avgTrainImg", pAvgTrainImg, cvAttrList(0,0));  
  
    for(i=0; i<nEigens; i++){  
    char varname[200];  
    sprintf( varname, "eigenVect_%d", i);  
    cvWrite(fileStorage, varname, eigenVectArr[i], cvAttrList(0,0));  
    }  
  
    //release the file-storage interface  
    cvReleaseFileStorage( &fileStorage );  
}  
// Face Recognize by PCA EigenFace...
int PCA_recognize(IplImage* faceRegion)
{
	CvMat* trainPersonNumMat = 0;   // the person numbers during training      
    float* projectedTestFace = 0;

	 // load the saved training data  
    if( !loadTrainingData( &trainPersonNumMat ) ) return -1;

	 // project the test face region onto the PCA subspace  
    projectedTestFace = (float*)cvAlloc( nEigens*sizeof(float) );
    cvEigenDecomposite(  
        faceRegion,  
        nEigens,  
        eigenVectArr,  
            0, 0,  
        pAvgTrainImg,  
        projectedTestFace  
    );
	int iNearest, nearest; 
	iNearest = findNearestNeighbor(projectedTestFace);   
    nearest = trainPersonNumMat->data.i[iNearest]; 
	return nearest;
}