在android中使用人脸检测裁剪图像

Posted

技术标签:

【中文标题】在android中使用人脸检测裁剪图像【英文标题】:Crop Image with face detection in android 【发布时间】:2014-04-28 10:09:06 【问题描述】:

我需要一个可以使用人脸检测功能裁剪任何图像的演示。

已修复

但是经过几个小时的冲浪后,我一个演示都没有,所以我准备了一个演示,结合了我在网上找到的几个演示。

我已经准备了一个演示来裁剪图像。

我的演示裁剪了图像矩形和圆形。

它还检测人脸并根据人脸检测裁剪图像。

我正在使用下面的图片来裁剪它。

裁剪结果的截图是:

示例的xml是:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity" >

<View
    android:id="@+id/part1"
    android:layout_
    android:layout_ >
</View>

<View
    android:id="@+id/part2"
    android:layout_
    android:layout_
    android:layout_marginTop="30dp" >
</View>

</LinearLayout>

Activity的java代码:

public class MainActivity extends Activity 
public View part1, part2;
int viewHeight, viewWidth;
private FaceDetector myFaceDetect;
private FaceDetector.Face[] myFace;
float myEyesDistance;

@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    part1 = findViewById(R.id.part1);
    part2 = findViewById(R.id.part2);
    part1.post(new Runnable() 

        @Override
        public void run() 
            // TODO Auto-generated method stub
            viewHeight = part1.getMeasuredHeight();
            viewWidth = part1.getMeasuredWidth();
            try 

                Paint paint = new Paint();
                paint.setFilterBitmap(true);
                Bitmap bitmapOrg = BitmapFactory.decodeResource(
                        getResources(),
                        R.drawable.sachin_tendulkar_10102013);

                int targetWidth = bitmapOrg.getWidth();
                int targetHeight = bitmapOrg.getHeight();

                Bitmap targetBitmap = Bitmap.createBitmap(targetWidth,
                        targetHeight, Bitmap.Config.ARGB_8888);

                RectF rectf = new RectF(0, 0, viewWidth, viewHeight);

                Canvas canvas = new Canvas(targetBitmap);
                Path path = new Path();

                path.addRect(rectf, Path.Direction.CW);
                canvas.clipPath(path);

                canvas.drawBitmap(
                        bitmapOrg,
                        new Rect(0, 0, bitmapOrg.getWidth(), bitmapOrg
                                .getHeight()), new Rect(0, 0, targetWidth,
                                targetHeight), paint);

                Matrix matrix = new Matrix();
                matrix.postScale(1f, 1f);

                BitmapFactory.Options bitmapFatoryOptions = new BitmapFactory.Options();
                bitmapFatoryOptions.inPreferredConfig = Bitmap.Config.RGB_565;

                bitmapOrg = BitmapFactory.decodeResource(getResources(),
                        R.drawable.sachin_tendulkar_10102013,
                        bitmapFatoryOptions);

                myFace = new FaceDetector.Face[5];
                myFaceDetect = new FaceDetector(targetWidth, targetHeight,
                        5);
                int numberOfFaceDetected = myFaceDetect.findFaces(
                        bitmapOrg, myFace);
                Bitmap resizedBitmap = null;
                if (numberOfFaceDetected > 0) 
                    PointF myMidPoint = null;
                    Face face = myFace[0];
                    myMidPoint = new PointF();
                    face.getMidPoint(myMidPoint);
                    myEyesDistance = face.eyesDistance();

                    if (myMidPoint.x + viewWidth > targetWidth) 
                        while (myMidPoint.x + viewWidth > targetWidth) 
                            myMidPoint.x--;
                        
                    
                    if (myMidPoint.y + viewHeight > targetHeight) 
                        while (myMidPoint.y + viewHeight > targetHeight) 
                            myMidPoint.y--;
                        
                    
                    resizedBitmap = Bitmap.createBitmap(bitmapOrg,
                            (int) (myMidPoint.x - myEyesDistance),
                            (int) (myMidPoint.y - myEyesDistance),
                            viewWidth, viewHeight, matrix, true);
                 else 
                    resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
                            viewWidth, viewHeight, matrix, true);
                
                /* convert Bitmap to resource */
                // Bitmap resizedBitmap = Bitmap.createBitmap(targetBitmap,
                // 0,
                // 0, viewWidth, viewHeight, matrix, true);
                BitmapDrawable bd = new BitmapDrawable(resizedBitmap);

                part1.setBackgroundDrawable(bd);

             catch (Exception e) 
                System.out.println("Error1 : " + e.getMessage()
                        + e.toString());
            
        
    );
    part2.post(new Runnable() 

        @Override
        public void run() 
            // TODO Auto-generated method stub
            viewHeight = part2.getMeasuredHeight();
            viewWidth = part2.getMeasuredWidth();
            try 

                Paint paint = new Paint();
                paint.setFilterBitmap(true);
                Bitmap bitmapOrg = BitmapFactory.decodeResource(
                        getResources(),
                        R.drawable.sachin_tendulkar_10102013);

                int targetWidth = bitmapOrg.getWidth();
                int targetHeight = bitmapOrg.getHeight();

                Bitmap targetBitmap = Bitmap.createBitmap(targetWidth,
                        targetHeight, Bitmap.Config.ARGB_8888);

                RectF rectf = new RectF(0, 0, viewWidth, viewHeight);

                Canvas canvas = new Canvas(targetBitmap);
                Path path = new Path();

                path.addRect(rectf, Path.Direction.CW);
                canvas.clipPath(path);

                canvas.drawBitmap(
                        bitmapOrg,
                        new Rect(0, 0, bitmapOrg.getWidth(), bitmapOrg
                                .getHeight()), new Rect(0, 0, targetWidth,
                                targetHeight), paint);

                Matrix matrix = new Matrix();
                matrix.postScale(1f, 1f);

                BitmapFactory.Options bitmapFatoryOptions = new BitmapFactory.Options();
                bitmapFatoryOptions.inPreferredConfig = Bitmap.Config.RGB_565;

                bitmapOrg = BitmapFactory.decodeResource(getResources(),
                        R.drawable.sachin_tendulkar_10102013,
                        bitmapFatoryOptions);

                myFace = new FaceDetector.Face[5];
                myFaceDetect = new FaceDetector(targetWidth, targetHeight,
                        5);
                int numberOfFaceDetected = myFaceDetect.findFaces(
                        bitmapOrg, myFace);
                Bitmap resizedBitmap = null;
                if (numberOfFaceDetected > 0) 
                    PointF myMidPoint = null;
                    Face face = myFace[0];
                    myMidPoint = new PointF();
                    face.getMidPoint(myMidPoint);
                    myEyesDistance = face.eyesDistance() + 20;

                    if (myMidPoint.x + viewWidth > targetWidth) 
                        while (myMidPoint.x + viewWidth > targetWidth) 
                            myMidPoint.x--;
                        
                    
                    if (myMidPoint.y + viewHeight > targetHeight) 
                        while (myMidPoint.y + viewHeight > targetHeight) 
                            myMidPoint.y--;
                        
                    
                    resizedBitmap = Bitmap.createBitmap(bitmapOrg,
                            (int) (myMidPoint.x - myEyesDistance),
                            (int) (myMidPoint.y - myEyesDistance),
                            viewWidth, viewHeight, matrix, true);
                 else 
                    resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
                            viewWidth, viewHeight, matrix, true);
                
                /* convert Bitmap to resource */
                // Bitmap resizedBitmap = Bitmap.createBitmap(targetBitmap,
                // 0,
                // 0, viewWidth, viewHeight, matrix, true);
                BitmapDrawable bd = new  BitmapDrawable(resizedBitmap);

                part2.setBackgroundDrawable(new BitmapDrawable(
                        getCroppedBitmap(bd.getBitmap())));

             catch (Exception e) 
                System.out.println("Error1 : " + e.getMessage()
                        + e.toString());
            
        
    );


