Thứ Sáu, 6 tháng 6, 2014

Coding nhận dạng mặt người

Sưu tầm, lưu trữ, sau này nghiên cứu tiếp.
  1. // eigenface.c, by Robin Hewitt, 2007
  2. //
  3. // Example program showing how to implement eigenface with OpenCV
  4.  
  5. // Usage:
  6. //
  7. // First, you need some face images. I used the ORL face database.
  8. // You can download it for free at
  9. //    www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html
  10. //
  11. // List the training and test face images you want to use in the
  12. // input files train.txt and test.txt. (Example input files are provided
  13. // in the download.) To use these input files exactly as provided, unzip
  14. // the ORL face database, and place train.txt, test.txt, and eigenface.exe
  15. // at the root of the unzipped database.
  16. //
  17. // To run the learning phase of eigenface, enter
  18. //    eigenface train
  19. // at the command prompt. To run the recognition phase, enter
  20. //    eigenface test
  21.  
  22.  
  23. #include
  24. #include
  25. #include "cv.h"
  26. #include "cvaux.h"
  27. #include "highgui.h"
  28.  
  29.  
  30. //// Global variables
  31. IplImage ** faceImgArr        = 0; // array of face images
  32. CvMat    *  personNumTruthMat = 0; // array of person numbers
  33. int nTrainFaces               = 0; // the number of training images
  34. int nEigens                   = 0; // the number of eigenvalues
  35. IplImage * pAvgTrainImg       = 0; // the average image
  36. IplImage ** eigenVectArr      = 0; // eigenvectors
  37. CvMat * eigenValMat           = 0; // eigenvalues
  38. CvMat * projectedTrainFaceMat = 0; // projected training faces
  39.  
  40.  
  41. //// Function prototypes
  42. void learn();
  43. void recognize();
  44. void doPCA();
  45. void storeTrainingData();
  46. int  loadTrainingData(CvMat ** pTrainPersonNumMat);
  47. int  findNearestNeighbor(float * projectedTestFace);
  48. int  loadFaceImgArray(char * filename);
  49. void printUsage();
  50.  
  51.  
  52. //////////////////////////////////
  53. // main()
  54. //
  55. void main( int argc, char** argv )
  56. {
  57.         // validate that an input was specified
  58.         if( argc != 2 )
  59.         {
  60.                 printUsage();
  61.                 return;
  62.         }
  63.  
  64.         if( !strcmp(argv[1]"train") ) learn();
  65.         else if( !strcmp(argv[1]"test") ) recognize();
  66.         else
  67.         {
  68.                 printf("Unknown command: %s\n", argv[1]);
  69.                 printUsage();
  70.         }
  71. }
  72.  
  73.  
  74. //////////////////////////////////
  75. // learn()
  76. //
  77. void learn()
  78. {
  79.         int i, offset;
  80.  
  81.         // load training data
  82.         nTrainFaces = loadFaceImgArray("train.txt");
  83.         if( nTrainFaces < 2 )
  84.         {
  85.                 fprintf(stderr,
  86.                         "Need 2 or more training faces\n"
  87.                         "Input file contains only %d\n", nTrainFaces);
  88.                 return;
  89.         }
  90.  
  91.         // do PCA on the training faces
  92.         doPCA();
  93.  
  94.         // project the training images onto the PCA subspace
  95.         projectedTrainFaceMat = cvCreateMat( nTrainFaces, nEigens, CV_32FC1 );
  96.         offset = projectedTrainFaceMat->step / sizeof(float);
  97.         for(i=0; i<nTrainFaces; i++)
  98.         {
  99.                 //int offset = i * nEigens;
  100.                 cvEigenDecomposite(
  101.                         faceImgArr[i],
  102.                         nEigens,
  103.                         eigenVectArr,
  104.                         00,
  105.                         pAvgTrainImg,
  106.                         //projectedTrainFaceMat->data.fl + i*nEigens);
  107.                         projectedTrainFaceMat->data.fl + i*offset);
  108.         }
  109.  
  110.         // store the recognition data as an xml file
  111.         storeTrainingData();
  112. }
  113.  
  114.  
  115. //////////////////////////////////
  116. // recognize()
  117. //
  118. void recognize()
  119. {
  120.         int i, nTestFaces  = 0;         // the number of test images
  121.         CvMat * trainPersonNumMat = 0;  // the person numbers during training
  122.         float * projectedTestFace = 0;
  123.  
  124.         // load test images and ground truth for person number
  125.         nTestFaces = loadFaceImgArray("test.txt");
  126.         printf("%d test faces loaded\n", nTestFaces);
  127.  
  128.         // load the saved training data
  129.         if( !loadTrainingData( &trainPersonNumMat ) ) return;
  130.  
  131.         // project the test images onto the PCA subspace
  132.         projectedTestFace = (float *)cvAlloc( nEigens*sizeof(float) );
  133.         for(i=0; i<nTestFaces; i++)
  134.         {
  135.                 int iNearest, nearest, truth;
  136.  
  137.                 // project the test image onto the PCA subspace
  138.                 cvEigenDecomposite(
  139.                         faceImgArr[i],
  140.                         nEigens,
  141.                         eigenVectArr,
  142.                         0, 0,
  143.                         pAvgTrainImg,
  144.                         projectedTestFace);
  145.  
  146.                 iNearest = findNearestNeighbor(projectedTestFace);
  147.                 truth    = personNumTruthMat->data.i[i];
  148.                 nearest  = trainPersonNumMat->data.i[iNearest];
  149.  
  150.                 printf("nearest = %d, Truth = %d\n", nearest, truth);
  151.         }
  152. }
  153.  
  154.  
  155. //////////////////////////////////
  156. // loadTrainingData()
  157. //
  158. int loadTrainingData(CvMat ** pTrainPersonNumMat)
  159. {
  160.         CvFileStorage * fileStorage;
  161.         int i;
  162.  
  163.         // create a file-storage interface
  164.         fileStorage = cvOpenFileStorage( "facedata.xml", 0, CV_STORAGE_READ );
  165.         if( !fileStorage )
  166.         {
  167.                 fprintf(stderr, "Can't open facedata.xml\n");
  168.                 return 0;
  169.         }
  170.  
  171.         nEigens = cvReadIntByName(fileStorage, 0"nEigens", 0);
  172.         nTrainFaces = cvReadIntByName(fileStorage, 0"nTrainFaces", 0);
  173.         *pTrainPersonNumMat = (CvMat *)cvReadByName(fileStorage, 0"trainPersonNumMat", 0);
  174.         eigenValMat  = (CvMat *)cvReadByName(fileStorage, 0"eigenValMat", 0);
  175.         projectedTrainFaceMat = (CvMat *)cvReadByName(fileStorage, 0"projectedTrainFaceMat", 0);
  176.         pAvgTrainImg = (IplImage *)cvReadByName(fileStorage, 0"avgTrainImg", 0);
  177.         eigenVectArr = (IplImage **)cvAlloc(nTrainFaces*sizeof(IplImage *));
  178.         for(i=0; i<nEigens; i++)
  179.         {
  180.                 char varname[200];
  181.                 sprintf( varname, "eigenVect_%d", i );
  182.                 eigenVectArr[i] = (IplImage *)cvReadByName(fileStorage, 0, varname, 0);
  183.         }
  184.  
  185.         // release the file-storage interface
  186.         cvReleaseFileStorage( &fileStorage );
  187.  
  188.         return 1;
  189. }
  190.  
  191.  
  192. //////////////////////////////////
  193. // storeTrainingData()
  194. //
  195. void storeTrainingData()
  196. {
  197.         CvFileStorage * fileStorage;
  198.         int i;
  199.  
  200.         // create a file-storage interface
  201.         fileStorage = cvOpenFileStorage( "facedata.xml", 0, CV_STORAGE_WRITE );
  202.  
  203.         // store all the data
  204.         cvWriteInt( fileStorage, "nEigens", nEigens );
  205.         cvWriteInt( fileStorage, "nTrainFaces", nTrainFaces );
  206.         cvWrite(fileStorage, "trainPersonNumMat", personNumTruthMat, cvAttrList(0,0));
  207.         cvWrite(fileStorage, "eigenValMat", eigenValMat, cvAttrList(0,0));
  208.         cvWrite(fileStorage, "projectedTrainFaceMat", projectedTrainFaceMat, cvAttrList(0,0));
  209.         cvWrite(fileStorage, "avgTrainImg", pAvgTrainImg, cvAttrList(0,0));
  210.         for(i=0; i<nEigens; i++)
  211.         {
  212.                 char varname[200];
  213.                 sprintf( varname, "eigenVect_%d", i );
  214.                 cvWrite(fileStorage, varname, eigenVectArr[i], cvAttrList(0,0));
  215.         }
  216.  
  217.         // release the file-storage interface
  218.         cvReleaseFileStorage( &fileStorage );
  219. }
  220.  
  221.  
  222. //////////////////////////////////
  223. // findNearestNeighbor()
  224. //
  225. int findNearestNeighbor(float * projectedTestFace)
  226. {
  227.         //double leastDistSq = 1e12;
  228.         double leastDistSq = DBL_MAX;
  229.         int i, iTrain, iNearest = 0;
  230.  
  231.         for(iTrain=0; iTrain<nTrainFaces; iTrain++)
  232.         {
  233.                 double distSq=0;
  234.  
  235.                 for(i=0; i<nEigens; i++)
  236.                 {
  237.                         float d_i =
  238.                                 projectedTestFace[i] -
  239.                                 projectedTrainFaceMat->data.fl[iTrain*nEigens + i];
  240.                         //distSq += d_i*d_i / eigenValMat->data.fl[i];  // Mahalanobis
  241.                         distSq += d_i*d_i; // Euclidean
  242.                 }
  243.  
  244.                 if(distSq < leastDistSq)
  245.                 {
  246.                         leastDistSq = distSq;
  247.                         iNearest = iTrain;
  248.                 }
  249.         }
  250.  
  251.         return iNearest;
  252. }
  253.  
  254.  
  255. //////////////////////////////////
  256. // doPCA()
  257. //
  258. void doPCA()
  259. {
  260.         int i;
  261.         CvTermCriteria calcLimit;
  262.         CvSize faceImgSize;
  263.  
  264.         // set the number of eigenvalues to use
  265.         nEigens = nTrainFaces-1;
  266.  
  267.         // allocate the eigenvector images
  268.         faceImgSize.width  = faceImgArr[0]->width;
  269.         faceImgSize.height = faceImgArr[0]->height;
  270.         eigenVectArr = (IplImage**)cvAlloc(sizeof(IplImage*) * nEigens);
  271.         for(i=0; i<nEigens; i++)
  272.                 eigenVectArr[i] = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1);
  273.  
  274.         // allocate the eigenvalue array
  275.         eigenValMat = cvCreateMat( 1, nEigens, CV_32FC1 );
  276.  
  277.         // allocate the averaged image
  278.         pAvgTrainImg = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1);
  279.  
  280.         // set the PCA termination criterion
  281.         calcLimit = cvTermCriteria( CV_TERMCRIT_ITER, nEigens, 1);
  282.  
  283.         // compute average image, eigenvalues, and eigenvectors
  284.         cvCalcEigenObjects(
  285.                 nTrainFaces,
  286.                 (void*)faceImgArr,
  287.                 (void*)eigenVectArr,
  288.                 CV_EIGOBJ_NO_CALLBACK,
  289.                 0,
  290.                 0,
  291.                 &calcLimit,
  292.                 pAvgTrainImg,
  293.                 eigenValMat->data.fl);
  294.  
  295.         cvNormalize(eigenValMat, eigenValMat, 1, 0, CV_L1, 0);
  296. }
  297.  
  298.  
  299. //////////////////////////////////
  300. // loadFaceImgArray()
  301. //
  302. int loadFaceImgArray(char * filename)
  303. {
  304.         FILE * imgListFile = 0;
  305.         char imgFilename[512];
  306.         int iFace, nFaces=0;
  307.  
  308.  
  309.         // open the input file
  310.         if( !(imgListFile = fopen(filename, "r")) )
  311.         {
  312.                 fprintf(stderr, "Can\'t open file %s\n", filename);
  313.                 return 0;
  314.         }
  315.  
  316.         // count the number of faces
  317.         while( fgets(imgFilename, 512, imgListFile) ) ++nFaces;
  318.         rewind(imgListFile);
  319.  
  320.         // allocate the face-image array and person number matrix
  321.         faceImgArr        = (IplImage **)cvAlloc( nFaces*sizeof(IplImage *) );
  322.         personNumTruthMat = cvCreateMat( 1, nFaces, CV_32SC1 );
  323.  
  324.         // store the face images in an array
  325.         for(iFace=0; iFace<nFaces; iFace++)
  326.         {
  327.                 // read person number and name of image file
  328.                 fscanf(imgListFile,
  329.                         "%d %s", personNumTruthMat->data.i+iFace, imgFilename);
  330.  
  331.                 // load the face image
  332.                 faceImgArr[iFace] = cvLoadImage(imgFilename, CV_LOAD_IMAGE_GRAYSCALE);
  333.  
  334.                 if( !faceImgArr[iFace] )
  335.                 {
  336.                         fprintf(stderr, "Can\'t load image from %s\n", imgFilename);
  337.                         return 0;
  338.                 }
  339.         }
  340.  
  341.         fclose(imgListFile);
  342.  
  343.         return nFaces;
  344. }
  345.  
  346.  
  347. //////////////////////////////////
  348. // printUsage()
  349. //
  350. void printUsage()
  351. {
  352.         printf("Usage: eigenface \n",
  353.                "  Valid commands are\n"
  354.                "    train\n"
  355.                "    test\n");
  356. }

Không có nhận xét nào:

Đăng nhận xét