Advertisement
Guest User

Untitled

a guest
May 17th, 2013
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 37.42 KB | None | 0 0
  1. #include <stdio.h>
  2. #if defined WIN32 || defined _WIN32
  3.     #include <conio.h>      // For _kbhit() on Windows
  4.     #include <direct.h>     // For mkdir(path) on Windows
  5.     #define snprintf sprintf_s  // Visual Studio on Windows comes with sprintf_s() instead of snprintf()
  6. #else
  7.     #include <stdio.h>      // For getchar() on Linux
  8.     #include <termios.h>    // For kbhit() on Linux
  9.     #include <unistd.h>
  10.     #include <sys/types.h>
  11.     #include <sys/stat.h>   // For mkdir(path, options) on Linux
  12. #endif
  13. #include <vector>
  14. #include <string>
  15. #include "cv.h"
  16. #include "cvaux.h"
  17. #include "highgui.h"
  18.  
  19. #ifndef BOOL
  20.     #define BOOL bool
  21. #endif
  22.  
  23. #include <stdlib.h>
  24.  
  25. using namespace std;
  26.  
  27. const char *faceCascadeFilename;
  28.  
  29. int SAVE_EIGENFACE_IMAGES = 0;      // Set to 0 if you dont want images of the Eigenvectors saved to files (for debugging).
  30. //#define USE_MAHALANOBIS_DISTANCE  // You might get better recognition accuracy if you enable this.
  31.  
  32. // Global variables
  33. IplImage ** faceImgArr        = 0; // array of face images
  34. CvMat    *  personNumTruthMat = 0; // array of person numbers
  35. vector<string> personNames;         // array of person names (indexed by the person number). Added by Shervin.
  36. int faceWidth = 120;    // Default dimensions for faces in the face recognition database. Added by Shervin.
  37. int faceHeight = 90;    //  "       "       "       "       "       "       "       "
  38. int nPersons                  = 0; // the number of people in the training set. Added by Shervin.
  39. int nTrainFaces               = 0; // the number of training images
  40. int nEigens                   = 0; // the number of eigenvalues
  41. IplImage * pAvgTrainImg       = 0; // the average image
  42. IplImage ** eigenVectArr      = 0; // eigenvectors
  43. CvMat * eigenValMat           = 0; // eigenvalues
  44. CvMat * projectedTrainFaceMat = 0; // projected training faces
  45.  
  46. CvCapture* camera = 0;  // The camera device.
  47.  
  48. // Function prototypes
  49. void printUsage();
  50. void learn(const char *szFileTrain);
  51. void doPCA();
  52. void storeTrainingData();
  53. int  loadTrainingData(CvMat ** pTrainPersonNumMat);
  54. int  findNearestNeighbor(float * projectedTestFace);
  55. int findNearestNeighbor(float * projectedTestFace, float *pConfidence);
  56. int  loadFaceImgArray(const char * filename);
  57. void recognizeFileList(const char *szFileTest);
  58. int recognizeFromCam(void);
  59. IplImage* getCameraFrame(void);
  60. IplImage* convertImageToGreyscale(const IplImage *imageSrc);
  61. IplImage* cropImage(const IplImage *img, const CvRect region);
  62. IplImage* resizeImage(const IplImage *origImg, int newWidth, int newHeight);
  63. IplImage* convertFloatImageToUcharImage(const IplImage *srcImg);
  64. void saveFloatImage(const char *filename, const IplImage *srcImg);
  65. CvRect detectFaceInImage(const IplImage *inputImg, const CvHaarClassifierCascade* cascade );
  66. CvMat* retrainOnline(void);
  67.  
  68. // Show how to use this program from the command-line.
  69. void printUsage()
  70. {
  71.     printf("Usage: FaceMaster [<command>] \n"
  72.         "  Valid commands are: \n"
  73.         "    <user code> \n"
  74.         "    Provide user code as arg!!\n"
  75.         );
  76. }
  77. #if defined WIN32 || defined _WIN32
  78.     // Wrappers of kbhit() and getch() for Windows:
  79.     #define changeKeyboardMode
  80.     #define kbhit _kbhit
  81. #else
  82.     // Create an equivalent to kbhit() and getch() for Linux,
  83.     // based on "http://cboard.cprogramming.com/c-programming/63166-kbhit-linux.html":
  84.    
  85.     #define VK_ESCAPE 0x1B      // Escape character
  86.  
  87.     // If 'dir' is 1, get the Linux terminal to return the 1st keypress instead of waiting for an ENTER key.
  88.     // If 'dir' is 0, will reset the terminal back to the original settings.
  89.     void changeKeyboardMode(int dir)
  90.     {
  91.         static struct termios oldt, newt;
  92.  
  93.         if ( dir == 1 ) {
  94.             tcgetattr( STDIN_FILENO, &oldt);
  95.             newt = oldt;
  96.             newt.c_lflag &= ~( ICANON | ECHO );
  97.             tcsetattr( STDIN_FILENO, TCSANOW, &newt);
  98.         }
  99.         else
  100.             tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
  101.     }
  102.  
  103.     // Get the next keypress.
  104.     int kbhit(void)
  105.     {
  106.         struct timeval tv;
  107.         fd_set rdfs;
  108.  
  109.         tv.tv_sec = 0;
  110.         tv.tv_usec = 0;
  111.  
  112.         FD_ZERO(&rdfs);
  113.         FD_SET (STDIN_FILENO, &rdfs);
  114.  
  115.         select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv);
  116.         return FD_ISSET(STDIN_FILENO, &rdfs);
  117.     }
  118.  
  119.     // Use getchar() on Linux instead of getch().
  120.     #define getch() getchar()
  121. #endif
  122.  
  123. #define MAX_STRING_LENGTH 10
  124.  
  125.   char S[MAX_STRING_LENGTH];
  126.   char A0[MAX_STRING_LENGTH];
  127.  
  128. //int c = 0;
  129. // Startup routine.
  130.  
  131. int main()
  132. {
  133.    char astr[120]; 
  134.    printf("PATH='%s%s'\n", getenv("HOME"), "/user/share");
  135.    snprintf(astr, sizeof astr, "%s%s\n", getenv("HOME"), "user/share/haarcascade_frontalface_alt2.xml");
  136.    printf("%s\n",astr);
  137.    const char *faceCascadeFilename = astr;
  138.    int n;
  139.  
  140. while(1)
  141.   {
  142.     gets(S);
  143.     n = sscanf(S,"%s",A0);
  144.     printf("A0:\t%s\n",A0);
  145.     if ( recognizeFromCam() )
  146.     {
  147.         break;
  148.         continue;
  149.         return 0;
  150.     }
  151.  
  152.   }
  153. }
  154.  
  155.  
  156. // Save all the eigenvectors as images, so that they can be checked.
  157. void storeEigenfaceImages()
  158. {
  159.     // Store the average image to a file
  160.    
  161.       char bufb[256];
  162.     snprintf(bufb, sizeof bufb, "%s%s", A0, ".bmp");
  163.    
  164.     printf("Saving the image of the average face as 'out_averageImage.bmp'.\n");
  165.     cvSaveImage(bufb, pAvgTrainImg);
  166.     // Create a large image made of many eigenface images.
  167.     // Must also convert each eigenface image to a normal 8-bit UCHAR image instead of a 32-bit float image.
  168.     printf("Saving the %d eigenvector images as 'out_eigenfaces.bmp'\n", nEigens);
  169.     if (nEigens > 0) {
  170.         // Put all the eigenfaces next to each other.
  171.         int COLUMNS = 8;    // Put upto 8 images on a row.
  172.         int nCols = min(nEigens, COLUMNS);
  173.         int nRows = 1 + (nEigens / COLUMNS);    // Put the rest on new rows.
  174.         int w = eigenVectArr[0]->width;
  175.         int h = eigenVectArr[0]->height;
  176.         CvSize size;
  177.         size = cvSize(nCols * w, nRows * h);
  178.         //PETER ADDED XTRA IMAGE no
  179.         IplImage *bigImg = cvCreateImage(size, IPL_DEPTH_8U, 1);    // 8-bit Greyscale UCHAR image
  180.         for (int i=0; i<nEigens; i++) {
  181.             // Get the eigenface image.
  182.             IplImage *byteImg = convertFloatImageToUcharImage(eigenVectArr[i]);
  183.             // Paste it into the correct position.
  184.             int x = w * (i % COLUMNS);
  185.             int y = h * (i / COLUMNS);
  186.             CvRect ROI = cvRect(x, y, w, h);
  187.             cvSetImageROI(bigImg, ROI);
  188.             cvCopyImage(byteImg, bigImg);
  189.             cvResetImageROI(bigImg);
  190.             cvReleaseImage(&byteImg);
  191.         }
  192.         cvSaveImage(bufb, bigImg);
  193.         cvReleaseImage(&bigImg);
  194.     }
  195. }
  196.  
  197. // Train from the data in the given text file, and store the trained data into the file 'data.xml'.
  198.  
  199. void learn(const char *szFileTrain)
  200. {
  201.     int i, offset;
  202.  
  203.     // load training data
  204.     printf("Loading the training images in '%s'\n", szFileTrain);
  205.     nTrainFaces = loadFaceImgArray(szFileTrain);
  206.     printf("Got %d training images.\n", nTrainFaces);
  207.     if( nTrainFaces < 2 )
  208.     {
  209.         fprintf(stderr,
  210.                 "Need 2 or more training faces\n"
  211.                 "Input file contains only %d\n", nTrainFaces);
  212.         return;
  213.     }
  214.  
  215.     // do PCA on the training faces
  216.     doPCA();
  217.  
  218.     // project the training images onto the PCA subspace
  219.     projectedTrainFaceMat = cvCreateMat( nTrainFaces, nEigens, CV_32FC1 );
  220.     offset = projectedTrainFaceMat->step / sizeof(float);
  221.     for(i=0; i<nTrainFaces; i++)
  222.     {
  223.         //int offset = i * nEigens;
  224.         cvEigenDecomposite(
  225.             faceImgArr[i],
  226.             nEigens,
  227.             eigenVectArr,
  228.             0, 0,
  229.             pAvgTrainImg,
  230.             //projectedTrainFaceMat->data.fl + i*nEigens);
  231.             projectedTrainFaceMat->data.fl + i*offset);
  232.     }
  233.  
  234.     // store the recognition data as an xml file
  235.     storeTrainingData();
  236.  
  237.     // Save all the eigenvectors as images, so that they can be checked.
  238.     if (SAVE_EIGENFACE_IMAGES) {
  239.         storeEigenfaceImages();
  240.     }
  241.  
  242. }
  243.  
  244.  
  245. // Open the training data from the file.
  246. int loadTrainingData(CvMat ** pTrainPersonNumMat)
  247. {
  248.     CvFileStorage * fileStorage;
  249.     int i;
  250.  
  251.     char buf[256];
  252.  
  253.     snprintf(buf, sizeof buf, "%s%s", A0, ".xml");
  254.  
  255.     // create a file-storage interface
  256.     fileStorage = cvOpenFileStorage( buf, 0, CV_STORAGE_READ );
  257.     if( !fileStorage ) {
  258.         printf("Can't open training database file.\n");
  259.         changeKeyboardMode(0);
  260.         return 0;
  261.     }
  262.  
  263.     // Load the person names. Added by Shervin.
  264.     personNames.clear();    // Make sure it starts as empty.
  265.     nPersons = cvReadIntByName( fileStorage, 0, "nPersons", 0 );
  266.     if (nPersons == 0) {
  267.         printf("No people found in the training database.\n");
  268.         changeKeyboardMode(0);
  269.         return 0;
  270.     }
  271.     // Load each person's name.
  272.     for (i=0; i<nPersons; i++) {
  273.         string sPersonName;
  274.         char varname[200];
  275.         snprintf( varname, sizeof(varname)-1, "personName_%d", (i+1) );
  276.         sPersonName = cvReadStringByName(fileStorage, 0, varname );
  277.         personNames.push_back( sPersonName );
  278.     }
  279.  
  280.     // Load the data
  281.     nEigens = cvReadIntByName(fileStorage, 0, "nEigens", 0);
  282.     nTrainFaces = cvReadIntByName(fileStorage, 0, "nTrainFaces", 0);
  283.     *pTrainPersonNumMat = (CvMat *)cvReadByName(fileStorage, 0, "trainPersonNumMat", 0);
  284.     eigenValMat  = (CvMat *)cvReadByName(fileStorage, 0, "eigenValMat", 0);
  285.     projectedTrainFaceMat = (CvMat *)cvReadByName(fileStorage, 0, "projectedTrainFaceMat", 0);
  286.     pAvgTrainImg = (IplImage *)cvReadByName(fileStorage, 0, "avgTrainImg", 0);
  287.     eigenVectArr = (IplImage **)cvAlloc(nTrainFaces*sizeof(IplImage *));
  288.     for(i=0; i<nEigens; i++)
  289.     {
  290.         char varname[200];
  291.         snprintf( varname, sizeof(varname)-1, "eigenVect_%d", i );
  292.         eigenVectArr[i] = (IplImage *)cvReadByName(fileStorage, 0, varname, 0);
  293.     }
  294.  
  295.     // release the file-storage interface
  296.     cvReleaseFileStorage( &fileStorage );
  297.  
  298.     printf("Training data loaded (%d training images of %d people):\n", nTrainFaces, nPersons);
  299.     printf("People: ");
  300.     if (nPersons > 0)
  301.         printf("<%s>", personNames[0].c_str());
  302.     for (i=1; i<nPersons; i++) {
  303.         printf(", <%s>", personNames[i].c_str());
  304.     }
  305.     printf(".\n");
  306.  
  307.     return 1;
  308. }
  309.  
  310.  
  311. // Save the training data
  312. void storeTrainingData()
  313. {
  314.     CvFileStorage * fileStorage;
  315.     int i;
  316.  
  317.     char buf[256];
  318.       char str[15];
  319. //      sprintf(str, "%d", c);
  320.     snprintf(buf, sizeof buf, "%s%s", A0, ".xml");
  321.  
  322.     // create a file-storage interface
  323.     fileStorage = cvOpenFileStorage( buf, 0, CV_STORAGE_WRITE );
  324.  
  325.     // Store the person names. Added by Shervin.
  326.     cvWriteInt( fileStorage, "nPersons", nPersons );
  327.     for (i=0; i<nPersons; i++) {
  328.         char varname[200];
  329.         snprintf( varname, sizeof(varname)-1, "personName_%d", (i+1) );
  330.         cvWriteString(fileStorage, varname, personNames[i].c_str(), 0);
  331.     }
  332.  
  333.     // store all the data
  334.     cvWriteInt( fileStorage, "nEigens", nEigens );
  335.     cvWriteInt( fileStorage, "nTrainFaces", nTrainFaces );
  336.     cvWrite(fileStorage, "trainPersonNumMat", personNumTruthMat, cvAttrList(0,0));
  337.     cvWrite(fileStorage, "eigenValMat", eigenValMat, cvAttrList(0,0));
  338.     cvWrite(fileStorage, "projectedTrainFaceMat", projectedTrainFaceMat, cvAttrList(0,0));
  339.     cvWrite(fileStorage, "avgTrainImg", pAvgTrainImg, cvAttrList(0,0));
  340.     for(i=0; i<nEigens; i++)
  341.     {
  342.         char varname[200];
  343.         snprintf( varname, sizeof(varname)-1, "eigenVect_%d", i );
  344.         cvWrite(fileStorage, varname, eigenVectArr[i], cvAttrList(0,0));
  345.     }
  346.  
  347.     // release the file-storage interface
  348.     cvReleaseFileStorage( &fileStorage );
  349. }
  350.  
  351. // Find the most likely person based on a detection. Returns the index, and stores the confidence value into pConfidence.
  352. int findNearestNeighbor(float * projectedTestFace, float *pConfidence)
  353. {
  354.     //double leastDistSq = 1e12;
  355.     double leastDistSq = DBL_MAX;
  356.     int i, iTrain, iNearest = 0;
  357.  
  358.     for(iTrain=0; iTrain<nTrainFaces; iTrain++)
  359.     {
  360.         double distSq=0;
  361.  
  362.         for(i=0; i<nEigens; i++)
  363.         {
  364.             float d_i = projectedTestFace[i] - projectedTrainFaceMat->data.fl[iTrain*nEigens + i];
  365. #ifdef USE_MAHALANOBIS_DISTANCE
  366.             distSq += d_i*d_i / eigenValMat->data.fl[i];  // Mahalanobis distance (might give better results than Eucalidean distance)
  367. #else
  368.             distSq += d_i*d_i; // Euclidean distance.
  369. #endif
  370.         }
  371.  
  372.         if(distSq < leastDistSq)
  373.         {
  374.             leastDistSq = distSq;
  375.             iNearest = iTrain;
  376.         }
  377.     }
  378.  
  379.     // Return the confidence level based on the Euclidean distance,
  380.     // so that similar images should give a confidence between 0.5 to 1.0,
  381.     // and very different images should give a confidence between 0.0 to 0.5.
  382.     *pConfidence = 1.0f - sqrt( leastDistSq / (float)(nTrainFaces * nEigens) ) / 255.0f;
  383.  
  384.     // Return the found index.
  385.     return iNearest;
  386. }
  387.  
  388. // Do the Principal Component Analysis, finding the average image
  389. // and the eigenfaces that represent any image in the given dataset.
  390. void doPCA()
  391. {
  392.     int i;
  393.     CvTermCriteria calcLimit;
  394.     CvSize faceImgSize;
  395.  
  396.     // set the number of eigenvalues to use
  397.     nEigens = nTrainFaces-1;
  398.  
  399.     // allocate the eigenvector images
  400.     faceImgSize.width  = faceImgArr[0]->width;
  401.     faceImgSize.height = faceImgArr[0]->height;
  402.     eigenVectArr = (IplImage**)cvAlloc(sizeof(IplImage*) * nEigens);
  403.     for(i=0; i<nEigens; i++)
  404.         eigenVectArr[i] = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1);
  405.  
  406.     // allocate the eigenvalue array
  407.     eigenValMat = cvCreateMat( 1, nEigens, CV_32FC1 );
  408.  
  409.     // allocate the averaged image
  410.     pAvgTrainImg = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1);
  411.  
  412.     // set the PCA termination criterion
  413.     calcLimit = cvTermCriteria( CV_TERMCRIT_ITER, nEigens, 1);
  414.  
  415.     // compute average image, eigenvalues, and eigenvectors
  416.     cvCalcEigenObjects(
  417.         nTrainFaces,
  418.         (void*)faceImgArr,
  419.         (void*)eigenVectArr,
  420.         CV_EIGOBJ_NO_CALLBACK,
  421.         0,
  422.         0,
  423.         &calcLimit,
  424.         pAvgTrainImg,
  425.         eigenValMat->data.fl);
  426.  
  427.     cvNormalize(eigenValMat, eigenValMat, 1, 0, CV_L1, 0);
  428. }
  429.  
  430. // Read the names & image filenames of people from a text file, and load all those images listed.
  431. int loadFaceImgArray(const char * filename)
  432. {
  433.     FILE * imgListFile = 0;
  434.     char imgFilename[512];
  435.     int iFace, nFaces=0;
  436.     int i;
  437.  
  438.     // open the input file
  439.     if( !(imgListFile = fopen(filename, "r")) )
  440.     {
  441.         fprintf(stderr, "Can\'t open file %s\n", filename);
  442.         return 0;
  443.     }
  444.  
  445.     // count the number of faces
  446.     while( fgets(imgFilename, sizeof(imgFilename)-1, imgListFile) ) ++nFaces;
  447.     rewind(imgListFile);
  448.  
  449.     // allocate the face-image array and person number matrix
  450.     faceImgArr        = (IplImage **)cvAlloc( nFaces*sizeof(IplImage *) );
  451.     personNumTruthMat = cvCreateMat( 1, nFaces, CV_32SC1 );
  452.  
  453.     personNames.clear();    // Make sure it starts as empty.
  454.     nPersons = 0;
  455.  
  456.     // store the face images in an array
  457.     for(iFace=0; iFace<nFaces; iFace++)
  458.     {
  459.         char personName[256];
  460.         string sPersonName;
  461.         int personNumber;
  462.  
  463.         // read person number (beginning with 1), their name and the image filename.
  464.         fscanf(imgListFile, "%d %s %s", &personNumber, personName, imgFilename);
  465.         sPersonName = personName;
  466.         //printf("Got %d: %d, <%s>, <%s>.\n", iFace, personNumber, personName, imgFilename);
  467.  
  468.         // Check if a new person is being loaded.
  469.         if (personNumber > nPersons) {
  470.             // Allocate memory for the extra person (or possibly multiple), using this new person's name.
  471.             for (i=nPersons; i < personNumber; i++) {
  472.                 personNames.push_back( sPersonName );
  473.             }
  474.             nPersons = personNumber;
  475.             //printf("Got new person <%s> -> nPersons = %d [%d]\n", sPersonName.c_str(), nPersons, personNames.size());
  476.         }
  477.  
  478.         // Keep the data
  479.         personNumTruthMat->data.i[iFace] = personNumber;
  480.  
  481.         // load the face image
  482.         faceImgArr[iFace] = cvLoadImage(imgFilename, CV_LOAD_IMAGE_GRAYSCALE);
  483.  
  484.         if( !faceImgArr[iFace] )
  485.         {
  486.             fprintf(stderr, "Can\'t load image from %s\n", imgFilename);
  487.             return 0;
  488.         }
  489.     }
  490.  
  491.     fclose(imgListFile);
  492.  
  493.     printf("Data loaded from '%s': (%d images of %d people).\n", filename, nFaces, nPersons);
  494.     printf("People: ");
  495.     if (nPersons > 0)
  496.         printf("<%s>", personNames[0].c_str());
  497.     for (i=1; i<nPersons; i++) {
  498.         printf(", <%s>", personNames[i].c_str());
  499.     }
  500.     printf(".\n");
  501.  
  502.     return nFaces;
  503. }
  504.  
  505.  
  506. // Recognize the face in each of the test images given, and compare the results with the truth.
  507. void recognizeFileList(const char *szFileTest)
  508. {
  509.     int i, nTestFaces  = 0;         // the number of test images
  510.     CvMat * trainPersonNumMat = 0;  // the person numbers during training
  511.     float * projectedTestFace = 0;
  512.     const char *answer;
  513.     int nCorrect = 0;
  514.     int nWrong = 0;
  515.     double timeFaceRecognizeStart;
  516.     double tallyFaceRecognizeTime;
  517.     float confidence;
  518.  
  519.     // load test images and ground truth for person number
  520.     nTestFaces = loadFaceImgArray(szFileTest);
  521.     printf("%d test faces loaded\n", nTestFaces);
  522.  
  523.     // load the saved training data
  524.     if( !loadTrainingData( &trainPersonNumMat ) )
  525.         printf("%s","what the heck");
  526.         return;
  527.  
  528.     // project the test images onto the PCA subspace
  529.     projectedTestFace = (float *)cvAlloc( nEigens*sizeof(float) );
  530.     timeFaceRecognizeStart = (double)cvGetTickCount();  // Record the timing.
  531.     for(i=0; i<nTestFaces; i++)
  532.     {
  533.         int iNearest, nearest, truth;
  534.  
  535.         // project the test image onto the PCA subspace
  536.         cvEigenDecomposite(
  537.             faceImgArr[i],
  538.             nEigens,
  539.             eigenVectArr,
  540.             0, 0,
  541.             pAvgTrainImg,
  542.             projectedTestFace);
  543.  
  544.         iNearest = findNearestNeighbor(projectedTestFace, &confidence);
  545.         truth    = personNumTruthMat->data.i[i];
  546.         nearest  = trainPersonNumMat->data.i[iNearest];
  547.  
  548.         if (nearest == truth) {
  549.             answer = "Correct";
  550.             nCorrect++;
  551.         }
  552.         else {
  553.             answer = "WRONG!";
  554.             nWrong++;
  555.         }
  556.         printf("nearest = %d, Truth = %d (%s). Confidence = %f\n", nearest, truth, answer, confidence);
  557.     }
  558.     tallyFaceRecognizeTime = (double)cvGetTickCount() - timeFaceRecognizeStart;
  559.     if (nCorrect+nWrong > 0) {
  560.         printf("TOTAL ACCURACY: %d%% out of %d tests.\n", nCorrect * 100/(nCorrect+nWrong), (nCorrect+nWrong));
  561.         printf("TOTAL TIME: %.1fms average.\n", tallyFaceRecognizeTime/((double)cvGetTickFrequency() * 1000.0 * (nCorrect+nWrong) ) );
  562.     }
  563. }
  564.  
  565. // Grab the next camera frame. Waits until the next frame is ready,
  566. // and provides direct access to it, so do NOT modify the returned image or free it!
  567. // Will automatically initialize the camera on the first frame.
  568. IplImage* getCameraFrame(void)
  569. {
  570.     IplImage *frame;
  571.  
  572.     // If the camera hasn't been initialized, then open it.
  573.     if (!camera) {
  574.         printf("Acessing the camera ...\n");
  575.         camera = cvCaptureFromCAM( 0 );
  576.         if (!camera) {
  577.             printf("ERROR in getCameraFrame(): Couldn't access the camera.\n");
  578.             exit(1);
  579.         }
  580.         // Try to set the camera resolution
  581.         cvSetCaptureProperty( camera, CV_CAP_PROP_FRAME_WIDTH, 320 );
  582.         cvSetCaptureProperty( camera, CV_CAP_PROP_FRAME_HEIGHT, 240 );
  583.         cvSetCaptureProperty( camera, CV_CAP_PROP_BRIGHTNESS, 100 );
  584.         // Wait a little, so that the camera can auto-adjust itself
  585.         #if defined WIN32 || defined _WIN32
  586.             Sleep(5000);    // (in milliseconds)
  587.         #endif
  588.         frame = cvQueryFrame( camera ); // get the first frame, to make sure the camera is initialized.
  589.         if (frame) {
  590.             printf("Got a camera using a resolution of %dx%d.\n", (int)cvGetCaptureProperty( camera, CV_CAP_PROP_FRAME_WIDTH), (int)cvGetCaptureProperty( camera, CV_CAP_PROP_FRAME_HEIGHT) );
  591.         }
  592.     }
  593.  
  594.     frame = cvQueryFrame( camera );
  595.     if (!frame) {
  596.         fprintf(stderr, "ERROR in recognizeFromCam(): Could not access the camera or video file.\n");
  597.         exit(1);
  598.         //return NULL;
  599.     }
  600.     return frame;
  601. }
  602.  
  603. // Return a new image that is always greyscale, whether the input image was RGB or Greyscale.
  604. // Remember to free the returned image using cvReleaseImage() when finished.
  605. IplImage* convertImageToGreyscale(const IplImage *imageSrc)
  606. {
  607.     IplImage *imageGrey;
  608.     // Either convert the image to greyscale, or make a copy of the existing greyscale image.
  609.     // This is to make sure that the user can always call cvReleaseImage() on the output, whether it was greyscale or not.
  610.     if (imageSrc->nChannels == 3) {
  611.         imageGrey = cvCreateImage( cvGetSize(imageSrc), IPL_DEPTH_8U, 1 );
  612.         cvCvtColor( imageSrc, imageGrey, CV_BGR2GRAY );
  613.     }
  614.     else {
  615.         imageGrey = cvCloneImage(imageSrc);
  616.     }
  617.     return imageGrey;
  618. }
  619.  
  620. // Creates a new image copy that is of a desired size.
  621. // Remember to free the new image later.
  622. IplImage* resizeImage(const IplImage *origImg, int newWidth, int newHeight)
  623. {
  624.     IplImage *outImg = 0;
  625.     int origWidth;
  626.     int origHeight;
  627.     if (origImg) {
  628.         origWidth = origImg->width;
  629.         origHeight = origImg->height;
  630.     }
  631.     if (newWidth <= 0 || newHeight <= 0 || origImg == 0 || origWidth <= 0 || origHeight <= 0) {
  632.         printf("ERROR in resizeImage: Bad desired image size of %dx%d\n.", newWidth, newHeight);
  633.         exit(1);
  634.     }
  635.  
  636.     // Scale the image to the new dimensions, even if the aspect ratio will be changed.
  637.     outImg = cvCreateImage(cvSize(newWidth, newHeight), origImg->depth, origImg->nChannels);
  638.     //FIND
  639. //  cvSaveImage("NewPic.jpg",outImg);
  640.    
  641.     if (newWidth > origImg->width && newHeight > origImg->height) {
  642.         // Make the image larger
  643.         cvResetImageROI((IplImage*)origImg);
  644.         cvResize(origImg, outImg, CV_INTER_LINEAR); // CV_INTER_CUBIC or CV_INTER_LINEAR is good for enlarging
  645.     }
  646.     else {
  647.         // Make the image smaller
  648.         cvResetImageROI((IplImage*)origImg);
  649.         cvResize(origImg, outImg, CV_INTER_AREA);   // CV_INTER_AREA is good for shrinking / decimation, but bad at enlarging.
  650.     }
  651.    
  652.     return outImg;
  653. }
  654.  
  655. // Returns a new image that is a cropped version of the original image.
  656. IplImage* cropImage(const IplImage *img, const CvRect region)
  657. {
  658.     IplImage *imageTmp;
  659.     IplImage *imageRGB;
  660.     CvSize size;
  661.     size.height = img->height;
  662.     size.width = img->width;
  663.  
  664.     if (img->depth != IPL_DEPTH_8U) {
  665.         printf("ERROR in cropImage: Unknown image depth of %d given in cropImage() instead of 8 bits per pixel.\n", img->depth);
  666.         exit(1);
  667.     }
  668.  
  669.     // First create a new (color or greyscale) IPL Image and copy contents of img into it.
  670.     imageTmp = cvCreateImage(size, IPL_DEPTH_8U, img->nChannels);
  671.     cvCopy(img, imageTmp, NULL);
  672.  
  673.     // Create a new image of the detected region
  674.     // Set region of interest to that surrounding the face
  675.     cvSetImageROI(imageTmp, region);
  676.     // Copy region of interest (i.e. face) into a new iplImage (imageRGB) and return it
  677.     size.width = region.width;
  678.     size.height = region.height;
  679.     imageRGB = cvCreateImage(size, IPL_DEPTH_8U, img->nChannels);
  680.     cvCopy(imageTmp, imageRGB, NULL);   // Copy just the region.
  681.  
  682.     cvReleaseImage( &imageTmp );
  683.     return imageRGB;       
  684. }
  685.  
  686. // Get an 8-bit equivalent of the 32-bit Float image.
  687. // Returns a new image, so remember to call 'cvReleaseImage()' on the result.
  688. IplImage* convertFloatImageToUcharImage(const IplImage *srcImg)
  689. {
  690.     IplImage *dstImg = 0;
  691.     if ((srcImg) && (srcImg->width > 0 && srcImg->height > 0)) {
  692.  
  693.         // Spread the 32bit floating point pixels to fit within 8bit pixel range.
  694.         double minVal, maxVal;
  695.         cvMinMaxLoc(srcImg, &minVal, &maxVal);
  696.  
  697.         //cout << "FloatImage:(minV=" << minVal << ", maxV=" << maxVal << ")." << endl;
  698.  
  699.         // Deal with NaN and extreme values, since the DFT seems to give some NaN results.
  700.         if (cvIsNaN(minVal) || minVal < -1e30)
  701.             minVal = -1e30;
  702.         if (cvIsNaN(maxVal) || maxVal > 1e30)
  703.             maxVal = 1e30;
  704.         if (maxVal-minVal == 0.0f)
  705.             maxVal = minVal + 0.001;    // remove potential divide by zero errors.
  706.  
  707.         // Convert the format
  708.         dstImg = cvCreateImage(cvSize(srcImg->width, srcImg->height), 8, 1);
  709.         cvConvertScale(srcImg, dstImg, 255.0 / (maxVal - minVal), - minVal * 255.0 / (maxVal-minVal));
  710.     }
  711.     return dstImg;
  712. }
  713.  
  714. // Store a greyscale floating-point CvMat image into a BMP/JPG/GIF/PNG image,
  715. // since cvSaveImage() can only handle 8bit images (not 32bit float images).
  716. void saveFloatImage(const char *filename, const IplImage *srcImg)
  717. {
  718.     //cout << "Saving Float Image '" << filename << "' (" << srcImg->width << "," << srcImg->height << "). " << endl;
  719.     IplImage *byteImg = convertFloatImageToUcharImage(srcImg);
  720.     cvSaveImage(filename, byteImg);
  721.     cvReleaseImage(&byteImg);
  722. }
  723.  
  724. // Perform face detection on the input image, using the given Haar cascade classifier.
  725. // Returns a rectangle for the detected region in the given image.
  726.  
  727. CvRect detectFaceInImage(const IplImage *inputImg, const CvHaarClassifierCascade* cascade )
  728. {
  729.     const CvSize minFeatureSize = cvSize(20, 20);
  730.     const int flags = CV_HAAR_FIND_BIGGEST_OBJECT | CV_HAAR_DO_ROUGH_SEARCH;    // Only search for 1 face.
  731.     const float search_scale_factor = 1.1f;
  732.     IplImage *detectImg;
  733.     IplImage *greyImg = 0;
  734.     CvMemStorage* storage;
  735.     CvRect rc;
  736.     double t;
  737.     CvSeq* rects;
  738.     //int i;
  739.  
  740.     storage = cvCreateMemStorage(0);
  741.     cvClearMemStorage( storage );
  742.     // If the image is color, use a greyscale copy of the image.
  743.     detectImg = (IplImage*)inputImg;    // Assume the input image is to be used.
  744.     if (inputImg->nChannels > 1)
  745.     {
  746.         greyImg = cvCreateImage(cvSize(inputImg->width, inputImg->height), IPL_DEPTH_8U, 1 );
  747.         cvCvtColor( inputImg, greyImg, CV_BGR2GRAY );
  748.         detectImg = greyImg;    // Use the greyscale version as the input.
  749.     }
  750.     // Detect all the faces.
  751.     t = (double)cvGetTickCount();
  752.     rects = cvHaarDetectObjects( detectImg, (CvHaarClassifierCascade*)cascade, storage,
  753.                 search_scale_factor, 3, flags, minFeatureSize );
  754.     t = (double)cvGetTickCount() - t;
  755.     printf("[Face Detection took %d ms and found %d objects]\n", cvRound( t/((double)cvGetTickFrequency()*1000.0) ), rects->total );
  756.  
  757.     // Get the first detected face (the biggest).
  758.     if (rects->total > 0) {
  759.         rc = *(CvRect*)cvGetSeqElem( rects, 0 );
  760.     }
  761.     else
  762.         rc = cvRect(-1,-1,-1,-1);   // Couldn't find the face.
  763.     if (greyImg)
  764.         cvReleaseImage( &greyImg );
  765.         cvReleaseMemStorage( &storage );
  766.  
  767.     return rc;  // Return the biggest face found, or (-1,-1,-1,-1).
  768. }
  769.  
  770. CvMat* retrainOnline(void)
  771. {
  772.     CvMat *trainPersonNumMat;
  773.     int i;
  774.  
  775.     // Free & Re-initialize the global variables.
  776.     if (faceImgArr) {
  777.         for (i=0; i<nTrainFaces; i++) {
  778.             if (faceImgArr[i])
  779.                 cvReleaseImage( &faceImgArr[i] );
  780.         }
  781.     }
  782.     cvFree( &faceImgArr ); // array of face images
  783.     cvFree( &personNumTruthMat ); // array of person numbers
  784.     personNames.clear();            // array of person names (indexed by the person number). Added by Shervin.
  785.     nPersons = 0; // the number of people in the training set. Added by Shervin.
  786.     nTrainFaces = 0; // the number of training images
  787.     nEigens = 0; // the number of eigenvalues
  788.     cvReleaseImage( &pAvgTrainImg ); // the average image
  789.     for (i=0; i<nTrainFaces; i++) {
  790.         if (eigenVectArr[i])
  791.             cvReleaseImage( &eigenVectArr[i] );
  792.     }
  793.     cvFree( &eigenVectArr ); // eigenvectors
  794.     cvFree( &eigenValMat ); // eigenvalues
  795.     cvFree( &projectedTrainFaceMat ); // projected training faces
  796.  
  797.     // Retrain from the data in the files
  798.     printf("Retraining with the new person ...\n");
  799. //peter
  800.     char buf[256];
  801.     char str[15];
  802. //    sprintf(str, "%d", c);
  803.     snprintf(buf, sizeof buf, "%s%s", A0, ".txt");
  804.     learn(buf);
  805.     printf("Done retraining.\n");
  806.  
  807.     // Load the previously saved training data
  808.     if( !loadTrainingData( &trainPersonNumMat ) ) {
  809.         printf("ERROR in recognizeFromCam(): Couldn't load the training data!\n");
  810.         exit(1);
  811.     }
  812.  
  813.     return trainPersonNumMat;
  814. }
  815.  
  816. // Continuously recognize the person in the camera.
  817. int recognizeFromCam(void)
  818. {
  819.    
  820.   char astr[120];  
  821.   // printf("PATH='%s%s'\n", getenv("HOME"), "/user/share");
  822.    snprintf(astr, sizeof astr, "%s%s", getenv("HOME"), "/user/share/haarcascade_frontalface_alt2.xml");
  823.    printf("%s\n",astr);
  824.    const char *faceCascadeFilename = astr;
  825.    
  826.    
  827.     int i;
  828.     CvMat * trainPersonNumMat;  // the person numbers during training
  829.     float * projectedTestFace;
  830.     double timeFaceRecognizeStart;
  831.     double tallyFaceRecognizeTime;
  832.     CvHaarClassifierCascade* faceCascade;
  833.     char cstr[256];
  834.     BOOL saveNextFaces = FALSE;
  835.     char newPersonName[256];
  836.     int newPersonFaces;
  837. //counters
  838.     int a = 5;
  839.     int b = 15;
  840.     int c = 40;
  841.     int d = 2;
  842.     int e = 100;
  843.    
  844. //not used
  845.  
  846.     trainPersonNumMat = 0;  // the person numbers during training
  847.     projectedTestFace = 0;
  848.     saveNextFaces = FALSE;
  849.     newPersonFaces = 0;
  850.  
  851.     printf("Recognizing person in the camera ...\n");
  852.  
  853.     // Load the previously saved training data
  854.     if( loadTrainingData( &trainPersonNumMat ) ) {
  855.         faceWidth = pAvgTrainImg->width;
  856.         faceHeight = pAvgTrainImg->height;
  857.     }
  858.     else {
  859.         //peter debug
  860.         printf("ERROR in recognizeFromCam(): Couldn't load the training data! Person not trained?\n");
  861.         return 0;
  862.     }
  863.  
  864.     // Project the test images onto the PCA subspace
  865.     projectedTestFace = (float *)cvAlloc( nEigens*sizeof(float) );
  866.  
  867.  
  868.     char newdir[256];
  869.     snprintf(newdir, sizeof newdir, "%s%s", A0, "_");
  870.  
  871.     // Make sure there is a "data" folder, for storing the new person.
  872.     #if defined WIN32 || defined _WIN32
  873.         mkdir(c);
  874.     #else
  875.    
  876.         // For Linux, make the folder to be Read-Write-Executable for this user & group but only Readable for others.
  877.         mkdir(A0, S_IRWXU | S_IRWXG | S_IROTH);
  878.         mkdir(newdir, S_IRWXU | S_IRWXG | S_IROTH);
  879.     #endif
  880.  
  881.     // Load the HaarCascade classifier for face detection.
  882.     faceCascade = (CvHaarClassifierCascade*)cvLoad(faceCascadeFilename, 0, 0, 0 );
  883.     if( !faceCascade ) {
  884.         printf("ERROR in recognizeFromCam(): Could not load Haar cascade Face detection classifier in '%s'.\n", faceCascadeFilename);
  885.         return 0;
  886.     }
  887.  
  888.     // Tell the Linux terminal to return the 1st keypress instead of waiting for an ENTER key.
  889.     changeKeyboardMode(1);
  890.  
  891.     timeFaceRecognizeStart = (double)cvGetTickCount();  // Record the timing.
  892.  
  893.     while (1)
  894.     {
  895. //      int iNearest, nearest, truth;
  896.         int iNearest, nearest;
  897.         IplImage *camImg;
  898.         IplImage *greyImg;
  899.         IplImage *faceImg;
  900.         IplImage *sizedImg;
  901.         IplImage *equalizedImg;
  902.         IplImage *processedFaceImg;
  903.         CvRect faceRect;
  904. //peter remove ui
  905. //      IplImage *shownImg;
  906.         int keyPressed = 0;
  907.         FILE *trainFile;
  908.         float confidence;
  909.  
  910.         // Handle non-blocking keyboard input in the console.
  911.         if (kbhit())
  912.             keyPressed = getch();
  913.        
  914.         if (keyPressed == VK_ESCAPE) {  // Check if the user hit the 'Escape' key
  915.             break;  // Stop processing input.
  916.         }
  917.         switch (keyPressed) {
  918.             case 'n':   // Add a new person to the training set.
  919.                 // Train from the following images.
  920.                 printf("Enter your name: ");
  921.                 strcpy(newPersonName, "newPerson");
  922.  
  923.                 // Read a string from the console. Waits until they hit ENTER.
  924.                 changeKeyboardMode(0);
  925.                 fgets(newPersonName, sizeof(newPersonName)-1, stdin);
  926.                 changeKeyboardMode(1);
  927.                 // Remove 1 or 2 newline characters if they were appended (eg: Linux).
  928.                 i = strlen(newPersonName);
  929.                 if (i > 0 && (newPersonName[i-1] == 10 || newPersonName[i-1] == 13)) {
  930.                     newPersonName[i-1] = 0;
  931.                     i--;
  932.                 }
  933.                 if (i > 0 && (newPersonName[i-1] == 10 || newPersonName[i-1] == 13)) {
  934.                     newPersonName[i-1] = 0;
  935.                     i--;
  936.                 }
  937.                 if (i > 0) {
  938.                     printf("i s value '%i' ...\n", i);
  939.                     printf("Collecting all images until you hit 't', to start Training the images as '%s' ...\n", newPersonName);
  940.                     newPersonFaces = 0; // restart training a new person
  941.                     saveNextFaces = TRUE;
  942.                 }
  943.                 else {
  944.                     printf("Did not get a valid name from you, so will ignore it. Hit 'n' to retry.\n");
  945.                 }
  946.    
  947.                 break;
  948.    
  949.                 strcpy(newPersonName, "newPerson");
  950.                // char PersonName[256];
  951.                 snprintf(newPersonName, sizeof newPersonName, "%s%s", A0, "_");
  952.                     saveNextFaces = TRUE;
  953.    
  954.               case 't': // Start training
  955.                 saveNextFaces = FALSE;  // stop saving next faces.
  956.                 // Store the saved data into the training file.
  957.                 printf("Storing the training data for new person '%s'.\n", newPersonName);
  958.                 // Append the new person to the end of the training data.
  959.                
  960.                
  961.                 char buf[256];
  962.                 snprintf(buf, sizeof buf, "%s%s", A0, ".txt");
  963.                
  964.                 trainFile = fopen(buf, "a");
  965.                
  966.                 for (i=0; i<newPersonFaces; i++) {
  967.                     char newd[256];
  968.                       char str[15];
  969.                     snprintf(newd, sizeof newd, "%s%s", A0, "/%d_%s%d.pgm");
  970.                
  971.                     snprintf(cstr, sizeof(cstr)-1, newd, nPersons+1, newPersonName, i+1);
  972.                     fprintf(trainFile, "%d %s %s\n", nPersons+1, newPersonName, cstr);
  973.                 }
  974.                 fclose(trainFile);
  975.  
  976.                 // Re-initialize the local data.
  977.                 projectedTestFace = 0;
  978.                 saveNextFaces = FALSE;
  979.                 newPersonFaces = 0;
  980.  
  981.                 // Retrain from the new database without shutting down.
  982.                 // Depending on the number of images in the training set and number of people, it might take 30 seconds or so.
  983.                 cvFree( &trainPersonNumMat );   // Free the previous data before getting new data
  984.                 trainPersonNumMat = retrainOnline();
  985.                 // Project the test images onto the PCA subspace
  986.                 cvFree(&projectedTestFace); // Free the previous data before getting new data
  987.                 projectedTestFace = (float *)cvAlloc( nEigens*sizeof(float) );
  988.  
  989.                 printf("Recognizing person in the camera ...\n");
  990.                 continue;   // Begin with the next frame.
  991.                 break;
  992.         }
  993.  
  994.         // Get the camera frame
  995.         camImg = getCameraFrame();
  996.         if (!camImg) {
  997.             printf("ERROR in recognizeFromCam(): Bad input image!\n");
  998.             exit(1);
  999.         }
  1000.         // Make sure the image is greyscale, since the Eigenfaces is only done on greyscale image.
  1001.         greyImg = convertImageToGreyscale(camImg);
  1002.  
  1003.         // Perform face detection on the input image, using the given Haar cascade classifier.
  1004.         faceRect = detectFaceInImage(greyImg, faceCascade );
  1005.  
  1006.         if ( faceRect.x == -1 ) {
  1007.             e--;
  1008.             if (e < 1){
  1009.                 printf("Failed to find face and timed out\n");
  1010.                 changeKeyboardMode(0);
  1011.                 return 0;
  1012.                 }
  1013.         }
  1014.         // Make sure a valid face was detected.
  1015.         if (faceRect.width > 0) {
  1016.             faceImg = cropImage(greyImg, faceRect); // Get the detected face image.
  1017.             // Make sure the image is the same dimensions as the training images.
  1018.             sizedImg = resizeImage(faceImg, faceWidth, faceHeight);
  1019.             // Give the image a standard brightness and contrast, in case it was too dark or low contrast.
  1020.             equalizedImg = cvCreateImage(cvGetSize(sizedImg), 8, 1);    // Create an empty greyscale image
  1021.             cvEqualizeHist(sizedImg, equalizedImg);
  1022.             processedFaceImg = equalizedImg;
  1023.             if (!processedFaceImg) {
  1024.                 printf("ERROR in recognizeFromCam(): Don't have input image!\n");
  1025.                 exit(1);
  1026.             }
  1027.  
  1028.             // If the face rec database has been loaded, then try to recognize the person currently detected.
  1029.             if (nEigens > 0) {
  1030.                 // project the test image onto the PCA subspace
  1031.                 cvEigenDecomposite(
  1032.                     processedFaceImg,
  1033.                     nEigens,
  1034.                     eigenVectArr,
  1035.                     0, 0,
  1036.                     pAvgTrainImg,
  1037.                     projectedTestFace);
  1038.  
  1039.                 // Check which person it is most likely to be.
  1040.                 iNearest = findNearestNeighbor(projectedTestFace, &confidence);
  1041.                 nearest  = trainPersonNumMat->data.i[iNearest];
  1042.                 printf("I AM HERE!!! '%s' (confidence=%f).\n", personNames[nearest-1].c_str(), (confidence*confidence));
  1043.  /**
  1044.   * //for non euclidean matching
  1045.   *
  1046.                  if ((confidence*confidence) < 1){
  1047.                     printf("MMM Not sure!!! '%s' (confidence=%f).\n", personNames[nearest-1].c_str(), (confidence*confidence));
  1048.                     d--;
  1049.                     if (d < 1){
  1050.                         cmpFaces();
  1051.                         printf("HELLO THERE, WELCOME '%s' (confidence=%f).\n", personNames[nearest-1].c_str(), confidence);
  1052.                         changeKeyboardMode(0);
  1053.                         return;
  1054.                         }
  1055.                     }
  1056. **/
  1057.    
  1058.                  if (confidence < 0.80){
  1059.                     printf("MMM Not sure!!! '%s' (confidence=%f).\n", personNames[nearest-1].c_str(), confidence);
  1060.                     printf("FOUND! '%i' \n", a);
  1061.                     c--;
  1062.                     if (c < 1){
  1063.                         printf("CLOSE BUT NO CIGAR '%s' (confidence=%f).\n", personNames[nearest-1].c_str(), confidence);
  1064.                         changeKeyboardMode(0);
  1065.                         return 0;
  1066.                         }
  1067.                     }
  1068.  
  1069.  
  1070.                 if (confidence > 0.91){
  1071.                     printf("FOUND GOOD MATCH!!! '%s' (confidence=%f).\n", personNames[nearest-1].c_str(), confidence);
  1072.                     printf("FOUND! '%i' \n", a);
  1073.                     a--;
  1074.                     if (a < 1)
  1075.  
  1076. {
  1077.  
  1078. //FIND 123
  1079.                     {
  1080.                             printf("PASSED FOR '%s' (confidence=%f).\n", personNames[nearest-1].c_str(), confidence);
  1081.                             changeKeyboardMode(0);
  1082.                             return 0;
  1083.                     }
  1084.                 }
  1085.  
  1086. }
  1087.  
  1088.                 if (confidence < 0.5){
  1089.                     printf("VERY BAD MATCH!!! '%s' (confidence=%f).\n", personNames[nearest-1].c_str(), confidence);
  1090.                     b--;
  1091.                     if (b < 1){
  1092.                         printf("FAILED '%s' (confidence=%f).\n", personNames[nearest-1].c_str(), confidence);
  1093.                         changeKeyboardMode(0);
  1094.                         return 0;  
  1095.                         }
  1096.  
  1097.                     }
  1098.  
  1099.  
  1100.                 printf("Looking for in camera: '%s' (confidence=%f).\n", personNames[nearest-1].c_str(), confidence);
  1101.  
  1102.             }//endif nEigens
  1103.  
  1104.             // Possibly save the processed face to the training set.
  1105.             if (saveNextFaces) {
  1106. // MAYBE GET IT TO ONLY TRAIN SOME IMAGES ?
  1107.                 // Use a different filename each time.
  1108.                 char newd[256];
  1109.                   char str[15];
  1110.                 snprintf(newd, sizeof newd, "%s%s", A0, "/%d_%s%d.pgm");
  1111.                 //PETER FIND
  1112.                 snprintf(cstr, sizeof(cstr)-1, newd, nPersons+1, newPersonName, newPersonFaces+1);
  1113.                 printf("Storing the current face of '%s' into image '%s'.\n", newPersonName, cstr);
  1114.                 cvSaveImage(cstr, processedFaceImg, NULL);
  1115.                 newPersonFaces++;
  1116.             }
  1117.  
  1118.             // Free the resources used for this frame.
  1119.             cvReleaseImage( &greyImg );
  1120.             cvReleaseImage( &faceImg );
  1121.             cvReleaseImage( &sizedImg );
  1122.             cvReleaseImage( &equalizedImg );
  1123.         }
  1124.  
  1125.         // Show the data on the screen.
  1126.         char newdir[256];
  1127.         char newdir1[256];
  1128.  
  1129.  
  1130. //      shownImg = cvCloneImage(camImg);
  1131.         if (faceRect.width > 0) {   // Check if a face was detected.
  1132.             // Show the detected face region.
  1133.             if (nEigens > 0) {  // Check if the face recognition database is loaded and a person was recognized.
  1134.                 // Show the name of the recognized person, overlayed on the image below their face.
  1135.                 CvFont font;
  1136.                 cvInitFont(&font,CV_FONT_HERSHEY_PLAIN, 1.0, 1.0, 0,1,CV_AA);
  1137.                 CvScalar textColor = CV_RGB(0,255,255); // light blue text
  1138.                 char text[256];
  1139.                 snprintf(text, sizeof(text)-1, "Looking for: '%s'", personNames[nearest-1].c_str());
  1140.                 snprintf(text, sizeof(text)-1, "Confidence: %f", confidence);
  1141.             }
  1142.         }
  1143.  
  1144.         // Give some time for OpenCV to draw the GUI and check if the user has pressed something in the GUI window.
  1145.         keyPressed = cvWaitKey(10);
  1146.         if (keyPressed == VK_ESCAPE) {  // Check if the user hit the 'Escape' key in the GUI window.
  1147.             break;  // Stop processing input.
  1148.         }
  1149.  
  1150.     }
  1151.     tallyFaceRecognizeTime = (double)cvGetTickCount() - timeFaceRecognizeStart;
  1152.  
  1153.     // Reset the Linux terminal back to the original settings.
  1154.     changeKeyboardMode(0);
  1155.  
  1156.     // Free the camera and memory resources used.
  1157.     cvReleaseCapture( &camera );
  1158.     cvReleaseHaarClassifierCascade( &faceCascade );
  1159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement