/** * Draws the face annotations for position on the supplied canvas. */ @Override public void draw(Canvas canvas) { Face face = mFace; if (face == null) { return; } // Draws a circle at the position of the detected face, with the face's track id below. float x = translateX(face.getPosition().x + face.getWidth() / 2); float y = translateY(face.getPosition().y + face.getHeight() / 2); canvas.drawCircle(x, y, FACE_POSITION_RADIUS, mFacePositionPaint); canvas.drawText("id: " + mFaceId, x + ID_X_OFFSET, y + ID_Y_OFFSET, mIdPaint); canvas.drawText("happiness: " + String.format("%.2f", face.getIsSmilingProbability()), x - ID_X_OFFSET, y - ID_Y_OFFSET, mIdPaint); canvas.drawText("right eye: " + String.format("%.2f", face.getIsRightEyeOpenProbability()), x + ID_X_OFFSET * 2, y + ID_Y_OFFSET * 2, mIdPaint); canvas.drawText("left eye: " + String.format("%.2f", face.getIsLeftEyeOpenProbability()), x - ID_X_OFFSET*2, y - ID_Y_OFFSET*2, mIdPaint); // Draws a bounding box around the face. float xOffset = scaleX(face.getWidth() / 2.0f); float yOffset = scaleY(face.getHeight() / 2.0f); float left = x - xOffset; float top = y - yOffset; float right = x + xOffset; float bottom = y + yOffset; canvas.drawRect(left, top, right, bottom, mBoxPaint); } }
private void updatePreviousProportions(Face face) { for (Landmark landmark : face.getLandmarks()) { PointF position = landmark.getPosition(); float xProp = (position.x - face.getPosition().x) / face.getWidth(); float yProp = (position.y - face.getPosition().y) / face.getHeight(); mPreviousProportions.put(landmark.getType(), new PointF(xProp, yProp)); } }
/** * Draws the face annotations for position, size, and ID on the supplied canvas. */ @Override public void draw(Canvas canvas) { Face face = mFace; if (face == null) { return; } // Draws a circle at the position of the detected face, with the face's track id below. float cx = translateX(face.getPosition().x + face.getWidth() / 2); float cy = translateY(face.getPosition().y + face.getHeight() / 2); canvas.drawCircle(cx, cy, FACE_POSITION_RADIUS, mFacePositionPaint); canvas.drawText("id: " + getId(), cx + ID_X_OFFSET, cy + ID_Y_OFFSET, mIdPaint); // Draws an oval around the face. float xOffset = scaleX(face.getWidth() / 2.0f); float yOffset = scaleY(face.getHeight() / 2.0f); float left = cx - xOffset; float top = cy - yOffset; float right = cx + xOffset; float bottom = cy + yOffset; canvas.drawOval(left, top, right, bottom, mBoxPaint); } }
facePosition = new PointF(translateX(face.getPosition().x), translateY(face.getPosition().y)); faceWidth = face.getWidth() * 4; faceHeight = face.getHeight() * 4; faceCenter = new PointF(translateX(face.getPosition().x + faceWidth/8), translateY(face.getPosition().y + faceHeight/8)); isSmilingProbability = face.getIsSmilingProbability(); eyeRightOpenProbability = face.getIsRightEyeOpenProbability(); eyeLeftOpenProbability = face.getIsLeftEyeOpenProbability(); eulerY = face.getEulerY(); eulerZ = face.getEulerZ(); for(Landmark landmark : face.getLandmarks()) { switch (landmark.getType()) { case Landmark.LEFT_EYE:
/** * Updates the positions and state of eyes to the underlying graphic, according to the most * recent face detection results. The graphic will render the eyes and simulate the motion of * the iris based upon these changes over time. */ @Override public void onUpdate(FaceDetector.Detections<Face> detectionResults, Face face) { mOverlay.add(mEyesGraphic); updatePreviousProportions(face); PointF leftPosition = getLandmarkPosition(face, Landmark.LEFT_EYE); PointF rightPosition = getLandmarkPosition(face, Landmark.RIGHT_EYE); float leftOpenScore = face.getIsLeftEyeOpenProbability(); boolean isLeftOpen; if (leftOpenScore == Face.UNCOMPUTED_PROBABILITY) { isLeftOpen = mPreviousIsLeftOpen; } else { isLeftOpen = (leftOpenScore > EYE_CLOSED_THRESHOLD); mPreviousIsLeftOpen = isLeftOpen; } float rightOpenScore = face.getIsRightEyeOpenProbability(); boolean isRightOpen; if (rightOpenScore == Face.UNCOMPUTED_PROBABILITY) { isRightOpen = mPreviousIsRightOpen; } else { isRightOpen = (rightOpenScore > EYE_CLOSED_THRESHOLD); mPreviousIsRightOpen = isRightOpen; } mEyesGraphic.updateEyes(leftPosition, isLeftOpen, rightPosition, isRightOpen); }
private void logFaceData() { float smilingProbability; float leftEyeOpenProbability; float rightEyeOpenProbability; float eulerY; float eulerZ; for( int i = 0; i < mFaces.size(); i++ ) { Face face = mFaces.valueAt(i); smilingProbability = face.getIsSmilingProbability(); leftEyeOpenProbability = face.getIsLeftEyeOpenProbability(); rightEyeOpenProbability = face.getIsRightEyeOpenProbability(); eulerY = face.getEulerY(); eulerZ = face.getEulerZ(); Log.e( "Tuts+ Face Detection", "Smiling: " + smilingProbability ); Log.e( "Tuts+ Face Detection", "Left eye open: " + leftEyeOpenProbability ); Log.e( "Tuts+ Face Detection", "Right eye open: " + rightEyeOpenProbability ); Log.e( "Tuts+ Face Detection", "Euler Y: " + eulerY ); Log.e( "Tuts+ Face Detection", "Euler Z: " + eulerZ ); } } }
/** * Updates the face instance from the detection of the most recent frame. Invalidates the * relevant portions of the overlay to trigger a redraw. */ void updateFace(Face face) { mFace = face; op = Bitmap.createScaledBitmap(bitmap, (int) scaleX(face.getWidth()), (int) scaleY(((bitmap.getHeight() * face.getWidth()) / bitmap.getWidth())), false); postInvalidate(); }
/** * Draws a small circle for each detected landmark, centered at the detected landmark position. * <p> * * Note that eye landmarks are defined to be the midpoint between the detected eye corner * positions, which tends to place the eye landmarks at the lower eyelid rather than at the * pupil position. */ private void drawFaceAnnotations(Canvas canvas, double scale) { Paint paint = new Paint(); paint.setColor(Color.GREEN); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5); for (int i = 0; i < mFaces.size(); ++i) { Face face = mFaces.valueAt(i); for (Landmark landmark : face.getLandmarks()) { int cx = (int) (landmark.getPosition().x * scale); int cy = (int) (landmark.getPosition().y * scale); canvas.drawCircle(cx, cy, 10, paint); } } } }
/** * Calculates center of a given face * * @param face Face * @param center Center of the face */ private void getFaceCenter(Face face, PointF center) { float x = face.getPosition().x; float y = face.getPosition().y; float width = face.getWidth(); float height = face.getHeight(); center.set(x + (width / 2), y + (height / 2)); // face center in original bitmap }
/** * Update the position/characteristics of the face within the overlay. */ @Override public void onUpdate(FaceDetector.Detections<Face> detectionResults, Face face) { Log.d(getClass().getSimpleName(), "onUpdate" + face.getIsLeftEyeOpenProbability()); if (face.getIsLeftEyeOpenProbability() > 0.10 && face.getIsRightEyeOpenProbability() > 0.10) { isEyesClosedCount = 0; mWakelockManager.acquireWakelock(); } else { isEyesClosedCount++; if (isEyesClosedCount > 2) mWakelockManager.releaseWakelock(); } }
private void drawFaceLandmarks( Canvas canvas, double scale ) { Paint paint = new Paint(); paint.setColor( Color.GREEN ); paint.setStyle( Paint.Style.STROKE ); paint.setStrokeWidth( 5 ); for( int i = 0; i < mFaces.size(); i++ ) { Face face = mFaces.valueAt(i); for ( Landmark landmark : face.getLandmarks() ) { int cx = (int) ( landmark.getPosition().x * scale ); int cy = (int) ( landmark.getPosition().y * scale ); canvas.drawCircle( cx, cy, 10, paint ); } } }
/** * Calculates center of a given face * * @param face Face * @param center Center of the face */ private void getFaceCenter(Face face, PointF center) { float x = face.getPosition().x; float y = face.getPosition().y; float width = face.getWidth(); float height = face.getHeight(); center.set(x + (width / 2), y + (height / 2)); // face center in original bitmap }
/** * Finds a specific landmark position, or approximates the position based on past observations * if it is not present. */ private PointF getLandmarkPosition(Face face, int landmarkId) { for (Landmark landmark : face.getLandmarks()) { if (landmark.getType() == landmarkId) { return landmark.getPosition(); } } PointF prop = mPreviousProportions.get(landmarkId); if (prop == null) { return null; } float x = face.getPosition().x + (prop.x * face.getWidth()); float y = face.getPosition().y + (prop.y * face.getHeight()); return new PointF(x, y); } }
/** * When new frame analysed. */ @Override public void onUpdate(FaceDetector.Detections<Face> detectionResults, Face face) { Log.d("FaceTracker", "onUpdate" + face.getIsLeftEyeOpenProbability()); //if left and right eyes are open. (Probability more than 10%) if (face.getIsLeftEyeOpenProbability() > 0.10 && face.getIsRightEyeOpenProbability() > 0.10) { isEyesClosedCount = 0; mUserAwareVideoView.onUserAttentionAvailable(); } else { isEyesClosedCount++; if (isEyesClosedCount > 2) mUserAwareVideoView.onUserAttentionGone(); } }
private void drawFaceBox(Canvas canvas, double scale) { //This should be defined as a member variable rather than //being created on each onDraw request, but left here for //emphasis. Paint paint = new Paint(); paint.setColor(Color.GREEN); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5); float left = 0; float top = 0; float right = 0; float bottom = 0; for( int i = 0; i < mFaces.size(); i++ ) { Face face = mFaces.valueAt(i); left = (float) ( face.getPosition().x * scale ); top = (float) ( face.getPosition().y * scale ); right = (float) scale * ( face.getPosition().x + face.getWidth() ); bottom = (float) scale * ( face.getPosition().y + face.getHeight() ); canvas.drawRect( left, top, right, bottom, paint ); } }
/** * Draws the face annotations for position on the supplied canvas. */ @Override public void draw(Canvas canvas) { Face face = mFace; if (face == null) { return; } // Draws a circle at the position of the detected face, with the face's track id below. float x = translateX(face.getPosition().x + face.getWidth() / 2); float y = translateY(face.getPosition().y + face.getHeight() / 2); float xOffset = scaleX(face.getWidth() / 2.0f); float yOffset = scaleY(face.getHeight() / 2.0f); float left = x - xOffset; float top = y - yOffset; float right = x + xOffset; float bottom = y + yOffset; canvas.drawRect(left, top, right, bottom, mBoxPaint); canvas.drawBitmap(op, left, top, new Paint()); }