Android 集成百度人脸采集,实现简单人脸采集module

代码 演示效果:

一,创建账号,并集成百度人脸离线采集

        1、注册百度账号并认证

        百度智能云地址:百度智能云控制台-管理中心 (baidu.com)

        登录百度智能云后选择人脸采集

        

        2. 创建你的应用

        

        3.创建完成后,选择本地化部署,选择 离线人脸采集sdk  

        4. 需要注册,按照流程走就行,一般一天就能申请下来

                

        5. 注册完成后 创建新的授权

授权标识: 就是License ID 可以随意填写

场景类型:根据需要填写

开发平台:选择Android即可

Android包名 : 一定要和你的项目包名一样  比如我的项目包名是 com.bd.face,

那么我填写的也是com.bd.face

android MD5 签名:  

                1.首先 你要在Android中创建一个签名:

密钥  Alias:为您的密钥输入一个标识名。

Password:为您的密钥创建并确认一个安全的密码。此密码应当与您为密钥库选择 的密码不同

Validity (years):以年为单位设置密钥的有效时长。密钥的有效期应至少为 25 年, 以便您可以在应用的整个生命期内使用相同的密钥签署应用更新。

Certificate:为证书输入一些关于您自己的信息。此信息不会显示在应用中,但会作 为 APK 的一部分包含在您的证书中。 填写完表单后,请点击 OK

 这样你的签名就已经生成好了 请牢记你的密码

        2. (此步骤不可省略)生成完成之后 下面我们对 项目进行加签

        输入上面Alias密钥标识 选择文件位置,输入你刚注册的密码 这里release 和debug 都需要

 

 3. 下面开始生成签名的MD5

        找到 studio中的Terminal  

4.输入命令“ keytool -v -list -keystore gradledemo.jks ” 回车,(这里的xxxx.jks要输入你自己的),然后输入密码,就获取到你想要的信息了。如图

 5.把得到的MD5 值 输入到 这里 

点击确定后 生成

 

 

 下面开始集成:

二、集成

2.1 创建  assets 资源文件夹  放入下载的 License 


2.2 引入faceplatform-release库
将开发包中的faceplatform-release库 Import Module 到工程。

2.3 引入faceplatform-ui库
将开发包中的faceplatform-ui库 Import Module 到工程。

2.4 在 app 下的build.gradle 中添加

implementation project(path: ':faceplatform-ui')

 以上集成就已经完全集成成功!

下面奉上代码过程:

二.代码实现: 

    2.1首先添加权限:

      清单文件中需要添加一下文件

<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.hardware.camera.autofocus"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"
    tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>

需要添加动态权限有:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    requestPermissions(
        new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
          Manifest.permission.WRITE_EXTERNAL_STORAGE
         ,Manifest.permission.CAMERA
},1001);
}

2.2初始化FaceSDKManager

   2.2.1 首先配置 人脸参数数据  上代码:  

             代码有点多但是基本上都是复制

