private IplImage[] loadFaceImgArray(String filename) { IplImage[] faceImgArr; BufferedReader imgListFile; String imgFilename; int iFace = 0; int nFaces = 0; int i; try { imgListFile = new BufferedReader(new FileReader(filename)); while (true) { final String line = imgListFile.readLine(); if (line == null || line.isEmpty()) break; nFaces++; } System.out.println("loadingImgArray-> liczba plikow: " + nFaces); imgListFile = new BufferedReader(new FileReader(filename)); faceImgArr = new IplImage[nFaces]; personNumTruthMat = cvCreateMat( 1, // rows nFaces, // cols CV_32SC1 // type 32 bit unsigned 1 ch ); // initialize for debugging for (int j1 = 0; j1 < nFaces; j1++) { personNumTruthMat.put(0, j1, 0); } personNames.clear(); nPersons = 0; for (iFace = 0; iFace < nFaces; iFace++) { String personName; String sPersonName; int personNumber; // reading person number final String line = imgListFile.readLine(); if (line.isEmpty()) { break; } final String[] tokens = line.split(" "); personNumber = Integer.parseInt(tokens[0]); personName = tokens[1]; imgFilename = tokens[2]; sPersonName = personName; System.out.println( "Got: " + iFace + " " + personNumber + " " + personName + " " + imgFilename); // check if a new person is beaing loaded if (personNumber > nPersons) { // allocate memory personNames.add(sPersonName); nPersons = personNumber; System.out.println( "Added new person" + sPersonName + " ->nPersons = " + nPersons + " [" + personNames.size() + "] "); } // keep the data personNumTruthMat.put( 0, // i iFace, // j personNumber); // v // load the face img faceImgArr[iFace] = cvLoadImage( imgFilename, // filename CV_LOAD_IMAGE_GRAYSCALE // is color ); if (faceImgArr[iFace] == null) { throw new RuntimeException("Can't load image from " + imgFilename); } } imgListFile.close(); } catch (IOException ex) { throw new RuntimeException(ex); } System.out.println( "Data loaded from" + filename + "': (" + nFaces + " images of " + nPersons + " people)."); return faceImgArr; }
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(); }