,,Android基于虹软(ArcSoft)实现人脸识别

,,Android基于虹软(ArcSoft)实现人脸识别

人工智能时代正在快速到来,其中人脸识别是一项热门技术,在国内的应用也越来越多,比如刷脸打卡、刷脸APP、身份识别、人脸门禁等。本文将介绍基于虹软的Android人脸识别演示。来和边肖一起学习吧。

1.在虹软的开发者中心创建自己的应用,记录APP_ID和SDK_KEY,后面会用到。创建完成后,您可以下载SDK。

2.下载后可以参考和学习SDK包中的开发说明文档和代码。以下是开发说明文档中SDK包结构的截图。

3.创建一个空项目并复制。jar文件和。所以把SDK包中的文件放到项目的下面的包中。接下来的配置很重要。一个不处理,就是一个大bug。

4.“build.gradle in app”的第一个红框原本属于androidx,与支持不兼容,需要更改。所以整个项目中使用androidx的地方需要改变。第二个红框是ndk。添加此内容以查找。所以文件刚复制进来。第三个红框也应该更改如下。下面的依赖应该注意改变androidx的。

5.“整个项目中的build.gradle”记得添加jcenter()。

6.gradle.properties里可能有androidx的东西,也要删掉。

7.在AndroidManifest.xml中添加权限申请,并将其添加到。

清单:

uses-permission Android:name=' Android . permission . camera '/

uses-permission Android:name=' Android . permission . read _ PHONE _ STATE '/

uses-permission Android:name=' Android . permission . internet '/

uses-permission Android:name=' Android . permission . read _ EXTERNAL _ STORAGE '/

uses-permission Android:name=' Android . permission . write _ EXTERNAL _ STORAGE '/

提供商:

供应者

Android:name=' Android . support . v4 . content . file provider '

Android:authorities=' $ { application id }。'提供商'

android:exported='false '

Android:grantUriPermissions=' true '

元数据

Android:name=' Android . support . file _ PROVIDER _ PATHS '

Android:resource=' @ XML/provider _ paths '/

/提供商

添加后,在res下创建一个xml包,并在其中添加一个provider_paths.xml文件,代码如下:

?xml版本='1.0 '编码='utf-8 '?

路径xmlns:Android=' http://schemas . Android . com/apk/RES/Android '

外部路径名='外部文件'路径=','/

根路径

name='根路径'

路径=“.”/

/路径

8.从SDK包中引入下面的函数包模块和BaseActivity,将常用包下常量中的APP_ID和SDK_KEY改为刚才记录的内容。

9.创建三个acvitity,一个是主界面,一个是人脸数据库的管理界面,一个是人脸识别功能界面。

10.布局包下需要引入以下五个布局文件。

11.主界面的主要功能是激活权限,连接动态库,激活引擎。我修改了onCreate()和Util包下ConfigUtil.class的代码,让它自动激活,自动修改为全方位人脸检测(其他选项好像无法实现人脸识别)。下面是激活引擎的代码。

