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 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); } } } }
/** * 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); } }
FaceDetector detector = new FaceDetector.Builder(context) .setLandmarkType(FaceDetector.ALL_LANDMARKS) .setClassificationType(FaceDetector.ALL_CLASSIFICATIONS) .setTrackingEnabled(true) .setMode(FaceDetector.FAST_MODE) .setProminentFaceOnly(mIsFrontFacing) .setMinFaceSize(mIsFrontFacing ? 0.35f : 0.15f) .build(); processor = new LargestFaceFocusingProcessor.Builder(detector, tracker).build(); } else { detector.setProcessor(processor); if (!detector.isOperational()) {
public void setBitmap( Bitmap bitmap ) { mBitmap = bitmap; FaceDetector detector = new FaceDetector.Builder( getContext() ) .setTrackingEnabled(true) .setLandmarkType(FaceDetector.ALL_LANDMARKS) .setMode(FaceDetector.ACCURATE_MODE) .build(); if (!detector.isOperational()) { //Handle contingency } else { Frame frame = new Frame.Builder().setBitmap(bitmap).build(); mFaces = detector.detect(frame); detector.release(); } logFaceData(); invalidate(); }
/** * Creates and starts the camera. Note that this uses a higher resolution in comparison * to other detection examples to enable the barcode detector to detect small barcodes * at long distances. */ private void createCameraSource() { Context context = getApplicationContext(); FaceDetector detector = new FaceDetector.Builder(context) .setClassificationType(FaceDetector.ALL_CLASSIFICATIONS) .build(); detector.setProcessor( new MultiProcessor.Builder<>(new GraphicFaceTrackerFactory()) .build()); if (!detector.isOperational()) { // Note: The first time that an app using face API is installed on a device, GMS will // download a native library to the device in order to do detection. Usually this // completes before the app is run for the first time. But if that download has not yet // completed, then the above call will not detect any faces. // // isOperational() can be used to check if the required native library is currently // available. The detector will automatically become operational once the library // download completes on device. Log.w(TAG, "Face detector dependencies are not yet available."); } mCameraSource = new CameraSource.Builder(context, detector) .setRequestedPreviewSize(640, 480) .setFacing(CameraSource.CAMERA_FACING_BACK) .setRequestedFps(30.0f) .build(); }
private static void initDetector() { if (faceDetector == null) { synchronized (PicassoFaceDetector.class) { if (faceDetector == null) { faceDetector = new FaceDetector.Builder(getContext()) .setTrackingEnabled(false) .build(); } } } }
/** * 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); } }
FaceDetector detector = new FaceDetector.Builder(getApplicationContext()) .setTrackingEnabled(false) .setLandmarkType(FaceDetector.ALL_LANDMARKS) .build();
FaceDetector faceDetector = new FaceDetector.Builder(context).build(); FaceTrackerFactory faceFactory = new FaceTrackerFactory(mGraphicOverlay); faceDetector.setProcessor( new MultiProcessor.Builder<>(faceFactory).build());
/** * 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); }
/** * Release the detector when you no longer need it. * Remember to call PicassoFaceDetector.initialize(context) if you have to re-use. */ public static void releaseDetector() { if (faceDetector != null) { faceDetector.release(); faceDetector = null; } mContext = null; } }
/** * 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); } }
private static void initDetector() { if (faceDetector == null) { synchronized ((GlideFaceDetector.class)) { if (faceDetector == null) { faceDetector = new FaceDetector.Builder(getContext()) .setTrackingEnabled(false) .build(); } } } }
/** * 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 }
public static void releaseDetector() { if (faceDetector != null) { faceDetector.release(); faceDetector = null; } mContext = null; } }
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 }
/** * Stop eye tracking. */ void stopEyeTracker() { isTrackingRunning = false; if (mDetector != null) mDetector.release(); if (mPreview != null) mPreview.release(); }
@Override protected void onDestroy() { super.onDestroy(); stopCameraSource(); if(previewFaceDetector != null) { previewFaceDetector.release(); } } }