首页后端开发其他后端知识Android从图片中切取人脸区域怎么操作

Android从图片中切取人脸区域怎么操作

时间2024-03-28 14:40:03发布访客分类其他后端知识浏览376
导读:这篇文章给大家分享的是“Android从图片中切取人脸区域怎么操作”,文中的讲解内容简单清晰,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下“Android从图片中切取人脸区域怎么操作”吧。...
这篇文章给大家分享的是“Android从图片中切取人脸区域怎么操作”,文中的讲解内容简单清晰,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下“Android从图片中切取人脸区域怎么操作”吧。


从一张图片中切出人脸区域是App开发中常用的场景,譬如,现在很多App用户上传头像的时候,喜欢随手自拍。自拍的图片往往在尺寸、位置上并不完美。而App需要在各种千奇百怪的UI场景下显示用户的头像。所以从原始头像图片中切取出人脸区域看起来是个刚需。这里介绍如何应用Android提供的人脸识别接口完成简单的切取人脸区域。


简单起见,输入为一个可能人脸的Bitmap,并且假定目标是识别出一个人脸而已。输出为一个以人脸为中心的原图的部分切图。如果需要自定义长宽比例,或者只需要定位人脸位置,来半侧切图,可以稍加改动实现。


Android官方提供的人脸识别api在android.media.FaceDetector,核心的api是FaceDetector.findFaces()


直接贴代码

package com.example.testface;
    
 
import android.graphics.Bitmap;
    
import android.graphics.PointF;
    
import android.media.FaceDetector;
    
import android.util.Log;

 
public final class FaceHelper {
    
 
    private static final String LOG_TAG = "FaceHelper";
    
    private static final boolean DEBUG_ENABLE = false;

 
    public static Bitmap genFaceBitmap(Bitmap sourceBitmap) {

 
        if (!checkBitmap(sourceBitmap, "genFaceBitmap()")) {
    
            return null;

        }
    
 
        // default algorithm of face detecting of Android can only handle
        // RGB_565 bitmap, so copy it by RGB_565 here.
        Bitmap cacheBitmap = sourceBitmap.copy(Bitmap.Config.RGB_565, false);
    
 
        // gives up strong reference here. because this method may be
        // time-consuming, so maybe run in work thread usually, we give up the
        // strong reference of the source bitmap after it copied, so that it can
        // be recycled and GC in another thread.
        sourceBitmap = null;

 
        if (DEBUG_ENABLE) {
    
            Log.i(LOG_TAG,
                    "genFaceBitmap() : source bitmap width - "
                              cacheBitmap.getWidth()   " , height - "
                              cacheBitmap.getHeight());

        }
    
 
        int cacheWidth = cacheBitmap.getWidth();
    
        int cacheHeight = cacheBitmap.getHeight();

 
        // default algorithm of face detecting of Android can only handle the
        // bitmap that width is even, so we give up the 1 pixel from right if
        // not even.
        if (cacheWidth % 2 != 0) {

            if (0 == cacheWidth - 1) {

                if (DEBUG_ENABLE) {
    
                    Log.e(LOG_TAG,
                            "genFaceBitmap() : source bitmap width is only 1 , return null.");

                }
    
                return null;

            }
    
            final Bitmap localCacheBitmap = Bitmap.createBitmap(cacheBitmap, 0,
                    0, cacheWidth - 1, cacheHeight);
    
            cacheBitmap.recycle();
    
            cacheBitmap = localCacheBitmap;
    
            --cacheWidth;

 
            if (DEBUG_ENABLE) {
    
                Log.i(LOG_TAG,
                        "genFaceBitmap() : source bitmap width - "
                                  cacheBitmap.getWidth()   " , height - "
                                  cacheBitmap.getHeight());

            }

        }
    
 
        final FaceDetector.Face[] faces = new FaceDetector.Face[1];
    
        final int facefound = new FaceDetector(cacheWidth, cacheHeight, 1)
                .findFaces(cacheBitmap, faces);

        if (DEBUG_ENABLE) {
    
            Log.i(LOG_TAG, "genFaceBitmap() : facefound - "   facefound);

        }

        if (0 == facefound) {

            if (DEBUG_ENABLE) {
    
                Log.e(LOG_TAG, "genFaceBitmap() : no face found , return null.");

            }
    
            return null;

        }
    
 
        final PointF p = new PointF();
    
        faces[0].getMidPoint(p);

        if (DEBUG_ENABLE) {
    
            Log.i(LOG_TAG,
                    "getFaceBitmap() : confidence - "   faces[0].confidence());
    
            Log.i(LOG_TAG, "genFaceBitmap() : face center x - "   p.x
                      " , y - "   p.y);

        }
    
        final int faceX = (int) p.x;
    
        final int faceY = (int) p.y;

        if (DEBUG_ENABLE) {
    
            Log.i(LOG_TAG, "genFaceBitmap() : int faceX - "   faceX
                      " , int faceY - "   faceY);

        }
    
 
        // compute an area that face in middle of it.
        int startX, startY, width, height;

        if (faceX = cacheWidth - faceX) {
    
            startX = 0;
    
            width = faceX * 2;

        }
 else {
    
            startX = faceX - (cacheWidth - faceX);
    
            width = (cacheWidth - faceX) * 2;

        }

        if (faceY = cacheHeight - faceY) {
    
            startY = 0;
    
            height = faceY * 2;

        }
 else {
    
            startY = faceY - (cacheHeight - faceY);
    
            height = (cacheHeight - faceY) * 2;

        }
    
 
        final Bitmap result = Bitmap.createBitmap(cacheBitmap, startX, startY,
                width, height);
    
        cacheBitmap.recycle();
    
        return result;

    }

 
    private static boolean checkBitmap(final Bitmap bitmap,
            final String debugInfo) {

        if (null == bitmap || bitmap.isRecycled()) {

            if (DEBUG_ENABLE) {
    
                Log.e(LOG_TAG, debugInfo
                          " : check bitmap , is null or is recycled.");

            }
    
            return false;

        }

        if (0 == bitmap.getWidth() || 0 == bitmap.getHeight()) {

            if (DEBUG_ENABLE) {
    
                Log.e(LOG_TAG, debugInfo
                          " : check bitmap , width is 0 or height is 0.");

            }
    
            return false;

        }
    
        return true;

    }

 
}
    


主要的坑有两个:

(1)只能处理RGB_565格式的Bitmap,需要做转换。

(2)只能处理width为偶数的Bitmap,这里的解法是如果是奇数,则放弃最右侧的一列像素。

这样就可以一个一个把人脸裁剪出来,以便获取人脸的图片,从而用其获取单人脸的特征。
感谢各位的阅读,以上就是“Android从图片中切取人脸区域怎么操作”的内容了,通过以上内容的阐述,相信大家对Android从图片中切取人脸区域怎么操作已经有了进一步的了解,如果想要了解更多相关的内容,欢迎关注网络,网络将为大家推送更多相关知识点的文章。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: Android从图片中切取人脸区域怎么操作
本文地址: https://pptw.com/jishu/655005.html
html5怎样实现页面跳转,有哪些方式 微信小程序特定区域怎样实现滚动到顶部时固定

游客 回复需填写必要信息