1

所以我使用 API 来检测图像中的人脸,到目前为止它对我来说效果很好。但是,我无法弄清楚如何将图像裁剪到脸部。我知道如何裁剪位图,但它需要在位图中获取人脸的左上角位置以及宽度和高度。当我使用查询左上角位置时

    points = face.getPosition();

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

但是当我查看点时,我注意到 y 是 -63.5555 而 x 是 235.6666;我不明白为什么有一个负的 y 坐标。我做了一些调试并查看了面部对象内部;我发现它已经包含一个 PointF 对象,该对象已经具有正 x 和 y 坐标。那么为什么在这种情况下会返回负 y 坐标呢?

4

2 回答 2

3

边界框估计头部的尺寸,即使它在照片中可能不完全可见。如果面部被图像的顶部或左侧裁剪,则坐标可能为负(例如,头部顶部从图片顶部裁剪,导致y坐标高于0)。

您在调试中看到的差异是由于实现在内部使用头部中心位置来表示位置(大约在眼睛之间的中点),但是当您使用 API 将其转换为左上角位置时为方便起见,调用 getPosition。

另请注意,边界框不一定是面部的紧密边界。如果您想要更紧密的拟合,您应该启用地标检测并计算您相对于返回的地标的所需裁剪水平。

于 2016-07-19T17:30:28.937 回答
0

我之前使用过相同的 API,并且能够成功裁剪脸部。

尝试

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

getRotateImageToUpload 的代码是

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;
}
于 2016-07-19T06:33:59.527 回答