1

So I am using the API to detect faces in images, and it is working well for me so far. I have not been able to figure out how to crop the image to the face however. I know how to crop the Bitmap, but it requires getting the top left position of the face in the Bitmap and width and height. When I query for the top left position using

    points = face.getPosition();

    Bitmap bmp = Bitmap.createBitmap(bit,(int)points.x,(int)(-1.0*points.y),(int)face.getWidth(),(int)face.getHeight());

But when I look at points, I notice that y is -63.5555 and x is 235.6666; I dont understand why there is a negative y coordinate. I did some Debugging and looked inside the face object; I found that it contained a PointF object already that had positive x and y coordinates. So why is a negative y coordinate being returned in this case?

georgetheevilman
  • 177
  • 4
  • 10

2 Answers2

3

The bounding box estimates the dimensions of the head, even though it may not be entirely visible within the photo. The coordinates may be negative if the face is cropped by the top or left of the image (e.g., the top of the head is cropped off the top of the picture, resulting in a y coordinate above 0).

The difference that you see in debugging is due to that fact that the implementation internally uses the head center position to represent the position (approximately at the mid-point between the eyes), but the API translates this to the top-left position when you call getPosition, for your convenience.

Also note that the bounding box is not necessarily a tight bounds on the face. If you want a tighter fit, you should enable landmark detection and compute your desired level of cropping relative to the returned landmarks.

pm0733464
  • 2,862
  • 14
  • 16
0

I have used the same API before and was able to successfully crop the face.

Try

           //Crop face option

           BitmapFactory.Options options = new BitmapFactory.Options();
           options.inPreferredConfig = Bitmap.Config.ARGB_8888;
           //Bitmap bitmap = BitmapFactory.decodeFile(pictureFile.getAbsolutePath(), options);
           Bitmap bitmap = getRotatedImageToUpload(pictureFile.getAbsolutePath());


           Bitmap faceBitmap = Bitmap.createBitmap(bitmap, (int) faceCentre.x, (int) faceCentre.y, (int) faceWidth, (int) faceHeight);

           FileOutputStream out = null;
           try {
               out = new FileOutputStream(getOutputMediaFile());
               faceBitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
               // PNG is a lossless format, the compression factor (100) is ignored
           } catch (Exception e) {
               e.printStackTrace();
           } finally {
               try {
                   if (out != null) {
                       out.close();
                   }
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }

           //End of Crop face option

And the code for getRotateImageToUpload is

public Bitmap getRotatedImageToUpload(String filePath) {
        try {
            String file = filePath;
            BitmapFactory.Options bounds = new BitmapFactory.Options();
            bounds.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(file, bounds);

        BitmapFactory.Options opts = new BitmapFactory.Options();
        Bitmap bm = BitmapFactory.decodeFile(file, opts);
        ExifInterface exif = null;

        exif = new ExifInterface(file);

        String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
        int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL;

        int rotationAngle = 0;
        if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
        if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
        if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;

        Matrix matrix = new Matrix();
        matrix.setRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
        Bitmap rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bounds.outWidth, bounds.outHeight, matrix, true);
        return rotatedBitmap;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}