前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >人脸识别(基于ArcFace)

人脸识别(基于ArcFace)

作者头像
用户3112896
发布2019-09-26 16:34:48
5.1K0
发布2019-09-26 16:34:48
举报
文章被收录于专栏:安卓圈安卓圈

我们先来看看效果

上面是根据图片检测出其中的人脸、每个人脸的年龄还有性别,非常强大

第一步:

登录https://ai.arcsoft.com.cn/,注册开发者账号,身份认证,注册应用,得到APPID和SDKKEY

第二步:

阅读SDK接入文档https://ai.arcsoft.com.cn/manual/arcface_android_guideV2.html

其中重要的是下面

代码语言:javascript
复制
Step1:调用FaceEngine的active方法激活设备,一个设备安装后仅需激活一次,卸载重新安装后需要重新激活。

Step2:调用FaceEngine的init方法初始化SDK,初始化成功后才能进一步使用SDK的功能。

Step3:调用FaceEngine的detectFaces方法进行图像数据或预览数据的人脸检测,若检测成功,则可得到一个人脸列表。(初始化时combineMask需要ASF_FACE_DETECT)

Step4:调用FaceEngine的extractFaceFeature方法可对图像中指定的人脸进行特征提取。(初始化时combineMask需要ASF_FACE_RECOGNITION)

Step5:调用FaceEngine的compareFaceFeature方法可对传入的两个人脸特征进行比对,获取相似度。(初始化时combineMask需要ASF_FACE_RECOGNITION)

Step6:调用FaceEngine的process方法,传入不同的combineMask组合可对Age、Gender、Face3Dangle、Liveness进行检测,传入的combineMask的任一属性都需要在init时进行初始化。

Step7:调用FaceEngine的getAge、getGender、getFace3Dangle、getLiveness方法可获取年龄、性别、三维角度、活体检测结果,且每个结果在获取前都需要在process中进行处理。

Step8:调用FaceEngine的unInit方法销毁引擎。在init成功后如不unInit会导致内存泄漏。

引擎一定要先激活,只需激活一次,然后初始化,接着就选择你需要的方法调用,step3-step7选择其中一个调用即可,最后的最后一定要销毁引擎

贴出核心代码:

代码语言:javascript
复制
/**
 * 激活引擎
 */
public void activeEngine() {
    if (!checkPermissions(NEEDED_PERMISSIONS)) {
        ActivityCompat.requestPermissions(this, NEEDED_PERMISSIONS, ACTION_REQUEST_PERMISSIONS);
        return;
    }
    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            faceEngine = new FaceEngine();
            int activeCode = faceEngine.active(MainActivity.this, Constants.APP_ID, Constants.SDK_KEY);
            emitter.onNext(activeCode);
        }
    })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<Integer>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(Integer activeCode) {
                    if (activeCode == ErrorInfo.MOK) {
                        showToast(getString(R.string.active_success));
                    } else if (activeCode == ErrorInfo.MERR_ASF_ALREADY_ACTIVATED) {
                        showToast(getString(R.string.already_activated));
                    } else {
                        showToast(getString(R.string.active_failed, activeCode));
                    }
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });
}
代码语言:javascript
复制
/**
  * 初始化引擎
  **/
private void initEngine() {
    faceEngineCode = faceEngine.init(this, FaceEngine.ASF_DETECT_MODE_IMAGE, FaceEngine.ASF_OP_0_HIGHER_EXT,
            16, 10, FaceEngine.ASF_FACE_RECOGNITION | FaceEngine.ASF_FACE_DETECT | FaceEngine.ASF_AGE | FaceEngine.ASF_GENDER | FaceEngine.ASF_FACE3DANGLE | FaceEngine.ASF_LIVENESS);
    VersionInfo versionInfo = new VersionInfo();
    faceEngine.getVersion(versionInfo);

    if (faceEngineCode != ErrorInfo.MOK) {
        showToast(getString(R.string.init_failed, faceEngineCode));
    }
}
代码语言:javascript
复制
//bitmap转bgr
byte[] bgr24 = ImageUtil.bitmapToBgr(bitmap);

if (bgr24 == null) {
    clearDialog();
    showToast("图片转化失败");
    return;
}

/**
 * 2.成功获取到了BGR24 数据,开始人脸检测
 */
List<FaceInfo> faceInfoList = new ArrayList<>();
faceEngine.detectFaces(bgr24, width, height, FaceEngine.CP_PAF_BGR24, faceInfoList);
if (faceInfoList.size() == 0) {
    clearDialog();
    showToast("没有检测到人脸");
    startActivity(new Intent(this, MainActivity.class));
}
if (faceInfoList.size() > 1) {
    clearDialog();
    showToast("请不要同时出现多个人脸");
    startActivity(new Intent(this, MainActivity.class));
}
if (faceInfoList.size() == 1) {
    clearDialog();
    FaceInfo faceInfo = faceInfoList.get(0);
    //得到人脸的宽和高
    final int faceWidth = faceInfo.getRect().width();
    final int faceHeight = faceInfo.getRect().height();
    makeFace();
}

我这里只做了识别人脸,其他的功能可以参考官网的Demo

多次调用ImageView.setImageResource方法,我在开发过程中遇到了OOM,因为这些加载图片的方法最终都是通过java层的createBitmap来完成的,需要消耗很多内存

可以采用BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的source。decedeStream最大的秘密在于其直接调用JNI>>nativeDecideAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间

代码语言:javascript
复制
/**
 * 此方法是为了防止内存溢出
 */
private BitmapDrawable getBitmap(int resId) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferredConfig = Bitmap.Config.RGB_565;
    options.inPurgeable = true;
    options.inInputShareable = true;
    InputStream is = getResources().openRawResource(resId);
    Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);
    try {
        is.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return new BitmapDrawable(getResources(), bitmap);
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 安卓圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
人脸识别
腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档