Показать наложенное изображение, если лицо заблокировано в режиме предварительного просмотра - PullRequest
0 голосов
/ 10 января 2020

Я работаю над проектом, использующим распознавание лиц, и использую MLToolkit, предоставленный Firebase. Используя предоставленный Google codelab код здесь Я успешно интегрировал распознавание лиц. Я сделал еще один шаг и попытался нанести наложенное изображение на определенные ориентиры. Но мое изображение исчезает, когда лицо блокируется. Я хочу знать, есть ли способ, где, даже если лицо пользователя заблокировано, мы все еще можем показать изображение на этих ориентирах?

Ниже приведен мой класс FaceContourGraphi c, где я провел весь свой эксперимент:

 private static final float FACE_POSITION_RADIUS = 4.0f;
    private static final float ID_TEXT_SIZE = 30.0f;
    private static final float ID_Y_OFFSET = 80.0f;
    private static final float ID_X_OFFSET = -70.0f;
    private static final float BOX_STROKE_WIDTH = 5.0f;

    private final Paint facePositionPaint;
    private final Paint idPaint;
    private final Paint boxPaint;
    private Drawable mHatGraphic;
    private Context context;

    private volatile FirebaseVisionFace firebaseVisionFace;
    FirebaseVisionFaceContour contour;
    private float[] leftx = new float[4];
    private float[] rightx = new float[4];
    private float[] lefty = new float[4];
    private float[] righty = new float[4];

    public FaceContourGraphic(GraphicOverlay overlay, FirebaseVisionFace face, Context mContext) {
        super(overlay);

        this.firebaseVisionFace = face;
        final int selectedColor = Color.BLUE;

        facePositionPaint = new Paint();
        facePositionPaint.setColor(selectedColor);

        idPaint = new Paint();
        idPaint.setColor(selectedColor);
        idPaint.setTextSize(ID_TEXT_SIZE);
        this.context = mContext;
        boxPaint = new Paint();
        boxPaint.setColor(selectedColor);
        boxPaint.setStyle(Paint.Style.STROKE);
        boxPaint.setStrokeWidth(BOX_STROKE_WIDTH);
        mHatGraphic = mContext.getResources().getDrawable(R.drawable.flat_tapered_brush);
    }

    /**
     * Draws the face annotations for position on the supplied canvas.
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void draw(Canvas canvas) {
        FirebaseVisionFace face = firebaseVisionFace;
        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.getBoundingBox().centerX());
        float y = translateY(face.getBoundingBox().centerY());
        canvas.drawCircle(x, y, FACE_POSITION_RADIUS, facePositionPaint);
        canvas.drawText("id: " + face.getTrackingId(), x + ID_X_OFFSET, y + ID_Y_OFFSET, idPaint);

        // Draws a bounding box around the face.
        float xOffset = scaleX(face.getBoundingBox().width() / 2.0f);
        float yOffset = scaleY(face.getBoundingBox().height() / 2.0f);
        float left = x - xOffset;
        float top = y - yOffset;
        float right = x + xOffset;
        float bottom = y + yOffset;
        canvas.drawRect(left, top, right, bottom, boxPaint);

        contour = face.getContour(FirebaseVisionFaceContour.ALL_POINTS);


        for (com.google.firebase.ml.vision.common.FirebaseVisionPoint point : contour.getPoints()) {
            float px = translateX(point.getX());
            float py = translateY(point.getY());
            canvas.drawCircle(px, py, FACE_POSITION_RADIUS, facePositionPaint);

            Log.e("points:", point.getX().toString());
        }

        for (int z = 0; z < contour.getPoints().size(); z++) {
            if (z < 36) {
                if (z == 35) {
                    canvas.drawLine(translateX(contour.getPoints().get(z).getX()), translateY(contour.getPoints().get(z).getY()), translateX(contour.getPoints().get(0).getX()), translateY(contour.getPoints().get(0).getY()), idPaint);
                } else {
                    canvas.drawLine(translateX(contour.getPoints().get(z).getX()), translateY(contour.getPoints().get(z).getY()), translateX(contour.getPoints().get(z + 1).getX()), translateY(contour.getPoints().get(z + 1).getY()), idPaint);
                }
            }
        }

        canvas.drawLine(translateX(contour.getPoints().get(33).getX()), translateY(contour.getPoints().get(33).getY()), translateX(contour.getPoints().get(3).getX()), translateY(contour.getPoints().get(3).getY()), idPaint);
        canvas.drawLine(translateX(contour.getPoints().get(12).getX()), translateY(contour.getPoints().get(12).getY()), translateX(contour.getPoints().get(24).getX()), translateY(contour.getPoints().get(24).getY()), idPaint);
        canvas.drawLine(translateX(contour.getPoints().get(10).getX()), translateY(contour.getPoints().get(10).getY()), translateX(contour.getPoints().get(26).getX()), translateY(contour.getPoints().get(26).getY()), idPaint);
        canvas.drawLine(translateX(contour.getPoints().get(18).getX()), translateY(contour.getPoints().get(18).getY()), translateX(contour.getPoints().get(0).getX()), translateY(contour.getPoints().get(0).getY()), idPaint);
        canvas.drawLine(translateX(contour.getPoints().get(15).getX()), translateY(contour.getPoints().get(15).getY()), translateX(contour.getPoints().get(21).getX()), translateY(contour.getPoints().get(21).getY()), idPaint);
        //TODO below line coordinates are for right eyebrow
        //canvas.drawLine(translateX(contour.getPoints().get(36).getX()), translateY(contour.getPoints().get(36).getY()), translateX(contour.getPoints().get(40).getX()), translateY(contour.getPoints().get(40).getY()), idPaint);
        canvas.drawLine(translateX(contour.getPoints().get(46).getX()), translateY(contour.getPoints().get(46).getY()), translateX(contour.getPoints().get(50).getX()), translateY(contour.getPoints().get(50).getY()), idPaint);
        canvas.drawLine(translateX(contour.getPoints().get(38).getX()), translateY(contour.getPoints().get(38).getY()), translateX(contour.getPoints().get(43).getX()), translateY(contour.getPoints().get(43).getY()), idPaint);

        // draw line for  cheek

        canvas.drawLine(translateX(contour.getPoints().get(56).getX()), translateY(contour.getPoints().get(56).getY()), translateX(contour.getPoints().get(64).getX()), translateY(contour.getPoints().get(64).getY()), idPaint);

        canvas.drawLine(translateX(contour.getPoints().get(72).getX()), translateY(contour.getPoints().get(72).getY()), translateX(contour.getPoints().get(80).getX()), translateY(contour.getPoints().get(80).getY()), idPaint);

        // line from nose to end of eye

        canvas.drawLine(translateX(contour.getPoints().get(56).getX()), translateY(contour.getPoints().get(56).getY()), translateX(contour.getPoints().get(128).getX()), translateY(contour.getPoints().get(128).getY()), idPaint);
        canvas.drawLine(translateX(contour.getPoints().get(80).getX()), translateY(contour.getPoints().get(80).getY()), translateX(contour.getPoints().get(130).getX()), translateY(contour.getPoints().get(130).getY()), idPaint);

        // draw line from face to nose base left and right
        canvas.drawLine(translateX(contour.getPoints().get(130).getX()), translateY(contour.getPoints().get(130).getY()), translateX(contour.getPoints().get(7).getX()), translateY(contour.getPoints().get(7).getY()), idPaint);
        canvas.drawLine(translateX(contour.getPoints().get(128).getX()), translateY(contour.getPoints().get(128).getY()), translateX(contour.getPoints().get(29).getX()), translateY(contour.getPoints().get(29).getY()), idPaint);

// eyebrow coordinates


        // Text Displayed
        float jaw_width = ((contour.getPoints().get(12).getX() / 2.0f) - (contour.getPoints().get(24).getX() / 2.0f));
        float cheek_width = ((contour.getPoints().get(10).getX() / 2.0f) - (contour.getPoints().get(26).getX() / 2.0f));
        float forehead_width = ((contour.getPoints().get(3).getX() / 2.0f) - (contour.getPoints().get(33).getX() / 2.0f));
        float face_height = ((contour.getPoints().get(18).getY() / 2.0f) - (contour.getPoints().get(0).getY() / 2.0f));
        float chin_width = ((contour.getPoints().get(15).getX() / 2.0f) - (contour.getPoints().get(21).getX() / 2.0f));
        float left_eyebrow_width = ((contour.getPoints().get(36).getX() / 2.0f) - (contour.getPoints().get(40).getX() / 2.0f));
        float right_nose_to_cheek_width = ((contour.getPoints().get(128).getX() / 2.0f) - (contour.getPoints().get(26).getX() / 2.0f));


        canvas.drawText("Jaw Width = " + jaw_width, 0, 500, idPaint);
        canvas.drawText("Cheek Width = " + cheek_width, 0, 200, idPaint);
        canvas.drawText("Forehead Width = " + forehead_width, 0, 250, idPaint);

        canvas.drawText("Face Height = " + face_height, 0, 150, idPaint);
        canvas.drawText("chin width = " + chin_width, 0, 400, idPaint);

        calculateWidestPart(canvas, jaw_width, cheek_width, forehead_width, face_height);
        calculateFaceLength(canvas, jaw_width, cheek_width, forehead_width, face_height, chin_width);

        calculateRightEyebrowCoordinates(canvas);
        calculateLeftEyebrowCoordinates(canvas);
        calculateLeftCheekCoordinates(canvas);
        calculateRightCheekCoordinates(canvas, right_nose_to_cheek_width);

    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void calculateRightCheekCoordinates(Canvas canvas, float right_nose_to_cheek_width) {
        PointF cheekPositionRight = new PointF(translateX(contour.getPoints().get(128).getX()),
                translateY(contour.getPoints().get(128).getY()));

        PointF cheekPositionTop = new PointF(translateX(contour.getPoints().get(29).getX()),
                translateY(contour.getPoints().get(29).getY()));
        drawEyebrow(canvas, cheekPositionRight, cheekPositionTop, R.drawable.right_cheek);
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void calculateLeftCheekCoordinates(Canvas canvas) {
        PointF cheekPositionLeft = new PointF(translateX(contour.getPoints().get(7).getX()),
                translateY(contour.getPoints().get(7).getY()));

        PointF cheekPositionTop = new PointF(translateX(contour.getPoints().get(7).getX()),
                translateY(contour.getPoints().get(7).getY()));
        drawEyebrow(canvas, cheekPositionLeft, cheekPositionTop, R.drawable.left_cheek);
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void calculateLeftEyebrowCoordinates(Canvas canvas) {
        PointF eyebrowPositionRight = new PointF(translateX(contour.getPoints().get(46).getX()),
                translateY(contour.getPoints().get(46).getY()));

        PointF eyebrowPositionTop = new PointF(translateX(contour.getPoints().get(48).getX()),
                translateY(contour.getPoints().get(48).getY()));
        drawEyebrow(canvas, eyebrowPositionRight, eyebrowPositionTop, R.drawable.lefteyebrow);
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void calculateRightEyebrowCoordinates(Canvas canvas) {
        PointF eyebrowPositionLeft = new PointF(translateX(contour.getPoints().get(36).getX()),
                translateY(contour.getPoints().get(36).getY()));

        PointF eyebrowPositionRight = new PointF(translateX(contour.getPoints().get(40).getX()),
                translateY(contour.getPoints().get(40).getY()));

        PointF eyebrowPositionTop = new PointF(translateX(contour.getPoints().get(38).getX()),
                translateY(contour.getPoints().get(38).getY()));

        PointF eyebrowPositionBottom = new PointF(translateX(contour.getPoints().get(43).getX()),
                translateY(contour.getPoints().get(43).getY()));
        drawEyebrow(canvas, eyebrowPositionRight, eyebrowPositionTop, R.drawable.eyebrows);
    }

    private void calculateFaceLength(Canvas canvas, float jaw_width, float cheek_width, float forehead_width, float face_height, float chin_width) {
        face_height = Math.round(face_height);
        cheek_width = Math.round(cheek_width);
        forehead_width = Math.round(forehead_width);
        jaw_width = Math.round(jaw_width);
        int jaw_forehead_difference = (int) Math.abs((jaw_width - forehead_width));
        int cheek_jaw_difference = (int) Math.abs((cheek_width - jaw_width));
        int cheek_forehead_difference = (int) Math.abs((cheek_width - forehead_width));
        if (face_height >= cheek_width && jaw_forehead_difference <= 10) {
            canvas.drawText("Face Shape = Round" + " ", 0, 450, idPaint);
        } else if (face_height > cheek_width && cheek_jaw_difference > 10) {
            canvas.drawText("Face Shape = Oval " + " ", 0, 450, idPaint);
        } else if (cheek_jaw_difference <= 5 && cheek_forehead_difference <= 5) {
            canvas.drawText("Face Shape = Square" + " ", 0, 450, idPaint);
        } else if (face_height > cheek_width && forehead_width > jaw_width && chin_width < 30) {
            canvas.drawText("Face Shape = Diamond" + " ", 0, 450, idPaint);
        }
    }

    private void calculateWidestPart(Canvas canvas, float jaw_width, float cheek_width, float forehead_width, float face_height) {
        if (forehead_width > jaw_width && forehead_width > cheek_width) {
            canvas.drawText("widest part = Forehead " + " ", 0, 300, idPaint);
        } else if (jaw_width > forehead_width && jaw_width > cheek_width) {
            canvas.drawText("widest part = Jaw" + " ", 0, 300, idPaint);
        } else {
            canvas.drawText("widest part = Cheek" + " ", 0, 300, idPaint);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void drawEyebrow(Canvas canvas,
                             PointF rightEyebrow, PointF topEyebrow, int eyebrows) {
        //int right = (int)leftEyebrow.x;
        int left = (int) rightEyebrow.x;
        int top = (int) topEyebrow.y;
        //int bottom = (int)bottomEyebrow.y;
        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), eyebrows);
        //if you are in non activity then use context.getResources()
        canvas.drawBitmap(bitmap, left, top, facePositionPaint);
    }
}
...