private void setFaceConfig() {
    // 获取配置人脸 的接口
    FaceConfig config = FaceSDKManager.getInstance().getFaceConfig();
    // 设置模糊度阈值
    config.setBlurnessValue((float)0.8);
    // 设置最小光照阈值(范围0-255)
    config.setBrightnessValue(30);
    // 设置最大光照阈值(范围0-255)
    config.setBrightnessMaxValue(240);
    // 设置左眼遮挡阈值
    config.setOcclusionLeftEyeValue(v);
    // 设置右眼遮挡阈值
    config.setOcclusionRightEyeValue(v);
    // 设置鼻子遮挡阈值
    config.setOcclusionNoseValue(v);
    // 设置嘴巴遮挡阈值
    config.setOcclusionMouthValue(v);
    // 设置左脸颊遮挡阈值
    config.setOcclusionLeftContourValue(v);
    // 设置右脸颊遮挡阈值
    config.setOcclusionRightContourValue(v);
    // 设置下巴遮挡阈值
    config.setOcclusionChinValue(v);
    // 设置人脸姿态角阈值
    config.setHeadPitchValue(30);
    config.setHeadYawValue(18);
    config.setHeadRollValue(30);
    // 设置可检测的最小人脸阈值
    config.setMinFaceSize(FaceEnvironment.VALUE_MIN_FACE_SIZE);
    // 设置可检测到人脸的阈值
    config.setNotFaceValue(FaceEnvironment.VALUE_NOT_FACE_THRESHOLD);
    // 设置闭眼阈值
    config.setEyeClosedValue(FaceEnvironment.VALUE_CLOSE_EYES);
    // 设置图片缓存数量
    config.setCacheImageNum(FaceEnvironment.VALUE_CACHE_IMAGE_NUM);
    // 设置活体动作,通过设置list,LivenessTypeEunm.Eye, LivenessTypeEunm.Mouth,
    // LivenessTypeEunm.HeadUp, LivenessTypeEunm.HeadDown, LivenessTypeEunm.HeadLeft,
    // LivenessTypeEunm.HeadRight
    config.setLivenessTypeList(livenessList);
    // 设置动作活体是否随机
    config.setLivenessRandom(true);
    // 设置开启提示音
    config.setSound(true);
    // 原图缩放系数
    config.setScale(FaceEnvironment.VALUE_SCALE);
    // 抠图宽高的设定,为了保证好的抠图效果,建议高宽比是4:3
    config.setCropHeight(FaceEnvironment.VALUE_CROP_HEIGHT);
    config.setCropWidth(FaceEnvironment.VALUE_CROP_WIDTH);
    // 抠图人脸框与背景比例
    config.setEnlargeRatio(FaceEnvironment.VALUE_CROP_ENLARGERATIO);
    // 加密类型,0:Base64加密,上传时image_sec传false;1:百度加密文件加密,上传时image_sec传true
    config.setSecType(FaceEnvironment.VALUE_SEC_TYPE);
    // 检测超时设置
    config.setTimeDetectModule(FaceEnvironment.TIME_DETECT_MODULE);
    // 检测框远近比率
    config.setFaceFarRatio(FaceEnvironment.VALUE_FAR_RATIO);
    config.setFaceClosedRatio(FaceEnvironment.VALUE_CLOSED_RATIO);
    // 保存 设置
    FaceSDKManager.getInstance().setFaceConfig(config);
}

2.2.2初始化FaceSDKManager

// 初始化 人脸 功能
    private void initLicense() {
        // 调用 配置信息方法
        setFaceConfig();
        // 为了android和ios 区分授权,appId=appname_face_android ,其中appname为申请sdk时的应用名
        // 应用上下文
        // 申请License取得的APPID
        // assets目录下License文件名
        FaceSDKManager.getInstance().initialize(this, "******-face-android",
                "idl-license.face-android", new IInitCallback() {
                    @Override
                    public void initSuccess() {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this, "初始化成功", Toast.LENGTH_SHORT).show();
                                isfacle=true;
                            }
                        });
                    }

                    @Override
                    public void initFailure(final int errCode, final String errMsg) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this, "初始化失败", Toast.LENGTH_SHORT).show();
                                isfacle=false;
                            }
                        });
                    }
            });
    }

这样咱们 的初始化就完成了 下面就是初始化的全部代码

  布局代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

   <Button
       android:onClick="onclick"
       android:text="人脸采集"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>

</LinearLayout>

Java代码


