最近工作中用到活体检测功能,完成后特地记录一下接入过程和遇到的一些问题
此文参考:
1、准备工作
- 注册百度AI账号:百度AI开放平台
- 注册完后进行企业认证,个人账号无法使用
2、创建应用
创建应用成功后后,会生成AppID 、API Key 等信息,这些信息后续在配置Android时会用到
3、新建授权
- 授权标示:自定义填写
- 场景类型:根据自己项目选择
- 平台类型&&开发平台:默认选中
- iOS包名:
- 安卓包名:
- 安卓签名MD5: 参考图示百度AI里面的的文档生成即可。如果原先已经生成了.keystore 签名文件,那就直接用这个签名查看MD5 值即可。
如何查看MD5 :进入.keystore 签名文件所在目录,命令行输入 keytool –list –v –keystore ./签名文件名称
4、下载SDK
选择刚才创建的授权下载即可
5、Android的配置(需要用Android studio来配置运行)
-
下载Android license文件,拷贝到项目assets目录
-
导入人脸识别封装模块
将 react-native-baidu-face项目里的baiduface文件夹拖到项目包名目录下(例如:com.xxx)
修改Config类,配置对应apiKey、secretKey、licenseID、licenseFileName(默认是idl-license.face-android)
apiKey、secretKey就是前面申请应用拿到的。
对应下面的这些值
-
配置打包签名文件
新建授权的时候我们生成了一个签名文件.keystore或.jks ,并且填入了该签名文件的 MD5
由于SDK运行时会校验签名文件的MD5是否和申请时填入一样。
为了便于debug能正常使用SDK,需要配置打包签名文件。 -
keystore签名文件放到android/app根目录下
-
在gradle.properties文件下增加常量标识
-
android > app > build.gradle 下面添加(修改)signingConfigs相关的配置
signingConfigs {
debug {
storeFile file(MYAPP_RELEASE_STORE_FILE)
storePassword MYAPP_RELEASE_STORE_PASSWORD
keyAlias MYAPP_RELEASE_KEY_ALIAS
keyPassword MYAPP_RELEASE_KEY_PASSWORD
}
release {
storeFile file(MYAPP_RELEASE_STORE_FILE)
storePassword MYAPP_RELEASE_STORE_PASSWORD
keyAlias MYAPP_RELEASE_KEY_ALIAS
keyPassword MYAPP_RELEASE_KEY_PASSWORD
}
}
buildTypes {
release {
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
signingConfig signingConfigs.release
debuggable false
jniDebuggable false
}
}
6、将第4步下载好的SDK包中faceplatform库、faceplatform-ui库Copy 到工程根目录
-
修改faceplatform库里面的build.gradle的dependencies一下,不然后面会报错
因为这个项目用的RN框架比较老(0.46),所以用的
compile ('com.android.support:appcompat-v7:27.0.1')
正常可换成
implementation com.android.support:appcompat-v7:27.0.1
后面的版本号根据自己项目的实际情况更换 -
在build.gradle引人faceplatform-ui库工程
compile project(path:':faceplatform-ui')
- Setting.gradle中include faceplatfrom-ui和facepaltfrom
include ':faceplatform' , ':faceplatform-ui'
- 在AndroidManifest.xml文件的标签下配置权限,Feature 声明:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<!-- 权限级别: dangerous -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 权限级别: normal -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- 需要使用Feature -->
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.front"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.flash"
android:required="false" />
<Application>
<!-- 活体图像采集界面 -->
<activity
android:name="com.facetest.baiduface.faceactivity.FaceLivenessExpActivity"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:theme="@style/Theme_NoTitle" />
<!-- 人脸跟踪采集界面 -->
<activity
android:name="com.facetest.baiduface.faceactivity.FaceDetectExpActivity"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:theme="@style/Theme_NoTitle" />
</Application>
7、替换xml文件
以下xml文件,从react-native-baidu-face项目或者下载下来的安装SDK工程取都可以
- 将 react-native-baidu-face项目里的android/app/src/main/res/values/styles.xml 文件替换自己工程的styles.xml
- 将 react-native-baidu-face项目里的android/app/src/main/res/layout/widget_face_dialog.xml、activity_settings.xml 复制到自己工程 layout 文件夹下
8、配置MainApplication.java
package com.facetest;
import android.app.Application;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import com.facetest.baiduface.module.BaiduFacePackage;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
private static MainApplication mainApplication;
private static final BaiduFacePackage baiduFacePackage = new BaiduFacePackage(); // 创建package实例
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
baiduFacePackage //注册 package
);
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
mainApplication = this;
SoLoader.init(this, /* native exopackage */ false);
}
public static Application getApplication() {
return mainApplication;
}
/**
* 获取人脸识别package实例
*/
public static BaiduFacePackage getBaiduFacePackage() {
return baiduFacePackage;
}
}
9、React Native 使用
- 引入平台module
const FaceCheckHelper = Platform.select({
android: ()=> NativeModules.PushFaceViewControllerModule,
ios: ()=> NativeModules.RNIOSExportJsToReact
})();
const NativeModule = new NativeEventEmitter(FaceCheckHelper);
- 启动采集界面
liveness = async () => {
// 注意:调用之前需要判断是否开启了相机权限,没开会导致闪退
let obj = {
//质量校验设置
'quality': {
'minFaceSize': 200,// 设置最小检测人脸阈值 默认是200
'cropFaceSizeWidth': 400,// 设置截取人脸图片大小 默认是 400
'occluThreshold': 0.5,// 设置人脸遮挡阀值 默认是 0.5
'illumThreshold': 40,// 设置亮度阀值 默认是 40
'blurThreshold': 0.7,// 设置图像模糊阀值 默认是 0.7
'EulurAngleThrPitch': 10,// 设置头部姿态角度 默认是 10
'EulurAngleThrYaw': 10,// 设置头部姿态角度 默认是 10
'EulurAngleThrRoll': 10,// 设置头部姿态角度 默认是 10
'isCheckQuality': true,// 设置是否进行人脸图片质量检测 默认是 true
'conditionTimeout': 10,// 设置超时时间 默认是 10
'notFaceThreshold': 0.6,// 设置人脸检测精度阀值 默认是0.6
'maxCropImageNum': 1,// 设置照片采集张数 默认是 1
},
'liveActionArray': [
0, //眨眨眼
1, //张张嘴
// 2, //向右摇头
// 3, //向左摇头
// 4, //抬头
// 5, //低头
// 6, //摇头
], //活体动作列表
'order': true,//是否按顺序进行活体动作
'sound': true, // 提示音,默认不开启
};
FaceCheckHelper.openPushFaceViewController(obj);
}
- 注册监听,接收采集结果(收集结果为base64图片格式)
componentDidMount() {
NativeModule.addListener('FaceCheckHelper', (data) => this.faceCheckCallback(data));
}
/**
* 人脸检测结果
*/
faceCheckCallback(data) {
this.setState({
text: Object.keys(data)
});
if (data.remindCode == 0){
let imagesArray = [];
let imagesName = Object.keys(data.images); // bestImage liveEye liveYaw liveMouth yawRight yawLeft pitchUp pitchDown
imagesName.map((info,index) =>{
imagesArray.push(
<View key={index} style={{margin:50}}>
<Image
style={{width:180, height: 320, backgroundColor:'red'}}
source={{uri:'data:image/jpg;base64,'+ data.images[info]}}/>
<Text>{info}</Text>
</View>
)
})
this.setState({imagesArray})
} else if (data.remindCode == 36) {
alert('采集超时');
}
}
10、接入安卓遇到的问题
- react-native-baidu-face项目里的baiduface文件夹里的文件需要修改导入包的路径,需要修改为自己项目的路径,不然项目无法运行
- 接入完成后运行项目闪退
解决方法:
修改baiduface文件夹中BaiduFacepackage文件中的createJSModules方法,之前是return null;,改为
return Collections.emptyList();
问题原因:因为我运行的这个项目RN版本为0.46,而我们参考的封装模块版本是大于0.47的,在0.47以上版本中已经移除createJSModules方法,单0.46中并没有,所以导致闪退。