Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
191 views
in Technique[技术] by (71.8m points)

Android: Draw Landmarks on face using Google Vision API

I have the current code which draw a bounding box around a user's face on a live camera preview.

I am also trying to draw the position of facial landmarks on the live camera preview. It draws them but not at the right location due to not having the scale value

I found this code online but am struggling to compute this scale value as it is a live camera preview and not a bitmap image

Example code found online

 double scale = Math.min( viewWidth / imageWidth, viewHeight / imageHeight );

 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);
    }

My Function

@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);
      


       // 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);

       Paint paint = new Paint();
       paint.setColor( Color.GREEN );
       paint.setStyle( Paint.Style.STROKE );
       paint.setStrokeWidth( 5 );

       for ( Landmark landmark : face.getLandmarks() ) {
           int cx = (int) ( landmark.getPosition().x);
           int cy = (int) ( landmark.getPosition().y);
           canvas.drawCircle( cx, cy, 10, paint );
       }

       }
question from:https://stackoverflow.com/questions/65938013/android-draw-landmarks-on-face-using-google-vision-api

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Solved via the following, but not wholly accurate

 if ((contains(face.getLandmarks(), 11) != 99)
                && (contains(face.getLandmarks(), 5) != 99)
                && (contains(face.getLandmarks(), 6) != 99)
        ) {

            Log.i(TAG, "draw: Mouth Open >> found all the points");

            /**
             * for bottom mouth
             */
            int cBottomMouthX;
            int cBottomMouthY;

                cBottomMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 0)).getPosition().x);
                cBottomMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 0)).getPosition().y);

                Log.i(TAG, "draw: Condition Bottom mouth >> cBottomMouthX >> " + cBottomMouthX + "    cBottomMouthY >> " + cBottomMouthY);

            canvas.drawCircle(cBottomMouthX, cBottomMouthY, 10, paint);

            /**
             * for left mouth
             */
            int cLeftMouthX;
            int cLeftMouthY;

                cLeftMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 5)).getPosition().x);
                cLeftMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 5)).getPosition().y);

                Log.i(TAG, "draw: Condition LEft mouth >> cLeftMouthX >> " + cLeftMouthX + "    cLeftMouthY >> " + cLeftMouthY);
                cLeftMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 5)).getPosition().x);
                cLeftMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 5)).getPosition().y);
            canvas.drawCircle(cLeftMouthX, cLeftMouthY, 10, paint);

            /**
             * for Right mouth
             */
            int cRightMouthX;
            int cRightMouthY;

                cRightMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 11)).getPosition().x);
                cRightMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 11)).getPosition().y);

                Log.i(TAG, "draw: Condition Right mouth >> cRightMouthX >> " + cRightMouthX + "    cRightMouthY >> " + cRightMouthY);



                cRightMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 11)).getPosition().x);
                cRightMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 11)).getPosition().y);

            canvas.drawCircle(cRightMouthX, cRightMouthY, 10, paint);

            float centerPointX = (cLeftMouthX + cRightMouthX) / 2;
            float centerPointY = ((cLeftMouthY + cRightMouthY) / 2) - 20;

            canvas.drawCircle(centerPointX, centerPointY, 10, paint);

            float differenceX = centerPointX - cBottomMouthX;
            float differenceY = centerPointY - cBottomMouthY;

            Log.i(TAG, "draw: difference X >> " + differenceX + "     Y >> " + differenceY);

            if (differenceY < (-60)) {
                Log.i(TAG, "draw: difference - Mouth is OPENED ");
            } else {
                Log.i(TAG, "draw: difference - Mouth is CLOSED ");
            }
        }
    }


    private int contains (List < Landmark > list,int name){
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getType() == name) {
                return i;
            }
        }
        return 99;
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...