公共void activeEngine(最终视图视图){

如果(!libraryExists) {

Toast.makeText(this,'找不到库文件!',吐司。LENGTH_SHORT)。show();

返回;

}

如果(!check PERMISSIONS(NEEDED _ PERMISSIONS)){

activity compat . REQUEST PERMISSIONS(this,NEEDED_PERMISSIONS,ACTION _ REQUEST _ PERMISSIONS);

返回;

}

如果(查看!=null) {

view . set clickable(false);

}

observable . create(new ObservableOnSubscribeInteger(){

@覆盖

公共void subscribe(observablemitterinteger发射器){

int active code=face engine . active online(main activity . this,常量。APP_ID,常量。SDK _ KEY);

emitter . on next(active code);

}

})。subscribeOn(Schedulers.io())。观察者离子(机器人调度程序。主线程())。subscribe(new observer integer(){

@覆盖

公共订阅无效(一次性d) {

}

@覆盖

公共void on next(整数活动代码){

if (activeCode==ErrorInfo .莫){

吐司。制作文本(主要活动。“这,”激活成功!',吐司. LENGTH_SHORT)。show();

} else if (activeCode==ErrorInfo .MERR ASF已经_激活){

吐司。制作文本(主要活动。“这,”已激活!',吐司. LENGTH_SHORT)。show();

}否则{

吐司。制作文本(主要活动。“这,”激活失败!',吐司. LENGTH_SHORT)。show();

}

如果(查看!=null) {

查看。设置clickable(真);

}

active fileinfo active fileinfo=new active fileinfo();

}

@覆盖

public void onError(Throwable e) {

吐司。制作文本(主要活动。这个,e.getMessage(),Toast .LENGTH_SHORT).show();

如果(查看!=null) {

查看。设置clickable(真);

}

}

@覆盖

公共void onComplete() {

}

});

}

12、人脸识别界面是最复杂的。其中不仅有人脸识别的功能,还有注册人脸和活体检测的功能。

通过手机自带的摄像头来实现人脸识别和活体检测的逻辑:

private void initCamera() {

显示指标metrics=新显示指标();

getWindowManager().getDefaultDisplay().getMetrics(度量);

最终人脸监听器人脸监听器=新人脸监听器(){

@覆盖

公共失效(例外e) {

Log.e(TAG,' on fail:' e . getmessage());

}

//请求神父的回调

@覆盖

public void onFaceFeatureInfoGet(@ Nullable final face feature face feature,final Integer requestId,final Integer errorCode) {

//FR成功

如果(faceFeature!=null) {

//Log.i(TAG,' on preview:fr end=' system。当前时间毫秒()'曲目id='请求id ');

整数活性=活性图。get(请求id);

//不做活体检测的情况,直接搜索

如果(!livenessDetect) {

searchFace(faceFeature,请求id);

}

//活体检测通过,搜索特征

else if(活跃度!=空活性==LivenessInfo .活着){

searchFace(faceFeature,请求id);

}

//活体检测未出结果,或者非活体,延迟执行该函数

否则{

if(requestfeaturestatusmap。包含密钥(请求id)){

可观察的。定时器(等待活动间隔,时间单位。毫秒)。订阅(新观察者Long() {

一次性的一次性的;

@覆盖

公共订阅无效(一次性d) {

一次性=d;

getfeaturedelayeddisposables。添加(一次性);

}

@覆盖

公共void onNext(Long aLong) {

onFaceFeatureInfoGet(人脸特征,requestId,错误代码);

}

@覆盖

public void onError(Throwable e) {

}

@覆盖

公共void onComplete() {

getfeaturedelayeddisposables。移除(一次性);

}

});

}

}

}

//特征提取失败

否则{

if(increasesandgetvalue(extractErrorRetryMap,requestId) MAX_RETRY_TIME) {

extracterrorretrymap。put(请求id,0);

字符串味精

//传入的FaceInfo在指定的图像上无法解析人脸,此处使用的是RGB人脸数据,一般是人脸模糊

if (errorCode!=空错误代码==错误信息FSDK MERR面部特征_低_置信度_级别){

msg='人脸置信度低!';

}否则{

msg=' extract code:'错误代码;

}

faceHelper.setName(requestId,'未通过!');

//在尝试最大次数后,特征提取仍然失败,则认为识别未通过

requestfeaturestatusmap。put(请求id,RequestFeatureStatus .失败);

retryRecognizeDelayed(请求id);

}否则{

requestfeaturestatusmap。put(请求id,RequestFeatureStatus .TO _ RETRY);

}

}

}

@覆盖

public void onFaceLivenessInfoGet(@ Nullable LivenessInfo LivenessInfo,final Integer requestId,Integer errorCode) {

if (livenessInfo!=null) {

int活性=活性信息。get liveness();

livenessMap.put(requestId,liveness);

//非活体,重试

if (liveness==LivenessInfo .NOT_ALIVE) {

faceHelper.setName(requestId,'未通过!非活体!');

//延迟失败重试间隔后,将该人脸状态置为未知,帧回调处理时会重新进行活体检测

retrylivenesdetectdelayed(请求id);

}

}否则{

if(increasesandgetvalue(livenesserrretrymap,requestId) MAX_RETRY_TIME) {

livenesserrretrymap。put(请求id,0);

字符串味精

//传入的FaceInfo在指定的图像上无法解析人脸,此处使用的是RGB人脸数据,一般是人脸模糊

if (errorCode!=空错误代码==错误信息FSDK MERR面部特征_低_置信度_级别){

msg='人脸置信度低!';

}否则{

msg=' process code:'错误代码;

}

faceHelper.setName(requestId,'未通过!');

retrylivenesdetectdelayed(请求id);

}否则{

livenessMap.put(requestId,LivenessInfo .未知);

}

}

}

};

摄像机监听器摄像机监听器=新摄像机监听器(){

@覆盖

公共打开的相机上的void(Camera Camera,int cameraId,int displayOrientation,boolean isMirror) {

相机size lastPreviewSize=previewSize;

预览尺寸=相机。获取参数().getPreviewSize();

绘图助手=新绘图助手(预览大小。width,previewSize.height,previewView.getWidth(),previewView.getHeight(),displayOrientation

,cameraId,isMirror,false,false);

Log.i(TAG,' onCameraOpened:' draw helper。tostring());

//切换相机的时候可能会导致预览尺寸发生变化

if (faceHelper==null ||

lastPreviewSize==null ||

lastPreviewSize.width!=预览大小。宽度| | lastpreviewsize。身高!=previewSize.height) {

整数trackedFaceCount=null

//记录切换时的人脸序号

如果(faceHelper!=null) {

trackedface count=face helper。gettrackedface count();

脸帮手。发布();

}

faceHelper=新的faceHelper .构建器()。弗泰因(弗泰因)。法语(法语)。氟引擎(氟引擎)。frQueueSize(最大检测数量)。flQueueSize(最大检测数量)。预览大小(预览大小)。面部监听器(面部监听器)。跟踪的面部计数(跟踪的面部计数==null?配置实用程序。gettrackedface计数(faceregisterandrecognise。这个。getapplicationcontext()):tracked face count)。build();

}

}

@覆盖

预览时公共无效(最终字节[]nv21,相机相机){

if (faceRectView!=null) {

facerectview。清除faceinfo();

}

list face previewinfo face previewfolist=face helper。onpreviewframe(nv21);

if (facePreviewInfoList!=null faceRectView!=null drawHelper!=null) {

drawPreviewInfo(facepreviewfolist);

}

registerFace(nv21,facepreviewfolist);

清左脸(facepreviewfolist);

if (facePreviewInfoList!=null facepreviewfolist。size()0 previewSize!=null) {

for(int I=0;我面对预览列表。size();i ) {

整数status=requestfeaturestatusmap。get(face previewinfolist。get(I)).getTrackId());

/**

* 在活体检测开启,在人脸识别状态不为成功或人脸活体状态不为处理中(分析)且不为处理完成(活着、不活着)时重新进行活体检测

*/

if(livenessDetect(status==null | | status!=RequestFeatureStatus .成功)){

整数活性=活性图。get(face previewinfolist。get(I)).getTrackId());

如果(活跃度==空

||(活跃度!=LivenessInfo .活蹦乱跳!=LivenessInfo .不活着活跃度!=RequestLivenessStatus .正在分析){

活跃度图。put(facepreviewfolist。get(I)).getTrackId(),RequestLivenessStatus .正在分析);

脸帮手。requestfaceliveness(nv21,facepreviewfolist。get(I)).getFaceInfo(),previewSize.width,previewSize.height,FaceEngine .CP_PAF_NV21,facepreviewfolist。得到(I).getTrackId(),LivenessType .RGB);

}

}

/**

* 对于每个人脸,若状态为空或者为失败,则请求特征提取(可根据需要添加其他判断以限制特征提取次数),

* 特征提取回传的人脸特征结果在{ @ link face listener # onFaceFeatureInfoGet(face feature,Integer,Integer)}中回传

*/

如果(状态==空

|| status==RequestFeatureStatus .TO_RETRY) {

requestfeaturestatusmap。put(facepreviewfolist。get(I)).getTrackId(),RequestFeatureStatus .正在搜索);

脸帮手。请求面特征(nv21,facepreviewfolist。get(I)).getFaceInfo(),previewSize.width,previewSize.height,FaceEngine .CP_PAF_NV21,facepreviewfolist。得到(I).getTrackId());

//Log.i(TAG,' on preview:fr start=' system。当前时间毫秒()' track id=' facepreviewfolist。get(I)).getTrackedFaceCount());

}

}

}

}