import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.baidu.idl.face.platform.FaceConfig;
import com.baidu.idl.face.platform.FaceEnvironment;
import com.baidu.idl.face.platform.FaceSDKManager;
import com.baidu.idl.face.platform.LivenessTypeEnum;
import com.baidu.idl.face.platform.listener.IInitCallback;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private List<LivenessTypeEnum> livenessList;
    private float v = (float)0.95;
    private boolean isfacle=false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA},1001);
        }

        // 动作活体条目集合
        livenessList = new ArrayList<>();
        // 眨眼
        livenessList.add(LivenessTypeEnum.Eye);
        // 张嘴
        livenessList.add(LivenessTypeEnum.Mouth);
        // 右转
        livenessList.add(LivenessTypeEnum.HeadRight);

        // 初始化FaceSDK
        initLicense();
    }

    public void onclick(View view) {
        if (isfacle){
            // 跳转到采集页面
            startActivity(new Intent(this,FaceLivenessExpActivity.class));
        }else {
            Toast.makeText(this, "初始化失败", Toast.LENGTH_SHORT).show();
        }
    }
    /**
     * 参数配置方法
     */
    private void setFaceConfig() {
        // 获取配置人脸 的接口
        FaceConfig config = FaceSDKManager.getInstance().getFaceConfig();
        // 设置模糊度阈值
        config.setBlurnessValue((float)0.8);
        // 设置最小光照阈值(范围0-255)
        config.setBrightnessValue(30);
        // 设置最大光照阈值(范围0-255)
        config.setBrightnessMaxValue(240);
        // 设置左眼遮挡阈值
        config.setOcclusionLeftEyeValue(v);
        // 设置右眼遮挡阈值
        config.setOcclusionRightEyeValue(v);
        // 设置鼻子遮挡阈值
        config.setOcclusionNoseValue(v);
        // 设置嘴巴遮挡阈值
        config.setOcclusionMouthValue(v);
        // 设置左脸颊遮挡阈值
        config.setOcclusionLeftContourValue(v);
        // 设置右脸颊遮挡阈值
        config.setOcclusionRightContourValue(v);
        // 设置下巴遮挡阈值
        config.setOcclusionChinValue(v);
        // 设置人脸姿态角阈值
        config.setHeadPitchValue(30);
        config.setHeadYawValue(18);
        config.setHeadRollValue(30);
        // 设置可检测的最小人脸阈值
        config.setMinFaceSize(FaceEnvironment.VALUE_MIN_FACE_SIZE);
        // 设置可检测到人脸的阈值
        config.setNotFaceValue(FaceEnvironment.VALUE_NOT_FACE_THRESHOLD);
        // 设置闭眼阈值
        config.setEyeClosedValue(FaceEnvironment.VALUE_CLOSE_EYES);
        // 设置图片缓存数量
        config.setCacheImageNum(FaceEnvironment.VALUE_CACHE_IMAGE_NUM);
        // 设置活体动作,通过设置list,LivenessTypeEunm.Eye, LivenessTypeEunm.Mouth,
        // LivenessTypeEunm.HeadUp, LivenessTypeEunm.HeadDown, LivenessTypeEunm.HeadLeft,
        // LivenessTypeEunm.HeadRight
        config.setLivenessTypeList(livenessList);
        // 设置动作活体是否随机
        config.setLivenessRandom(true);
        // 设置开启提示音
        config.setSound(true);
        // 原图缩放系数
        config.setScale(FaceEnvironment.VALUE_SCALE);
        // 抠图宽高的设定,为了保证好的抠图效果,建议高宽比是4:3
        config.setCropHeight(FaceEnvironment.VALUE_CROP_HEIGHT);
        config.setCropWidth(FaceEnvironment.VALUE_CROP_WIDTH);
        // 抠图人脸框与背景比例
        config.setEnlargeRatio(FaceEnvironment.VALUE_CROP_ENLARGERATIO);
        // 加密类型,0:Base64加密,上传时image_sec传false;1:百度加密文件加密,上传时image_sec传true
        config.setSecType(FaceEnvironment.VALUE_SEC_TYPE);
        // 检测超时设置
        config.setTimeDetectModule(FaceEnvironment.TIME_DETECT_MODULE);
        // 检测框远近比率
        config.setFaceFarRatio(FaceEnvironment.VALUE_FAR_RATIO);
        config.setFaceClosedRatio(FaceEnvironment.VALUE_CLOSED_RATIO);
        // 保存 设置
        FaceSDKManager.getInstance().setFaceConfig(config);
    }

    // 初始化 人脸 功能
    private void initLicense() {
        // 调用 配置信息方法
        setFaceConfig();
        // 为了android和ios 区分授权,appId=appname_face_android ,其中appname为申请sdk时的应用名
        // 应用上下文
        // 申请License取得的APPID
        // assets目录下License文件名
        FaceSDKManager.getInstance().initialize(this, "wangyilong-face-android",
                "idl-license.face-android", new IInitCallback() {
                    @Override
                    public void initSuccess() {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this, "初始化成功", Toast.LENGTH_SHORT).show();
                                isfacle=true;
                            }
                        });
                    }

                    @Override
                    public void initFailure(final int errCode, final String errMsg) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this, "初始化失败", Toast.LENGTH_SHORT).show();
                                isfacle=false;
                            }
                        });
                    }
            });
    }
 @Override
    protected void onDestroy() {
        super.onDestroy();
        // 释放资源
        FaceSDKManager.getInstance().release();
    }
}

