////////////////////////////////// // doPCA() // void faceRecognition::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, // Number of source objects. (void*)faceImgArr, // ... (void*)eigenVectArr, CV_EIGOBJ_NO_CALLBACK, //Input/output flags. 0, //Input/output buffer size in bytes. The size is zero, if unknown. 0, //Pointer to the structure that contains all necessary data for the callback functions. &calcLimit, //Determines conditions for the calculation to be finished. pAvgTrainImg, //Averaged object. eigenValMat->data.fl); //Pointer to the eigenvalues array in the descending order;may be NULL. //根据norm_type的不同值,图像src将被规范化 cvNormalize(eigenValMat, eigenValMat, 1, 0, CV_L1, 0); }
void doPCA() { int i; CvTermCriteria calcLimit; CvSize faceImgSize; numberOfEigenVectors = numberOfTrainingFaces-1; faceImgSize.width = faceImageArray[0]->width; faceImgSize.height = faceImageArray[0]->height; eigenVectorArray = (IplImage**)cvAlloc(sizeof(IplImage*) * numberOfEigenVectors); for (i=0; i<numberOfEigenVectors; i++) eigenVectorArray[i] = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1); eigenValueMatrix = cvCreateMat( 1, numberOfEigenVectors, CV_32FC1 ); averageTrainingImage = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1); calcLimit = cvTermCriteria( CV_TERMCRIT_ITER, numberOfEigenVectors, 1); cvCalcEigenObjects( numberOfTrainingFaces, (void*)faceImageArray, (void*)eigenVectorArray, CV_EIGOBJ_NO_CALLBACK, 0, 0, &calcLimit, averageTrainingImage, eigenValueMatrix->data.fl); cvNormalize(eigenValueMatrix, eigenValueMatrix, 1, 0, CV_L1, 0); }
// ComputePCA: Computes PCA PCAData* CPCAUtils::ComputePCA(ImageDataset *BC) { unsigned int i; PCAData *PCA=(PCAData*)new unsigned char[sizeof(PCAData)]; //Number of eigenvalues bouded by number of images in the dataset PCA->NumEigenobjects=BC->TotalImages-1; PCA->NumSamples=BC->TotalImages; //Bounds the number of objects to calculate if (PCA->NumEigenobjects>MAXEIGENOBJECTS) PCA->NumEigenobjects=MAXEIGENOBJECTS; if (PCA->NumEigenobjects>(unsigned int)(BC->ImageSize.height*BC->ImageSize.width)) PCA->NumEigenobjects=(BC->ImageSize.height*BC->ImageSize.width)-2; PCA->ImageSize=BC->ImageSize; PCA->NumCoefs=PCA->NumEigenobjects; //Allocating memory PCA->eigenObjects=(IplImage**) new unsigned char[(PCA->NumEigenobjects+1)*sizeof(IplImage*)]; if( !( PCA->eigVals = (float*) new unsigned char[(PCA->NumEigenobjects+1)*sizeof(float) ] ) ) exit(1); CvSize size=BC->ImageSize; if( !( PCA->avg = cvCreateImage( size, IPL_DEPTH_32F, 1 ) ) ) exit(1); for( i=0; i< (PCA->NumEigenobjects+1); i++ ) { PCA->eigenObjects[i] = cvCreateImage( size, IPL_DEPTH_32F, 1 ); if (!(PCA->eigenObjects[i])) exit(1); } CvTermCriteria ct=cvTermCriteria(CV_TERMCRIT_ITER,PCA->NumEigenobjects,0); cvCalcEigenObjects(PCA->NumSamples,(void*)BC->BC, (void*)PCA->eigenObjects, CV_EIGOBJ_NO_CALLBACK, 0, 0, &ct, PCA->avg, PCA->eigVals ); return(PCA); }
void EigenfaceRecognizer::doPCA() { // set the number of eigenvalues to use numEigenvalues = numTrainedImages-1; //the number of face images CvSize faceImgSize; // allocate the eigenvector images faceImgSize.width = images[0]->width; faceImgSize.height = images[0]->height; eigenVectors = (IplImage**)cvAlloc(sizeof(IplImage*) * numEigenvalues); for(int i = 0; i < numEigenvalues; i++) eigenVectors[i] = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1); // allocate the eigenvalue array eigenvalues = cvCreateMat( 1, numEigenvalues, CV_32FC1 ); // allocate the averaged image averageImage = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1); // set the PCA termination criterion CvTermCriteria calcLimit = cvTermCriteria( CV_TERMCRIT_ITER, numEigenvalues, 1); // compute average image, eigenvalues, and eigenvectors // the new C++ api has a cv::PCA object for this, upgrade this in the future! cvCalcEigenObjects( numTrainedImages, (void*)images, (void*)eigenVectors, CV_EIGOBJ_NO_CALLBACK, 0, 0, &calcLimit, averageImage, eigenvalues->data.fl); cvNormalize(eigenvalues, eigenvalues, 1, 0, CV_L1, 0); }
// Do the Principal Component Analysis, finding the average image // and the eigenfaces that represent any image in the given dataset. 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); cvNormalize(eigenValMat, eigenValMat, 1, 0, CV_L1, 0); }
//主成分分析 void doPCA() { int i; CvTermCriteria calcLimit; CvSize faceImgSize; // 自己设置主特征值个数 nEigens = nTrainFaces-1; //分配特征向量存储空间 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); //分配主特征值存储空间 eigenValMat = cvCreateMat( 1, nEigens, CV_32FC1 ); // 分配平均图像存储空间 pAvgTrainImg = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1); // 设定PCA分析结束条件 calcLimit = cvTermCriteria( CV_TERMCRIT_ITER, nEigens, 1); // 计算平均图像,特征值,特征向量 cvCalcEigenObjects( nTrainFaces, (void*)faceImgArr, (void*)eigenVectArr, CV_EIGOBJ_NO_CALLBACK, 0, 0, &calcLimit, pAvgTrainImg, eigenValMat->data.fl); cvNormalize(eigenValMat, eigenValMat, 1, 0, CV_L1, 0); }
pair<int, float> Eigenfaces::recognize(IplImage* input) { if (input == 0) { if (DEBUG) cout << "No faces passed. No recognition to do." << endl; return make_pair<int, float>(-1, -1); // Nothing } float minDist = FLT_MAX; int id = -1; clock_t recog = clock(); std::vector<IplImage*> tempFaces; tempFaces.push_back(input); unsigned int j, i; for( j = 0; j<d->faceImgArr.size(); j++) { tempFaces.push_back(d->faceImgArr.at(j)); float* eigenValues; //Initialize array with eigen values if( !(eigenValues = (float*) cvAlloc( 2*sizeof(float) ) ) ) cout << "Problems initializing eigenValues..." << endl; float* projectedTestFace = (float*)malloc(sizeof(float)); CvSize size=cvSize(tempFaces.at(0)->width, tempFaces.at(0)->height); //Set PCA's termination criterion CvTermCriteria mycrit = cvTermCriteria(CV_TERMCRIT_NUMBER, 1,0); //Initialise pointer to the pointers with eigen objects IplImage** eigenObjects = new IplImage *[2]; IplImage* pAvgTrainImg; //Initialize pointer to the average image if( !(pAvgTrainImg = cvCreateImage( size, IPL_DEPTH_32F, 1) ) ) cout<<"Problems initializing pAvgTrainImg..."<<endl; for(i = 0; i < 2; i++ ) { eigenObjects[i] = cvCreateImage( size, IPL_DEPTH_32F, 1 ); if(!(eigenObjects[i] ) ) cout<<"Problems initializing eigenObjects"<<endl; } //Perform PCA cvCalcEigenObjects(2, &tempFaces.front(), eigenObjects, CV_EIGOBJ_NO_CALLBACK, 0, NULL, &mycrit, pAvgTrainImg, eigenValues ); //This is a simple min distance mechanism for recognition. Perhaps we should check similarity of //images. if(eigenValues[0] < minDist) { minDist = eigenValues[0]; id = j; } //cvEigenDecomposite(tempFaces.at(0), nEigens, eigenObjects, //CV_EIGOBJ_NO_CALLBACK, NULL, pAvgTrainImg, projectedTestFace ); //IplImage *proj = cvCreateImage(cvSize(input->width, input->height), IPL_DEPTH_8U, 1); //cvEigenProjection(eigenObjects, nEigens, // CV_EIGOBJ_NO_CALLBACK, NULL, projectedTestFace, pAvgTrainImg, proj); //LibFaceUtils::showImage(proj); free(projectedTestFace); cvFree_(eigenValues); cvReleaseImage(&pAvgTrainImg); cvReleaseImage(&eigenObjects[0]); cvReleaseImage(&eigenObjects[1]); tempFaces.pop_back(); } tempFaces.clear(); recog = clock() - recog; if (DEBUG) printf("Recognition took: %f sec.\n", (double)recog / ((double)CLOCKS_PER_SEC)); if(minDist > d->THRESHOLD) { id = -1; minDist = -1; if(DEBUG) printf("The value is below the threshold.\n"); } else { if(DEBUG) printf("The value is: %f\n.", minDist); } return std::make_pair(id, minDist); }
/** * Performs PCA on the current training data, projects the training faces, and stores them in a DB. */ void Eigenfaces::EigenfacesPriv::learn(int index, IplImage* newFace) { int i; std::vector<IplImage*> tempFaces; tempFaces.push_back(newFace); tempFaces.push_back(faceImgArr.at(index)); float* projectedFace = (float*)malloc(sizeof(float)); CvSize size=cvSize(FACE_WIDTH, FACE_HEIGHT); //Set PCA's termination criterion CvTermCriteria mycrit = cvTermCriteria(CV_TERMCRIT_NUMBER, 1,0); //Initialise pointer to the pointers with eigen objects IplImage** eigenObjects = new IplImage *[2]; float* eigenValues; //Initialize array with eigen values if( !(eigenValues = (float*) cvAlloc( 2*sizeof(float) ) ) ) cout<<"Problems initializing eigenValues..."<<endl; IplImage* pAvgTrainImg; //Initialize pointer to the average image if( !(pAvgTrainImg = cvCreateImage( size, IPL_DEPTH_32F, 1) ) ) cout<<"Problems initializing pAvgTrainImg..."<<endl; for(i = 0; i < 2; i++ ) { eigenObjects[i] = cvCreateImage( size, IPL_DEPTH_32F, 1 ); if(!(eigenObjects[i] ) ) cout<<"Problems initializing eigenObjects"<<endl; } //Perform PCA cvCalcEigenObjects(2, &tempFaces.front(), eigenObjects, CV_EIGOBJ_NO_CALLBACK, 0, NULL, &mycrit, pAvgTrainImg, eigenValues ); cvEigenDecomposite(tempFaces.at(0), 1, eigenObjects, CV_EIGOBJ_NO_CALLBACK, NULL, pAvgTrainImg, projectedFace ); IplImage* proj = cvCreateImage(size, IPL_DEPTH_8U, 1); cvEigenProjection(eigenObjects, 1, CV_EIGOBJ_NO_CALLBACK, NULL, projectedFace, pAvgTrainImg, proj); //LibFaceUtils::showImage(proj); cvReleaseImage(&faceImgArr.at(index)); faceImgArr.at(index) = proj; //free other stuff allocated above. cvFree_(eigenValues); free(projectedFace); cvReleaseImage(&pAvgTrainImg); cvReleaseImage(&eigenObjects[0]); cvReleaseImage(&eigenObjects[1]); tempFaces.clear(); }
void PCAWrapper::training() { double *vals; double **coeffs; int i, j; faceImage = new IplImage *[imageCnt]; eigens = new IplImage *[imageCnt - 1]; projectionImage = new IplImage *[imageCnt]; for (i = 0; i < imageCnt; i++) { faceImage[i] = trainImage[i]; projectionImage[i] = cvCreateImage(cvGetSize(faceImage[i]), IPL_DEPTH_8U, 1); } for (i = 0; i < imageCnt - 1; i++) { eigens[i] = cvCreateImage(cvGetSize(faceImage[i]), IPL_DEPTH_32F, 1); } vals = new double[imageCnt]; memset(vals, 0, sizeof(double) * imageCnt); coeffs = new double *[imageCnt]; coeffs[0] = new double[imageCnt * (imageCnt - 1)]; DEBUG; for (i = 1; i < imageCnt; i++) { coeffs[i] = coeffs[i - 1] + (imageCnt - 1); } avg = cvCreateImage(cvGetSize(faceImage[0]), IPL_DEPTH_32F, 1); criteria = cvTermCriteria(CV_TERMCRIT_ITER, imageCnt - 1, 0); cvCalcEigenObjects(imageCnt, faceImage, eigens, 0, 0, 0, &criteria, avg, (float *)vals); projectionVector = new double *[imageCnt]; projectionVector[0] = new double[imageCnt * (imageCnt - 1)]; for (i = 1; i < imageCnt; i++) { projectionVector[i] = projectionVector[i - 1] + (imageCnt - 1); } for (i = 0; i < imageCnt; i++) { for (j = 0; j < imageCnt-1; j++) { projectionVector[i][j] = cvCalcDecompCoeff(trainImage[i], eigens[j], avg); } } for (i = 0; i < imageCnt; i++) { cvReleaseImage(&projectionImage[i]); } delete[]coeffs[0]; delete[]coeffs; delete[]faceImage; delete[]projectionImage; delete[]vals; }