@覆盖

public void onCameraClosed() {

Log.i(标记,' onCameraClosed:');

}

@覆盖

公共void onCameraError(异常e) {

Log.i(TAG,' onCameraError:' e . getmessage());

}

@覆盖

public void oncameraconconfigurationchanged(int camera id,int displayOrientation) {

if (drawHelper!=null) {

绘图助手。setcameradidisplayorientation(显示方向);

}

Log.i(TAG,' onCameraConfigurationChanged:' cameraID ' ' display orientation ');

}

};

cameraHelper=新cameraHelper .构建器()。预览视图大小(新的点(previewView.getMeasuredWidth()),previewView.getMeasuredHeight())。rotation(getWindowManager().getDefaultDisplay().getRotation())。specificCameraId(rgbCameraID!=null?rgbCameraID:相机100 . CameraInfo。相机_正面_正面)。isMirror(假)。预览(预览视图)。摄像师。build();

摄像助手。init();

摄像助手。start();

}

注册人脸的逻辑:

private void register face(final byte[]nv21,final list face previewinfo face previewfolist){

if(REGISTER STATUS==REGISTER _ STATUS _ READY face previewinfolist!=null face previewinfolist。size()0){

寄存器状态=寄存器_状态_处理;

可观察的。create(new ObservableOnSubscribeBoolean(){

@覆盖

公共void subscribe(observablemitterboolean发射器){

布尔成功=faceserver。getinstance()registernv 21(faceregisterandrecognise。this,nv21.clone(),previewSize.width,previewSize.height,

facepreviewfolist。获取(0).getFaceInfo(),'已注册'的面部助手。gettrackedfacecount());

emitter.onNext(成功);

}

})。订阅(计划程序。计算())。观察者离子(机器人调度程序。主线程())。subscribe(new ObserverBoolean(){

@覆盖

公共订阅无效(一次性d) {

}

@覆盖

公共void onNext(布尔成功){

字符串结果=成功?注册成功!":'注册失败!';

showToast(结果);

寄存器状态=寄存器状态完成;

}

@覆盖

public void onError(Throwable e) {

e。printstacktrace();

showToast('注册失败!');

寄存器状态=寄存器状态完成;

}

@覆盖

公共void onComplete() {

}

});

}

}