2.2 采集人脸页面的代码

  2.2.1  创建一个java类 集成自 FaceLivenessActivity 这个 FaceLivenessActivity 是引用的Module里面的  在清单文件中记得注册

<activity
            android:name=".FaceLivenessExpActivity"
            android:hardwareAccelerated="true"
            android:launchMode="singleTop"
            android:screenOrientation="portrait" />

Java代码: 重写里面的  onLivenessCompletion 方法

// todo 人脸 识别 活体检测
public class FaceLivenessExpActivity extends FaceLivenessActivity  {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }
    // 开始采集
    @Override
    public void onLivenessCompletion(FaceStatusNewEnum status, String message,
                                     HashMap<String, ImageInfo> base64ImageCropMap,
                                     HashMap<String, ImageInfo> base64ImageSrcMap, int currentLivenessCount) {
        super.onLivenessCompletion(status, message, base64ImageCropMap, base64ImageSrcMap, currentLivenessCount);

      
    }





    @Override
    public void finish() {
        super.finish();
    }

}
 获取最优图片 人脸采集时像素最清晰的一张
  // 开始采集
    @Override
    public void onLivenessCompletion(FaceStatusNewEnum status, String message,
                                     HashMap<String, ImageInfo> base64ImageCropMap,
                                     HashMap<String, ImageInfo> base64ImageSrcMap, int currentLivenessCount) {
        super.onLivenessCompletion(status, message, base64ImageCropMap, base64ImageSrcMap, currentLivenessCount);

        if (status == FaceStatusNewEnum.OK && mIsCompletion) {
            // 获取最优图片
            /***
             * base64ImageCropMap 裁剪 图片 集合
             *  base64ImageSrcMap 原图集合
             * */
            getBestImage(base64ImageCropMap, base64ImageSrcMap);
            // 在规定时间内没有完成
        } else if (status == FaceStatusNewEnum.DetectRemindCodeTimeout) {
            // 提示 动画
            if (mViewBg != null) {
                mViewBg.setVisibility(View.VISIBLE);
            }
            Toast.makeText(this, "您在规定时间内尚未完成", Toast.LENGTH_SHORT).show();
        }
    }
