2

I am trying to crop the detected face from camera after converting it to bitmap in onPictureTaken, but it doesn't crop correctly on the face area, how to crop face bitmap from camera?

enter image description here

mCameraSource.takePicture(null, new CameraSource.PictureCallback() {

  @Override
  public void onPictureTaken(byte[] bytes) {

    BitmapFactory.Options opt = new BitmapFactory.Options();
    opt.inDensity = DisplayMetrics.DENSITY_DEFAULT;
    opt.inTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
    opt.inScaled = false;
    Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt);

    Bitmap croppedFace = Bitmap.createBitmap(bmp, (int) facePosition.x, (int) facePosition.y, (int) faceWidth, (int) faceHeight);
    ivProfileImg.setImageBitmap(croppedFace);

  }
});

where facePosition is obtained from Tracker:

private class GraphicFaceTracker extends Tracker<Face> {
    private GraphicOverlay mOverlay;
    private FaceGraphic mFaceGraphic;

    GraphicFaceTracker(GraphicOverlay overlay) {
        mOverlay = overlay;
        mFaceGraphic = new FaceGraphic(overlay);
    }

    @Override
    public void onUpdate(FaceDetector.Detections<Face> detectionResults, Face face) {
        mOverlay.add(mFaceGraphic);
        mFaceGraphic.updateFace(face);

        //for cropping face
        facePosition = face.getPosition();
        faceWidth = face.getWidth();
        faceHeight = face.getHeight();

    }
}

Update: I managed to crop face by trial and error, added code to resize bmp into 1080 width, and scale facePosition values with 1.5, but I'm still not sure what is the proper code to replace these hard-coded values:

enter image description here

mCameraSource.takePicture(null, new CameraSource.PictureCallback() {

  @Override
  public void onPictureTaken(byte[] bytes) {

    BitmapFactory.Options opt = new BitmapFactory.Options();
    opt.inDensity = DisplayMetrics.DENSITY_DEFAULT;
    opt.inTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
    opt.inScaled = false;
    Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt);//2976, 3968

    //resized to 1080
    int resizedHeight = 1080*bmp.getHeight()/bmp.getWidth();
    bmp = Bitmap.createScaledBitmap(bmp,1080, resizedHeight, true);//1080, 1440

    //scale facePosition values to x1.5
    float scale = 1.5f;
    int screenX = (int)facePosition.x * scale;
    int screenY = (int)facePosition.y * scale;
    float fw = faceWidth * scale;
    float fh = faceHeight * scale;

    Bitmap croppedFace = Bitmap.createBitmap(bmp, screenX, screenY, (int) fw, (int) fh);
    ivProfileImg.setImageBitmap(croppedFace);

  }
});
Beeing Jk
  • 3,796
  • 1
  • 18
  • 29
  • Can you provide an example of incorrect crop? Why is it incorrect and what do you expect it to be? – fdermishin Jun 26 '20 at 02:35
  • 1
    @user13044086 I have uploaded a screenshot, hope it helps. – Beeing Jk Jun 26 '20 at 03:05
  • It seems that the issue happens because of using the wrong coordinates. You can check this [question](https://stackoverflow.com/questions/22102503/camera-face-detection-coords-to-screen-coords) if you use camera api 1 – fdermishin Jun 26 '20 at 03:58
  • 1
    Another thing I noticed is that you use take picture and use this bitmap to display it, but you use graphic overlay to detect face. Graphic overlay is potentially of lower size and doesn't match size of the picture taken. Can you check if these dimensions match? – fdermishin Jun 26 '20 at 04:10
  • @user13044086 ya the dimensions doesn't match, because maximum `facePosition.x` is only around 700 but bitmap width is 1080, but when I check `mOverlay.getWidth()`, it is big, 1080 as well. – Beeing Jk Jun 26 '20 at 04:40

0 Answers0