13、人脸库的管理界面。

公共类FaceLibs扩展基础活动{

私人执行服务执行服务;

私有文本视图文本视图

private TextView tvNotificationRegisterResult;

进度对话框进度对话框=空;

private static final int ACTION _ REQUEST _ PERMISSIONS=0x 001;

私有静态字符串[]需要_权限=新字符串[]{

显化。许可。阅读_外部_存储,

清单。权限。写_外部_存储

};

@覆盖

受保护的void onCreate(Bundle saved instancestate){

超级棒。oncreate(savedInstanceState);

setContentView(r . layout。activity _ face _ libs);

getWindow().addFlags(WindowManager .布局参数。FLAG _ KEEP _ SCREEN _ ON);

执行者服务=执行者。newsinglethreadexecutor();

tvNotificationRegisterResult=findViewById(r . id。通知_注册_结果);

进度对话框=新进度对话框(this);

int faceLibNum=faceserver。getinstance().get face number(this);

textView=findViewById(r . id。号);

文本视图。settext(faceLibNum ' ');

FaceServer.getInstance().初始化(这个);

}

@覆盖

受保护的void onDestroy() {

if (executorService!=null!executorService.isShutdown()) {

执行服务。立即关闭();

}

if (progressDialog!=空进度对话框。正在显示()){

进度对话框。dissolve();

}

FaceServer.getInstance().unInit();

超级棒。on destroy();

}

@覆盖

void afterRequestPermission(int请求代码,布尔值isAllGranted) {

}

公共空心净空面(视图视图){

int faceNum=faceserver。getinstance().get face number(this);

if (faceNum==0) {

showToast('人脸库已空!');

}否则{

报警对话框=新报警对话框。建筑商(本)。setTitle('通知)。setMessage('确定要删除' faceNum '个人脸吗?')。setPositiveButton('确定,新的对话界面OnClickListener() {

@覆盖

public void onClick(dialog interface dialog,int which) {

int deleteCount=FaceServer.getI

nstance().clearAllFaces(FaceLibs.this); showToast(deleteCount + "个人脸已删除!"); textView.setText("0"); } }) .setNegativeButton("取消", null) .create(); dialog.show(); } } }

14、以上就是大体的介绍,还有一些小的细枝末节需要同志们动手实操一下。下面就来看看实现的效果。

主界面:

注册成功并通过识别:

通过手机照片识别出不是活体:

清理人脸库:

以上就是Android基于虹软(ArcSoft)实现人脸识别的详细内容,更多关于Android人脸识别的资料请关注我们其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • windowsandroid手机版下载,windowsandroid安装apk
  • windowsandroid手机版下载,windowsandroid安装apk,WindowsAndroid 安装教程详解
  • android调用webview方法,androidwebview是什么,Android 中 WebView 的基本用法详解
  • android传感器高级编程,Android传感器,Android编程之光线传感器用法详解
  • android.app.Dialog,android自定义dialog对话框,Android开发笔记之-Dialog的使用详解
  • android 图片视频轮播框架,androidlayout轮播图,Android实现炫酷轮播图效果
  • android里的viewpager,安卓自定义view流程,Android自定义引导玩转ViewPager的方法详解
  • android里的viewpager,android viewpager详解
  • android里的viewpager,android viewpager详解,Android自定义超级炫酷的ViewPage指示器
  • android调用webview方法,androidwebview是什么
  • android设置控件宽度,android获取屏幕宽度和高度
  • android设置控件宽度,android获取屏幕宽度和高度,Android中获取控件宽高的4种方法集合
  • android蓝牙开发的基本流程,安卓蓝牙app开发教程
  • android蓝牙开发的基本流程,安卓蓝牙app开发教程,android蓝牙简单开发示例教程
  • android菜单栏,android菜单控件
  • 留言与评论(共有 条评论)
       
    验证码: