2013-03-19 90 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