2013-03-19 61 views
2

我的Java應用程序中有一個不同線程的JPG圖像的實時流,我想不斷掃描面以輸出所有不同面的列表運行過程中的照相機以及每張臉被看到的次數。這裏是我當前的代碼:如何使用OpenIMAJ識別新面孔

void doImageProcessing() { 

    // Create face stuff 
    FKEFaceDetector faceDetector = new FKEFaceDetector(new HaarCascadeDetector()); 
    EigenFaceRecogniser<KEDetectedFace, Person> faceRecognizer = EigenFaceRecogniser.create(512, new RotateScaleAligner(), 512, DoubleFVComparison.CORRELATION, Float.MAX_VALUE); 
    FaceRecognitionEngine<KEDetectedFace, Extractor<KEDetectedFace>, Person> faceEngine = FaceRecognitionEngine.create(faceDetector, faceRecognizer); 

    // Start loop 
    while (true) { 

     // Get next frame 
     byte[] imgData = nextProcessingData; 
     nextProcessingData = null; 

     // Decode image 
     BufferedImage img = ImageIO.read(new ByteArrayInputStream(imgData)); 

     // Detect faces 
     FImage fimg = ImageUtilities.createFImage(img); 
     List<KEDetectedFace> faces = faceEngine.getDetector().detectFaces(fimg); 

     // Go through detected faces 
     for (KEDetectedFace face : faces) { 

      // Find existing person for this face 
      Person person = null; 
      try { 

       List<IndependentPair<KEDetectedFace, ScoredAnnotation<Person>>> rfaces = faceEngine.recogniseBest(face.getFacePatch()); 
       ScoredAnnotation<Person> score = rfaces.get(0).getSecondObject(); 
       if (score != null) 
        person = score.annotation; 

      } catch (Exception e) { 
      } 

      // If not found, create 
      if (person == null) { 

       // Create person 
       person = new Person(); 
       System.out.println("Identified new person: " + person.getIdentifier()); 

       // Train engine to recognize this new person 
       faceEngine.train(person, face.getFacePatch()); 

      } else { 

       // This person has been detected before 
       System.out.println("Identified existing person: " + person.getIdentifier()); 

      } 

     } 

    } 

} 

問題是,它總是檢測到人臉如新,即使是在一幀檢測到的同一張臉。 rfaces始終爲空。它永遠不能識別現有的臉。我究竟做錯了什麼?

另外,我不知道該EigenFaceRecognizer創造者函數的參數應該是什麼,也許這就是爲什麼它不承認什麼...

回答

4

你給到EigenFaceRecogniser.create()函數的參數是這樣了,所以這可能是你的問題的可能原因。以下是更可能的工作:

EigenFaceRecogniser<KEDetectedFace, Person> faceRecognizer = EigenFaceRecogniser.create(20, new RotateScaleAligner(), 1, DoubleFVComparison.CORRELATION, 0.9f); 

闡釋:

  • 第一個參數是在本徵臉算法主分量的數目;確切的數值通常是通過實驗確定的,但約20左右的數值可能沒有問題。

  • 第三個參數是用於KNN分類器的最近鄰居的數量。 1個最近鄰居應該沒問題。

  • 最終參數是分類器的距離閾值。相關性比較返回相似性度量(高值意味着更相似),因此給定的閾值是必須超過的下限。由於我們設置了1個最近鄰居,因此最相似的人臉與查詢人臉之間的距離必須大於0.9。 請注意,0.9的值只是一個猜測;爲了優化識別器的性能,您需要充分利用這一點。

另一個小點 - 而不是:

BufferedImage img = ImageIO.read(new ByteArrayInputStream(imgData)); 
    FImage fimg = ImageUtilities.createFImage(img); 

這是一般更好地讓OpenIMAJ讀你的形象,它的工作原理圍繞着一些已知問題與ImageIO在處理某些類型的JPEG的:

FImage fimg = ImageUtilities.readF(new ByteArrayInputStream(imgData)); 
+1

感謝您的解釋,它比我能找到的任何其他方式都好... – jjv360 2013-03-21 22:39:01