2

我正在使用视觉 API 进行人脸检测,现在我想实现眨眼,但视觉 api 在一只眼睛关闭时仍能检测到眼睛。

请帮助我如何实现眨眼功能。

4

3 回答 3

7

面部的“睁眼概率”值是检测眨眼的关键。此外,您可以使用 Tracker 随时间跟踪眼睛状态,以检测指示眨眼的事件序列:

双眼睁开->双眼闭合->双眼睁开

这是一个示例跟踪器:

public class BlinkTracker extends Tracker<Face> {
  private final float OPEN_THRESHOLD = 0.85;
  private final float CLOSE_THRESHOLD = 0.15;

  private int state = 0;

  public void onUpdate(Detector.Detections<Face> detections, Face face) {
    float left = face.getIsLeftEyeOpenProbability();
    float right = face.getIsRightEyeOpenProbability();
    if ((left == Face.UNCOMPUTED_PROBABILITY) ||
        (right == Face.UNCOMPUTED_PROBABILITY)) {
      // At least one of the eyes was not detected.
      return;
    }

    switch (state) {
      case 0:
        if ((left > OPEN_THRESHOLD) && (right > OPEN_THRESHOLD)) {
          // Both eyes are initially open
          state = 1;
        }
        break;

        case 1:
          if ((left < CLOSE_THRESHOLD) && (right < CLOSE_THRESHOLD)) {
            // Both eyes become closed
            state = 2;
          }
          break;

        case 2:
          if ((left > OPEN_THRESHOLD) && (right > OPEN_THRESHOLD)) {
            // Both eyes are open again
            Log.i("BlinkTracker", "blink occurred!");
            state = 0;
          }
        break;
    }
  }

}

请注意,您还需要启用“分类”以使检测器指示眼睛是否睁开/闭合:

FaceDetector detector = new FaceDetector.Builder(context)
    .setClassificationType(FaceDetector.ALL_CLASSIFICATIONS)
    .build();

然后添加跟踪器作为处理器,用于从检测器接收随时间推移的面部更新。例如,此配置将用于跟踪视野中最大的人脸是否眨眼:

detector.setProcessor(
    new LargestFaceFocusingProcessor(detector, new BlinkTracker()));

或者,如果您有兴趣检测所有面部(而不仅仅是最大的面部)的眨眼,则可以使用 MultiProcessor 而不是 LargestFaceFocusingProcessor。

于 2016-01-05T16:13:46.600 回答
1

此答案假定您已经拥有检测正在运行的面部的代码。

该类Face具有float getIsLeftEyeOpenProbability()float getIsRightEyeOpenProbability(),您可以在每一帧上使用它们来查找一只眼睛是否眨眼,如果一个函数返回较大的值,另一个返回较小的值。

该类的官方文档Face可以在这里找到

于 2016-01-04T07:41:49.420 回答
0

是我使用 FaceDetectorAPi() 对眼睛检测器应用程序的实现,其在测试时的准确度超过 90%

private double leftEyeOpenProbability = -1.0;
private double rightEyeOpenProbability = -1.0;

private boolean isEyeBlinked(){

    if(mFaces.size()==0)
        return false;

    Face face = mFaces.valueAt(0);
    float currentLeftEyeOpenProbability = face.getIsLeftEyeOpenProbability();
    float currentRightEyeOpenProbability = face.getIsRightEyeOpenProbability();
    if(currentLeftEyeOpenProbability== -1.0 || currentRightEyeOpenProbability == -1.0){
        return false;
    }

    if(leftEyeOpenProbability>0.9 || rightEyeOpenProbability > 0.9){
        boolean blinked = false;
        if(currentLeftEyeOpenProbability<0.6 || rightEyeOpenProbability< 0.6){
            blinked = true;
        }
        leftEyeOpenProbability = currentLeftEyeOpenProbability;
        rightEyeOpenProbability = currentRightEyeOpenProbability;
        return blinked;
    }else{
        leftEyeOpenProbability = currentLeftEyeOpenProbability;
        rightEyeOpenProbability = currentRightEyeOpenProbability;
        return false;
    }
}
于 2018-01-23T00:58:17.340 回答