您现在的位置是:群英 > 开发技术 > 编程语言
Android从图片中切取人脸区域怎么操作
Admin发表于 2022-04-26 14:23:241061 次浏览
这篇文章给大家分享的是“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从图片中切取人脸区域怎么操作已经有了进一步的了解,如果想要了解更多相关的内容,欢迎关注群英网络,群英网络将为大家推送更多相关知识点的文章。

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

相关信息推荐
2022-06-21 17:09:27 
摘要:本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于数据处理中常见的一些问题,包括了数据的增删改查、数据的排序、数据的去重、平级列表变成树形结构以及数组对象相同项合并处理,下面一起来看一下,希望对大家有帮助。
2022-12-06 17:52:30 
摘要:php查询结果的方法:1、通过mysql_result()函数获取结果数据集中的一行元素;2、通过mysql_fetch_row()函数将数字作为属性索引来获得属性值;3、使用mysql_fetch_array()函数直接获得属性值;4、通过mysql_fetch_object()函数分析查询结果。
2022-08-19 17:49:19 
摘要:这篇文章主要介绍了如何在pycharm中使用less,操作步骤真的很简单,本文通过图文并茂的形式给大家详细介绍,需要的朋友可以参考下
云活动
推荐内容
热门关键词
热门信息
群英网络助力开启安全的云计算之旅
立即注册,领取新人大礼包
  • 联系我们
  • 24小时售后:4006784567
  • 24小时TEL :0668-2555666
  • 售前咨询TEL:400-678-4567

  • 官方微信

    官方微信
Copyright  ©  QY  Network  Company  Ltd. All  Rights  Reserved. 2003-2019  群英网络  版权所有   茂名市群英网络有限公司
增值电信经营许可证 : B1.B2-20140078   粤ICP备09006778号
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
微信公众号
返回顶部
返回顶部 返回顶部