// PCA wymaga poprawek ale zeby to sprawdzic musza byc wszystkie metody zrobione
  // PCA to glowna metoda algorytmu eigenface. To ona 'rozbija' twarz na wektory
  // i normalizuje dzieki czemu mozna je potem porownywac
  // i szukac najmniejszego 'distance'
  private void doPCA() {
    int i;
    CvTermCriteria calcLimit;
    CvSize faceImgSize = new CvSize();

    // set the number of eigenvalues to use
    nEigens = nTrainFaces - 1;

    // allocate the eigenvector images
    faceImgSize.width(trainingFaceImgArr[0].width());
    faceImgSize.height(trainingFaceImgArr[0].height());
    eigenVectArr = new IplImage[nEigens];

    for (i = 0; i < nEigens; i++) {
      eigenVectArr[i] =
          cvCreateImage(
              faceImgSize, // size
              IPL_DEPTH_32F, // depth
              1); // channels
    }
    // System.out.println(calcLimit);
    // allocate the eigenvalue array
    eigenValMat =
        cvCreateMat(
            1, // rows
            nEigens, // cols
            CV_32FC1); // type, 32-bit float, 1 channel

    // allocate the averaged image
    pAvgTrainImg =
        cvCreateImage(
            faceImgSize, // size
            IPL_DEPTH_32F, // depth
            1); // channels

    // set the PCA termination criterion
    calcLimit =
        cvTermCriteria(
            CV_TERMCRIT_ITER, // type
            nEigens, // max_iter
            1); // epsilon
    // compute average image, eigenvalues, and eigenvectors TU JEST PROBLEM
    cvCalcEigenObjects(
        nTrainFaces, // nObjects
        trainingFaceImgArr, // input
        eigenVectArr, // output
        CV_EIGOBJ_NO_CALLBACK, // ioFlags
        0, // ioBufSize
        null, // userData
        calcLimit,
        pAvgTrainImg, // avg
        eigenValMat.data_fl()); // eigVals
    // normalizacja czyli odjecie avarage face
    cvNormalize(
        eigenValMat, // src (CvArr)
        eigenValMat, // dst (CvArr)
        1, // a
        0, // b
        CV_L1, // norm_type
        null); // mask

    System.out.println("PCA done.");
  }
示例#2
0
  public void learn(String tmpImageDataOutput) {

    File folder = new File(tmpImageDataOutput);
    File[] listOfFiles = folder.listFiles();
    // load image to trainingFaces
    for (int i = 0; i < listOfFiles.length; i++) {
      if (listOfFiles[i].isFile()) {
        String file = listOfFiles[i].getName();
        String filepath = tmpImageDataOutput + "/" + file;
        IplImage tmpImage = cvLoadImage(filepath, CV_LOAD_IMAGE_GRAYSCALE);
        if (tmpImage != null) {
          trainingFaces.add(tmpImage);
        }
      }
    }
    int nfaces = trainingFaces.size();
    System.out.println("total: " + nfaces);
    // Does the Principal Component Analysis, finding the average image and the eigenfaces that
    // represent any image in the given dataset.....so call PCA
    // set the number of eigenvalues to use
    nTrainFaces = nfaces;
    nEigens = nTrainFaces - 1;
    CvTermCriteria calcLimit;
    CvSize faceImgSize = new CvSize();
    faceImgSize.width(trainingFaces.get(0).width());
    faceImgSize.height(trainingFaces.get(0).height());

    personNumTruthMat = cvCreateMat(1, nfaces, CV_32SC1);
    // rows ,nFaces,  type, 32-bit unsigned, one channel

    // initialize the person number matrix - for ease of debugging
    for (int j1 = 0; j1 < nfaces; j1++) {
      personNumTruthMat.put(0, j1, 0);
    }

    for (int i = 0; i < nEigens; i++) {
      eigens.add(
          cvCreateImage(
              faceImgSize, // size
              IPL_DEPTH_32F, // depth
              1)); // channels)
    }

    eigenValMat = cvCreateMat(1, nEigens, CV_32FC1); // type, 32-bit float, 1 channel
    // allocate the averaged image
    pAvgTrainImg =
        cvCreateImage(
            faceImgSize, // size
            IPL_DEPTH_32F, // depth
            1); // channels

    // set the PCA termination criterion
    calcLimit =
        cvTermCriteria(
            CV_TERMCRIT_ITER, // type
            nEigens, // max_iter
            1); // epsilon

    LOGGER.info("computing average image, eigenvalues and eigenvectors");
    // compute average image, eigenvalues, and eigenvectors
    eigenVectArr = eigens.toArray(new IplImage[eigens.size()]);
    cvCalcEigenObjects(
        nTrainFaces, // nObjects
        trainingFaces.toArray(new IplImage[trainingFaces.size()]), // input
        eigenVectArr, // the output is array... need to transfer to arrayList latter
        CV_EIGOBJ_NO_CALLBACK, // ioFlags
        0, // ioBufSize
        null, // userData
        calcLimit,
        pAvgTrainImg, // avg
        eigenValMat.data_fl()); // eigVals

    // eigens = (ArrayList) Arrays.asList(eigenVectArr)  ;

    LOGGER.info("normalizing the eigenvectors");
    cvNormalize(
        eigenValMat, // src (CvArr)
        eigenValMat, // dst (CvArr)
        1, // a
        0, // b
        CV_L1, // norm_type
        null); // mask

    LOGGER.info("projecting the training images onto the PCA subspace");
    // project the training images onto the PCA subspace
    projectedTrainFaceMat =
        cvCreateMat(
            nTrainFaces, // rows
            nEigens, // cols
            CV_32FC1); // type, 32-bit float, 1 channel

    // initialize the training face matrix - for ease of debugging
    for (int i1 = 0; i1 < nTrainFaces; i1++) {
      for (int j1 = 0; j1 < nEigens; j1++) {
        projectedTrainFaceMat.put(i1, j1, 0.0);
      }
    }

    LOGGER.info(
        "created projectedTrainFaceMat with "
            + nTrainFaces
            + " (nTrainFaces) rows and "
            + nEigens
            + " (nEigens) columns");
    /**
     * nTrainFace should always > 5 !!!!!!!!!!!!!!!! if (nTrainFaces < 5) {
     * LOGGER.info("projectedTrainFaceMat contents:\n" +
     * oneChannelCvMatToString(projectedTrainFaceMat)); }
     */
    final FloatPointer floatPointer = new FloatPointer(nEigens);
    for (int i = 0; i < nTrainFaces; i++) {
      cvEigenDecomposite(
          trainingFaces.get(i), // obj
          nEigens, // nEigObjs
          eigenVectArr, // eigInput (Pointer)
          0, // ioFlags
          null, // userData (Pointer)
          pAvgTrainImg, // avg
          floatPointer); // coeffs (FloatPointer)

      /*nTrainFace should always > 5 !!!!!!!!!!!!!!!!
      if (nTrainFaces < 5) {
        LOGGER.info("floatPointer: " + floatPointerToString(floatPointer));
      }*/
      for (int j1 = 0; j1 < nEigens; j1++) {
        projectedTrainFaceMat.put(i, j1, floatPointer.get(j1));
      }
    }
    /*nTrainFace should always > 5 !!!!!!!!!!!!!!!!
        if (nTrainFaces < 5) {
          LOGGER.info("projectedTrainFaceMat after cvEigenDecomposite:\n" + projectedTrainFaceMat);
        }
    */
    // store the recognition data as an xml file
    //    storeTrainingData();

    // Save all the eigenvectors as images, so that they can be checked.
    //  storeEigenfaceImages();

  }