2

i'm using the vision API for face detection, now i want to implement eye blink but still vision api detect eye while one eye is off.

please help me how to implement eye blink feature.

Sangha_development
  • 253
  • 1
  • 4
  • 9

3 Answers3

8

The "eye open probability" values from the face are the key to detecting the blink. In addition, you can use a Tracker to keep track of the eye state over time, to detect the sequence of events that indicate a blink:

both eyes open -> both eyes closed -> both eyes open

Here's an example 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;
    }
  }

}

Note that you need to also enable "classifications" in order to have the detector indicate if eyes are open/closed:

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

The tracker is then added as a processor for receiving face updates over time from the detector. For example, this configuration would be used to track whether the largest face in view has blinked:

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

Alternatively, you could use a MultiProcessor instead of LargestFaceFocusingProcessor if you are interested in detecting blinks for all faces (not just the largest face).

pm0733464
  • 2,862
  • 14
  • 16
1

This answer assumes that you already have the code to detect the face(s) running.

The Face class has function float getIsLeftEyeOpenProbability() and float getIsRightEyeOpenProbability(), You can use them on every frame to find whether one of the eyes was blinked, if one of the function returns a large value and the other returns a smaller value.

Official documentation of the Face class can be found here

Sssssuppp
  • 683
  • 1
  • 7
  • 29
Shiva
  • 6,677
  • 4
  • 36
  • 61
  • hello shiva... is it the right way to detect blink ? – Sangha_development Jan 04 '16 at 10:55
  • @Sangha_development: Ideally this should be good enough way, as the API's provided in the android-vision library there is no dedicated function to detect blink.So your implementation should be able to handle all the edge cases like When the value was not EyeOpenProbility was not detected it would default it to zero etc. – Shiva Jan 04 '16 at 11:26
0

here is my implentation fo eye detector application using FaceDetectorAPi() whose accuracy is more than 90% when tested

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;
    }
}
murali kurapati
  • 1,510
  • 18
  • 23
  • hey murali, your condition does not work if user keep open an eye and close another. But if you change `||` to `&&` `if(leftEyeOpenProbability>0.9 && rightEyeOpenProbability > 0.9){` , it will be fine. – Rurouni Aug 14 '18 at 06:00
  • Hi, Can I use eyeopenprobablity function from web application?does cloud vision api support this? – mrtechmaker Apr 11 '19 at 02:20
  • Can I use this from web application? – mrtechmaker Apr 11 '19 at 02:22
  • 1
    @KaranAhuja no because this is a Android library, there might a corresponding cloud api, but it wont be in real time because of network latency – murali kurapati Apr 11 '19 at 03:55