機器視覺學習總結(二)—— LDA,PCA演算法與應用
阿新 • • 發佈:2019-02-20
//***************************** 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; }