这篇文章仅仅是为了记录过程,方便下次快速集成使用,不做深究技术讨论
百度的人脸识别地址:
人脸识别_人脸识别_准确率99.99%_免费试用-百度AI开放平台
其次有几个注意事项,百度默认的demo是只支持竖屏的设备,手机或者平板。但是不支持模拟器的,所以不要在模拟器上试运行了。
话不多说,开始集成步骤:
一、注册应用获取环境
1.先打开上面的网址后,选择立即使用,登录上去后,先注册个应用
2. 添加一个授权设备,本地化部署-离线识别sdk-添加序列号
3.当你创建好一个单设备后,就会有两种激活方式,一个是在线激活,一个是离线激活。为了方便我使用在线激活,点击后,在设备上输入激活码即可激活。
4.我这里建议你无论做哪个业务的人脸识别,都去这里下载官方demo
这样你下载的demo是比较全的,既有激活代码(离线激活,在线激活,应用激活),还有闸机,考勤,支付,金融,人证核验,驾驶行为分析,注意力检测,属性八大模式,几乎可以针对各种业务场景了。此外还有人脸注册和人脸库管理两块的代码,可以说是很齐全了,UI也还不错,可以直接CV抠代码。
界面如下:?
非核心的代码都是很容易懂得,可以结合界面看代码。
二、融合代码到现有项目
1.集成环境
首先集成module? ? facelibray,无论你是哪个场景,这个是最基本的,比如导入。
?导入方式:
1. 拷贝示例代码中的lib下的文件到你的app下的lib里
2.在app下的build.gradle下添加如下代码
3.拷贝facelibray到项目工程下
4.修改settings.gradle如下
5.在app下的build.gradle下添加如下代码
?这样主module和lib都搞定了。接下来就是看你的需要了。
示例demo中有这些library
- attendancelibrary 考勤模块
- attrbutelibrary 属性模块
- drivermonitorlibrary 驾驶行为模块
- financelibrary 金融模块
- gatelibrary 闸机模块
- gazelibrary 注意力模块
- identifylibrary 认证核验模块
- paymentlibrary 支付模块
- registerlibrary 人脸注册和人脸管理模块
依据需要进行依赖,依赖步骤如上的主模块是一样的
?三、在线激活的代码如下 startActivity:
private void initLicense() {
FaceSDKManager.getInstance().init(mContext, new SdkInitListener() {
@Override
public void initStart() {
}
public void initLicenseSuccess() {
TimerTask task = new TimerTask() {
@Override
public void run() {
/**
*要执行的操作
*/
startActivity(new Intent(mContext, MainActivity.class));
finish();
}
};
Timer timer = new Timer();
timer.schedule(task, 2000);
}
@Override
public void initLicenseFail(int errorCode, String msg) {
TimerTask task = new TimerTask() {
@Override
public void run() {
/**
*要执行的操作
*/
startActivity(new Intent(mContext, ActivitionActivity.class));
finish();
}
};
Timer timer = new Timer();
timer.schedule(task, 2000);
}
@Override
public void initModelSuccess() {
}
@Override
public void initModelFail(int errorCode, String msg) {
}
});
}
其中的init就是从本地sp中获取激活码,如果没有就跳转到激活页面。这个比较简单就不多说了
四、激活进入自己的主页面后,最好初始化下摄像头
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mContext = this;
initView();
initRGBCheck();
}
private void initRGBCheck(){
if (isSetCameraId()){
return;
}
int mCameraNum = Camera.getNumberOfCameras();
ToastUtils.toast(mContext,mCameraNum+"个");
if (mCameraNum > 1){
try {
mCamera = new Camera[mCameraNum];
previewTextures = new PreviewTexture[mCameraNum];
mCamera[0] = Camera.open(0);
previewTextures[0] = new PreviewTexture(this, checkRBGTexture);
previewTextures[0].setCamera(mCamera[0], PREFER_WIDTH, PREFER_HEIGHT);
mCamera[0].setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
int check = StreamUtil.checkNirRgb(data, PREFER_WIDTH, PREFER_HEIGHT);
if (check == 1){
setRgbCameraId(0);
}
release(0);
}
});
}catch (Exception e){
e.printStackTrace();
}
try {
mCamera[1] = Camera.open(1);
previewTextures[1] = new PreviewTexture(this, checkNIRTexture);
previewTextures[1].setCamera(mCamera[1], PREFER_WIDTH, PREFER_HEIGHT);
mCamera[1].setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
int check = StreamUtil.checkNirRgb(data, PREFER_WIDTH, PREFER_HEIGHT);
if (check == 1){
setRgbCameraId(1);
}
release(1);
}
});
}catch (Exception e){
e.printStackTrace();
}
} else {
setRgbCameraId(0);
}
}
private void setRgbCameraId(int index){
com.baidu.idl.main.facesdk.attendancelibrary.model.SingleBaseConfig.getBaseConfig().setRBGCameraId(index);
com.baidu.idl.main.facesdk.registerlibrary.user.model.SingleBaseConfig.getBaseConfig().setRBGCameraId(index);
AttendanceConfigUtils.modityJson();
RegisterConfigUtils.modityJson();
}
private boolean isSetCameraId(){
if (com.baidu.idl.main.facesdk.attendancelibrary.
model.SingleBaseConfig.getBaseConfig().getRBGCameraId() == -1 ||
com.baidu.idl.main.facesdk.registerlibrary.user.model.
SingleBaseConfig.getBaseConfig().getRBGCameraId() == -1){
return false;
}else {
return true;
}
}
这些代码是它demo里就有可以拷贝。
五、跳转到对应功能页面
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.home_checkRl:
mLiveType = com.baidu.idl.main.facesdk.attendancelibrary.model.SingleBaseConfig.getBaseConfig().getType();
// 考勤模块
judgeLiveType(mLiveType,
FaceRGBAttendanceActivity.class,
FaceNIRAttendanceActivity.class,
FaceDepthAttendanceActivity.class,
FaceRGBNirDepthAttendanceActivity.class);
break;
case R.id.relative_register: // 人脸注册
dismissPopupWindow();
SharedPreferences sharedPreferences = this.getSharedPreferences("type", MODE_PRIVATE);
mLiveType = sharedPreferences.getInt("type", 0);
com.baidu.idl.main.facesdk.registerlibrary.user.manager.FaceSDKManager.getInstance().setActiveLog();
judgeLiveType(mLiveType, FaceRegisterNewActivity.class, FaceRegisterNewNIRActivity.class,
FaceRegisterNewDepthActivity.class, FaceRegisterNewRgbNirDepthActivity.class);
break;
}
}
private void judgeLiveType(int type, Class<?> rgbCls, Class<?> nirCls, Class<?> depthCls, Class<?> rndCls) {
switch (type) {
case 0: { // 不使用活体
startActivity(new Intent(HomeActivity.this, rgbCls));
break;
}
case 1: { // RGB活体
startActivity(new Intent(HomeActivity.this, rgbCls));
break;
}
case 2: { // NIR活体
startActivity(new Intent(HomeActivity.this, nirCls));
break;
}
case 3: { // 深度活体
int cameraType = SingleBaseConfig.getBaseConfig().getCameraType();
judgeCameraType(cameraType, depthCls);
break;
}
case 4: { // rgb+nir+depth活体
int cameraType = SingleBaseConfig.getBaseConfig().getCameraType();
judgeCameraType(cameraType, rndCls);
}
}
}
private void judgeCameraType(int cameraType, Class<?> depthCls) {
switch (cameraType) {
case 1: { // pro
startActivity(new Intent(HomeActivity.this, depthCls));
break;
}
case 2: { // atlas
startActivity(new Intent(HomeActivity.this, depthCls));
break;
}
case 6: { // Pico
// startActivity(new Intent(HomeActivity.this,
// PicoFaceDepthLivenessActivity.class));
break;
}
default:
startActivity(new Intent(HomeActivity.this, depthCls));
break;
}
}
这是点击自己的按钮跳转到各个场景页面的方式。
记得加上权限
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.hardware.camera.autofocus" />
<uses-permission
android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="true" />
<uses-feature
android:name="android.hardware.camera.front"
android:required="true" />
<uses-feature
android:name="android.hardware.camera.front.autofocus"
android:required="true" />
横屏处理问题:
1.人脸注册:
我是到FaceRegisterNewActivity下,对圆形采相控件进行动态根据屏幕大小设置宽高。
其次因为百度采集人像,还没反应过来就采集成功了,于是我加了个倒计时控件,其实就是个普通文本控件在采相控件的中间。然后用timer+timerTask+handler搞定的
private void initView() {
tvNum=findViewById(R.id.tv_num); //这是我自己加的倒计时控件,在镜头中心
mAutoTexturePreviewView = findViewById(R.id.auto_camera_preview_view);
mFaceRoundProView = findViewById(R.id.round_view);
// 屏幕的宽
int displayWidth = DensityUtils.getDisplayWidth(FaceRegisterNewActivity.this);
// 屏幕的高
int displayHeight = DensityUtils.getDisplayHeight(FaceRegisterNewActivity.this);
int min=Math.min(displayWidth,displayHeight);
ViewGroup.LayoutParams lp1 = mAutoTexturePreviewView.getLayoutParams();
lp1.width=min-DensityUtils.dip2px(FaceRegisterNewActivity.this,30);
lp1.height=min-DensityUtils.dip2px(FaceRegisterNewActivity.this,30);
mAutoTexturePreviewView.setLayoutParams(lp1);
ViewGroup.LayoutParams lp2 = mFaceRoundProView.getLayoutParams();
lp2.width=min-DensityUtils.dip2px(FaceRegisterNewActivity.this,30);
lp2.height=min-DensityUtils.dip2px(FaceRegisterNewActivity.this,30);
mAutoTexturePreviewView.setLayoutParams(lp2);
ViewGroup.LayoutParams lp3 = tvNum.getLayoutParams();
lp3.width=min-DensityUtils.dip2px(FaceRegisterNewActivity.this,30);
lp3.height=min-DensityUtils.dip2px(FaceRegisterNewActivity.this,30);
mAutoTexturePreviewView.setLayoutParams(lp3);
tvNum.setText("3");
tvNum.setVisibility(View.VISIBLE);
....
}
2.业务场景:
到各个场景里,例如这里是考勤的页面,注释掉下面的话,就可以横屏全部了,剩下的无非是调节下小控件的宽高
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
initListener();
FaceSDKManager.getInstance().initDataBases(this);
setContentView(R.layout.activity_face_rgb_attendancelibrary);
initView();
// 屏幕的宽
// int displayWidth = DensityUtils.getDisplayWidth(mContext);
// 屏幕的高
// int displayHeight = DensityUtils.getDisplayHeight(mContext);
// 当屏幕的宽大于屏幕宽时
// if (displayHeight < displayWidth) {
// // 获取高
// int height = displayHeight;
// // 获取宽
// int width = (int) (displayHeight * ((9.0f / 16.0f)));
// // 设置布局的宽和高
// FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(width, height);
// // 设置布局居中
// params.gravity = Gravity.CENTER;
// relativeLayout.setLayoutParams(params);
// }
}
好了,先记录到这,这些基本上可以做到,安卓设备离线情况下,在客户端进行人脸注册,管理人脸库和考勤了
本人个人原创,如有雷同,纯属巧合,或者与本人联系,做改动。请转载或者CV组合标明出处,谢谢!(如有疑问或错误欢迎指出,本人QQ:752231513)
|