#include <stdio.h>
#include <string.h>
#include "cv.h"
#include "cvaux.h"
#include "highgui.h" using namespace cv; //globle variables
int nTrainFaces = ; // number of trainning images
int nEigens = ; // number of eigenvalues
IplImage** faceImgArr = ; // array of face images
CvMat* personNumTruthMat = ; // array of person numbers
IplImage* pAvgTrainImg = ; // the average image
IplImage** eigenVectArr = ; // eigenvectors
CvMat* eigenValMat = ; // eigenvalues
CvMat* projectedTrainFaceMat = ; // projected training faces //// Function prototypes
void learn();
void recognize();
void doPCA();
void storeTrainingData();
int loadTrainingData(CvMat** pTrainPersonNumMat);
int findNearestNeighbor(float* projectedTestFace);
int loadFaceImgArray(char* filename);
void printUsage(); int main( int argc, char** argv )
{
if((argc != ) && (argc != )){
printUsage();
return -;
} if( !strcmp(argv[], "train" )){
learn();
} else if( !strcmp(argv[], "test") ){
recognize();
} else {
printf("Unknown command: %s\n", argv[]);
}
return ;
} void printUsage(){
printf("Usage: eigenface <command>\n",
" Valid commands are\n"
" train\n"
" test\n"
);
} void learn(){
int i; // load training data
nTrainFaces = loadFaceImgArray("train.txt");
if( nTrainFaces < ){
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(i = ; i < nTrainFaces; i ++){
cvEigenDecomposite(
faceImgArr[i],
nEigens,
eigenVectArr,
, ,
pAvgTrainImg,
projectedTrainFaceMat->data.fl + i*nEigens
);
} // store the recognition data as an xml file
storeTrainingData();
} int loadFaceImgArray(char* filename){
FILE* imgListFile = ;
char imgFilename[];
int iFace, nFaces = ; // open the input file
imgListFile = fopen(filename, "r"); // count the number of faces
while( fgets(imgFilename, , imgListFile) ) ++ nFaces;
rewind(imgListFile); // allocate the face-image array and person number matrix
faceImgArr = (IplImage **)cvAlloc( nFaces*sizeof(IplImage *) );
personNumTruthMat = cvCreateMat( , nFaces, CV_32SC1 ); // store the face images in an array
for(iFace=; 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 - ; // allocate the eigenvector images
faceImgSize.width = faceImgArr[]->width;
faceImgSize.height = faceImgArr[]->height;
eigenVectArr = (IplImage**)cvAlloc(sizeof(IplImage*) * nEigens);
for(i=; i<nEigens; i++){
eigenVectArr[i] = cvCreateImage(faceImgSize, IPL_DEPTH_32F, );
} // allocate the eigenvalue array
eigenValMat = cvCreateMat( , nEigens, CV_32FC1 ); // allocate the averaged image
pAvgTrainImg = cvCreateImage(faceImgSize, IPL_DEPTH_32F, ); // set the PCA termination criterion
calcLimit = cvTermCriteria( CV_TERMCRIT_ITER, nEigens, ); // compute average image, eigenvalues, and eigenvectors
cvCalcEigenObjects(
nTrainFaces,
(void*)faceImgArr,
(void*)eigenVectArr,
CV_EIGOBJ_NO_CALLBACK,
,
,
&calcLimit,
pAvgTrainImg,
eigenValMat->data.fl
);
} void storeTrainingData(){
CvFileStorage* fileStorage;
int i; // create a file-storage interface
fileStorage = cvOpenFileStorage( "facedata.xml", , CV_STORAGE_WRITE); // store all the data
cvWriteInt( fileStorage, "nEigens", nEigens);
cvWriteInt( fileStorage, "nTrainFaces", nTrainFaces );
cvWrite(fileStorage, "trainPersonNumMat", personNumTruthMat, cvAttrList(, ));
cvWrite(fileStorage, "eigenValMat", eigenValMat, cvAttrList(,));
cvWrite(fileStorage, "projectedTrainFaceMat", projectedTrainFaceMat, cvAttrList(,));
cvWrite(fileStorage, "avgTrainImg", pAvgTrainImg, cvAttrList(,)); for(i=; i<nEigens; i++){
char varname[];
sprintf( varname, "eigenVect_%d", i);
cvWrite(fileStorage, varname, eigenVectArr[i], cvAttrList(,));
} //release the file-storage interface
cvReleaseFileStorage( &fileStorage );
} void recognize(){
int i, nTestFaces = ; // the number of test images
CvMat* trainPersonNumMat = ; // the person numbers during training
float* projectedTestFace = ; // 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) );
for(i=; i<nTestFaces; i++){
int iNearest, nearest, truth; // project the test image onto PCA subspace
cvEigenDecomposite(
faceImgArr[i],
nEigens,
eigenVectArr,
, ,
pAvgTrainImg,
projectedTestFace
); iNearest = findNearestNeighbor(projectedTestFace);
truth = personNumTruthMat->data.i[i];
nearest = trainPersonNumMat->data.i[iNearest]; printf("nearest = %d, Truth = %d\n", nearest, truth);
}
} int loadTrainingData(CvMat** pTrainPersonNumMat){
CvFileStorage* fileStorage;
int i; // create a file-storage interface
fileStorage = cvOpenFileStorage( "facedata.xml", , CV_STORAGE_READ );
if( !fileStorage ){
fprintf(stderr, "Can't open facedata.xml\n");
return ;
} nEigens = cvReadIntByName(fileStorage, , "nEigens", );
nTrainFaces = cvReadIntByName(fileStorage, , "nTrainFaces", );
*pTrainPersonNumMat = (CvMat*)cvReadByName(fileStorage, , "trainPersonNumMat", );
eigenValMat = (CvMat*)cvReadByName(fileStorage, , "eigenValMat", );
projectedTrainFaceMat = (CvMat*)cvReadByName(fileStorage, , "projectedTrainFaceMat", );
pAvgTrainImg = (IplImage*)cvReadByName(fileStorage, , "avgTrainImg", );
eigenVectArr = (IplImage**)cvAlloc(nTrainFaces*sizeof(IplImage*));
for(i=; i<nEigens; i++){
char varname[];
sprintf( varname, "eigenVect_%d", i );
eigenVectArr[i] = (IplImage*)cvReadByName(fileStorage, , varname, );
} // release the file-storage interface
cvReleaseFileStorage( &fileStorage ); return ;
} int findNearestNeighbor(float* projectedTestFace){
double leastDistSq = DBL_MAX;
int i, iTrain, iNearest = ; for(iTrain=; iTrain<nTrainFaces; iTrain++){
double distSq = ; for(i=; i<nEigens; i++){
float d_i = projectedTestFace[i] -
projectedTrainFaceMat->data.fl[iTrain*nEigens + i];
distSq += d_i*d_i;
} if(distSq < leastDistSq){
leastDistSq = distSq;
iNearest = iTrain;
}
} return iNearest;
}

最新文章

  1. Brew安装MacVim
  2. 【译】用jQuery 处理XML--浏览器中的XML与JavaScript
  3. 分享几个原生javascript面向对象设计小游戏
  4. Vue系列: 如何通过组件的属性props设置样式
  5. NGINX: 405 Not Allowed
  6. SRM 591 div1 275
  7. R语言字符串函数
  8. Fiddler的基本介绍
  9. ---添加一条记录返回一条记录的ID
  10. C中程序的内存分配
  11. JAVA连接数据库后,对数据库进行增删改查
  12. 人生第一个过万 Star 的 github 项目诞生
  13. Linux Input子系统浅析(二)-- 模拟tp上报键值【转】
  14. html 文字少则居中多则居左
  15. 【Wildfly】从默认的自动重启修改为手动重启
  16. vue-awesome-swiper组件不能自动播放和导航器小圆点不显示问题
  17. js获得当前元素的样式
  18. CF1060E Sergey and Subways 假的点分治
  19. Java Object part1
  20. 深入理解Linux内核-内存管理

热门文章

  1. Codeforces691A【读题-水】
  2. Unity IK(反向运动学)初探
  3. Linux下安装ruby
  4. 阿里云物联网 .NET Core 客户端 | CZGL.AliIoTClient:6. 设备事件上报
  5. JDK1.7 和 jetty配置教程
  6. MyBatis逆向工程代码的生成以及使用详解(持续更新)
  7. UVA-11584:Partitioning by Palindromes(基础DP)
  8. typedef与复杂声明
  9. Python + request接口测试中Cookie和Session的获取和使用
  10. 牛客网Java刷题知识点之调用线程类的start()方法和run()方法的区别