@Override
public boolean onCreateOptionsMenu(Menu menu) 
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;


public Bitmap getCroppedBitmap(Bitmap bitmap) 
    // Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
    // bitmap.getHeight(), Config.ARGB_8888);
    // Canvas canvas = new Canvas(output);
    //
    // final int color = 0xff424242;
    // final Paint paint = new Paint();
    // final Rect rect = new Rect(0, 0, bitmap.getWidth(),
    // bitmap.getHeight());
    //
    // paint.setAntiAlias(true);
    // canvas.drawARGB(0, 0, 0, 0);
    // paint.setColor(color);
    // // canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
    // canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
    // bitmap.getWidth() / 2, paint);
    // paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    // canvas.drawBitmap(bitmap, rect, rect, paint);
    // // Bitmap _bmp = Bitmap.createScaledBitmap(output, 60, 60, false);
    // // return _bmp;
    // return output;

    int targetWidth = bitmap.getWidth();
    int targetHeight = bitmap.getHeight();
    Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight,
            Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(targetBitmap);
    Path path = new Path();
    path.addCircle(((float) targetWidth - 1) / 2,
            ((float) targetHeight - 1) / 2,
            (Math.min(((float) targetWidth), ((float) targetHeight)) /    2),
            Path.Direction.CCW);

    canvas.clipPath(path);
    Bitmap sourceBitmap = bitmap;
    canvas.drawBitmap(sourceBitmap, new Rect(0, 0, sourceBitmap.getWidth(),
            sourceBitmap.getHeight()), new Rect(0, 0, targetWidth,
            targetHeight), null);
    return targetBitmap;




【问题讨论】:

现在有什么问题? 我的问题现在已经解决了,但是上传了代码以防有人想要它,thnx.. 它可以在任何图像中使用吗? 是的,它是..您只需像我一样将图像放在任何可绘制的文件夹中..如果您想从图库中裁剪任何图像,只需为该图像制作一个名为 bitmapOrg 的位图..并继续演示.. 它不适用于所有图像 【参考方案1】:

该演示适用于放置在可绘制文件夹中的任何图像,

但是,如果您想裁剪任何动态图像,例如从图库中下载或选择的任何图像,只需对代码进行一些更改:

看线:

Bitmap bitmapOrg = BitmapFactory.decodeResource(
                    getResources(),
                    R.drawable.sachin_tendulkar_10102013);

这里我从 drawable 文件夹中获取图像,现在对于任何下载的图像,您只需将该图像保存在 bitmapOrg 变量中,因此只需将上述行更改两次,part1 用于矩形,part2 用于 ciculart您下载的图像作为位图保存到 bitmapOrg,并使用演示,它将以矩形和圆形方式裁剪您的图像。

【讨论】:

我用过这个,但它并不是在每张图像中都给出 100% 的结果。如果你在分类中使用了新的谷歌视觉 API,那么它会给你 100%。

以上是关于在android中使用人脸检测裁剪图像的主要内容,如果未能解决你的问题,请参考以下文章

Android自动裁剪相机捕获的图像

OpenCV 人脸检测 ROI 断言失败

iOS - 将图像裁剪为检测到的面部的问题

从文件夹中读取所有图像并检测人脸,裁剪并保存到新文件夹

等待图像的格式更改

Flutter 人脸检测