/**
     * 获取最优图片
     * @param imageCropMap 抠图集合
     * @param imageSrcMap  原图集合
     */
    private void getBestImage(HashMap<String, ImageInfo> imageCropMap,
                              HashMap<String, ImageInfo> imageSrcMap) {
        String bmpStr = null;
        // 将抠图集合中的图片按照质量降序排序,最终选取质量最优的一张抠图图片
        if (imageCropMap != null && imageCropMap.size() > 0) {
            List<Map.Entry<String, ImageInfo>> list1 = new ArrayList<>(imageCropMap.entrySet());
            // 返回来的 值 在list1 中
            Collections.sort(list1, new Comparator<Map.Entry<String, ImageInfo>>() {

                @Override
                public int compare(Map.Entry<String, ImageInfo> o1,
                                   Map.Entry<String, ImageInfo> o2) {
                    String[] key1 = o1.getKey().split("_");
                    String score1 = key1[2];
                    String[] key2 = o2.getKey().split("_");
                    String score2 = key2[2];
                    //  return 用于 结束循环    并返回 排完的集合
                    // 降序排序
                    return Float.valueOf(score2).compareTo(Float.valueOf(score1));
                }
            });

            // 获取抠图中的加密或非加密的base64
//            int secType = mFaceConfig.getSecType();
//            String base64;
//            if (secType == 0) {
//                base64 = list1.get(0).getValue().getBase64();
//            } else {
//                base64 = list1.get(0).getValue().getSecBase64();
//            }
        }

        // 将原图集合中的图片按照质量降序排序,最终选取质量最优的一张原图图片
        if (imageSrcMap != null && imageSrcMap.size() > 0) {
            List<Map.Entry<String, ImageInfo>> list2 = new ArrayList<>(imageSrcMap.entrySet());
            // 排序方法  返回的值在list2中
            Collections.sort(list2, new Comparator<Map.Entry<String, ImageInfo>>() {

                @Override
                public int compare(Map.Entry<String, ImageInfo> o1,
                                   Map.Entry<String, ImageInfo> o2) {
                    String[] key1 = o1.getKey().split("_");
                    String score1 = key1[2];
                    String[] key2 = o2.getKey().split("_");
                    String score2 = key2[2];
                    // 降序排序
                    return Float.valueOf(score2).compareTo(Float.valueOf(score1));
                }
            });
            // 获取 原图 集合中最优的一张图片
            // 给他转化为 Base64 码
            // 这个码 就是我们人脸的信息
            bmpStr = list2.get(0).getValue().getBase64();

             // 获取原图中的加密或非加密的base64
//            int secType = mFaceConfig.getSecType();
//            String base64;
//            if (secType == 0) {
//                base64 = bmpStr;
//            } else {
//                base64 = list2.get(0).getValue().getBase64();
//            }
//            Log.i("base64",  base64);
        }

        //  获取完 人脸信息后 页面跳转
        //  IntentUtils 导入的包 封装好的
        IntentUtils.getInstance().setBitmap(bmpStr);
        Intent intent = new Intent(FaceLivenessExpActivity.this,
                CompleteActivity.class);
        startActivity(intent);
    }

 还有一个 采集完成跳转的Activity 在下面给大家贴上代码

public class CompleteActivity extends AppCompatActivity {
    private ImageView image;
    private String bmpStr;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_complete);
        image = findViewById(R.id.image);
        Intent intent = getIntent();
        if (intent != null) {
            // 把 传过来的 Bitmp 流转化为 bitmmap 图片
            bmpStr = IntentUtils.getInstance().getBitmap();
            if (TextUtils.isEmpty(bmpStr)) {
                return;
            }
            Bitmap bmp = base64ToBitmap(bmpStr);
            // 进行裁剪
            bmp = FaceSDKManager.getInstance().scaleImage(bmp,
                    DensityUtils.dip2px(getApplicationContext(), 97),
                    DensityUtils.dip2px(getApplicationContext(), 97));
            image.setImageBitmap(bmp);
            Log.i("base64", "initData: "+ bmpStr);
        }

    }
    private Bitmap base64ToBitmap(String base64Data) {
        byte[] bytes = Base64Utils.decode(base64Data, Base64Utils.NO_WRAP);
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }
@Override
    protected void onDestroy() {
        super.onDestroy();
// 释放资源
        IntentUtils.getInstance().release();
    }

以上又是人脸识别的全部过程 第一次写博客 多谢大家支持!  在集成过程中如果有疑问

人脸识别_人脸检测_人脸对比_人脸搜索_活体检测_百度智能云 (baidu.com) 官方文档 解决

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>