// 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."); }
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(); }