Android开发基于ArcSoft实现人脸识别的方法是什么
发表于:2025-02-06 作者:千家信息网编辑
千家信息网最后更新 2025年02月06日,本篇内容主要讲解"Android开发基于ArcSoft实现人脸识别的方法是什么",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Android开发基于ArcS
千家信息网最后更新 2025年02月06日Android开发基于ArcSoft实现人脸识别的方法是什么
本篇内容主要讲解"Android开发基于ArcSoft实现人脸识别的方法是什么",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Android开发基于ArcSoft实现人脸识别的方法是什么"吧!
效果图
激活引擎
第一步配置APP_ID和SDK_KEY
int activeCode = FaceEngine.activeOnline( ChooseFunctionActivity.this, Param.APP_ID, Param.SDK_KEY);
public static final String APP_ID = "AwY6okHQHxtM92YRYSEqJQwb8cED5huPvYyMhK1w7BSo"; public static final String SDK_KEY = "AF8SaLYtP3ALsmaTR55y9UXaykBZjTtMt5gwCBkUGugh";
第二步:判断是否添加动态链接库(so文件与jar包)
private boolean checkSoFile(String[] libraries) { File dir = new File(getApplicationInfo().nativeLibraryDir); File[] files = dir.listFiles(); if (files == null || files.length == 0) { return false; } ListlibraryNameList = new ArrayList<>(); for (File file : files) { libraryNameList.add(file.getName()); } boolean exists = true; for (String library : libraries) { exists &= libraryNameList.contains(library); } return exists; }
第三步:判断是否申明所有权限
protected boolean CheckPermissions(String[] neededPermissions) { if (neededPermissions == null || neededPermissions.length == 0) { return true; } boolean allGranted = true; for (String neededPermission : neededPermissions) { allGranted &= ContextCompat.checkSelfPermission(this, neededPermission) == PackageManager.PERMISSION_GRANTED; } return allGranted; }
激活引擎代码如下
public void ActivationDevice(final View view) { if (!libraryExists) { ShowToast(getString(R.string.library_not_found)); return; } if (!CheckPermissions(NEEDED_PERMISSIONS)) { ActivityCompat.requestPermissions(this, NEEDED_PERMISSIONS, ACTION_REQUEST_PERMISSIONS); return; } if (view != null) { view.setClickable(false); } Observable.create( new ObservableOnSubscribe() { @Override public void subscribe(ObservableEmitter emitter) { RuntimeABI runtimeABI = FaceEngine.getRuntimeABI(); Log.i(TAG, "subscribe: getRuntimeABI() " + runtimeABI); long start = System.currentTimeMillis(); int activeCode = FaceEngine.activeOnline( ChooseFunctionActivity.this, Param.APP_ID, Param.SDK_KEY); Log.i(TAG, "subscribe cost: " + (System.currentTimeMillis() - start)); emitter.onNext(activeCode); } }) .subscribeOn( Schedulers.io()) .observeOn( AndroidSchedulers.mainThread()) .subscribe(new Observer () { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(Integer activeCode) { if (activeCode == ErrorInfo.MOK) { ShowToast(getString(R.string.activation_succeeded)); } else if (activeCode == ErrorInfo.MERR_ASF_ALREADY_ACTIVATED) { ShowToast(getString(R.string.already_activated)); } else { ShowToast(getString(R.string.active_failed, activeCode)); } if (view != null) { view.setClickable(true); } ActiveFileInfo activeFileInfo = new ActiveFileInfo(); int res = FaceEngine.getActiveFileInfo(ChooseFunctionActivity.this, activeFileInfo); if (res == ErrorInfo.MOK) { Log.i(TAG, activeFileInfo.toString()); } } @Override public void onError(Throwable e) { ShowToast(e.getMessage()); if (view != null) { view.setClickable(true); } } @Override public void onComplete() { } }); }
人脸比对 1:N
第一步:初始化本地人脸库
FaceServer.getInstance().init(this);
第二步:初始化引擎和相机
public void onGlobalLayout() { previewView.getViewTreeObserver().removeOnGlobalLayoutListener(this); if (!CheckPermissions(NEEDED_PERMISSIONS)) { ActivityCompat.requestPermissions(this, NEEDED_PERMISSIONS, ACTION_REQUEST_PERMISSIONS); } else { initEngine(); initCamera(); } }
第三步:初始化引擎
private void initEngine() { ftEngine = new FaceEngine(); ftInitCode = ftEngine.init(this, DetectMode.ASF_DETECT_MODE_VIDEO, ConfigUtil.getFtOrient(this), 16, MAX_DETECT_NUM, FaceEngine.ASF_FACE_DETECT); frEngine = new FaceEngine(); frInitCode = frEngine.init(this, DetectMode.ASF_DETECT_MODE_IMAGE, DetectFaceOrientPriority.ASF_OP_0_ONLY, 16, MAX_DETECT_NUM, FaceEngine.ASF_FACE_RECOGNITION); flEngine = new FaceEngine(); flInitCode = flEngine.init(this, DetectMode.ASF_DETECT_MODE_IMAGE, DetectFaceOrientPriority.ASF_OP_0_ONLY, 16, MAX_DETECT_NUM, FaceEngine.ASF_LIVENESS); Log.i(TAG, "initEngine: init: " + ftInitCode); if (ftInitCode != ErrorInfo.MOK) { String error = getString(R.string.specific_engine_init_failed, "ftEngine", ftInitCode); Log.i(TAG, "initEngine: " + error); ShowToast(error); } if (frInitCode != ErrorInfo.MOK) { String error = getString(R.string.specific_engine_init_failed, "frEngine", frInitCode); Log.i(TAG, "initEngine: " + error); ShowToast(error); } if (flInitCode != ErrorInfo.MOK) { String error = getString(R.string.specific_engine_init_failed, "flEngine", flInitCode); Log.i(TAG, "initEngine: " + error); ShowToast(error); } }
第四步:活体检测
private void initCamera() { DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); final FaceListener faceListener = new FaceListener() { @Override public void onFail(Exception e) { Log.e(TAG, "onFail: " + e.getMessage()); } //请求FR的回调 @Override public void onFaceFeatureInfoGet(@Nullable final FaceFeature faceFeature, final Integer requestId, final Integer errorCode) { //FR成功 if (faceFeature != null) {// Log.i(TAG, "onPreview: fr end = " + System.currentTimeMillis() + " trackId = " + requestId); Integer liveness = livenessMap.get(requestId); //不做活体检测的情况,直接搜索 if (!livenessDetect) { searchFace(faceFeature, requestId); } //活体检测通过,搜索特征 else if (liveness != null && liveness == LivenessInfo.ALIVE) { searchFace(faceFeature, requestId); } //活体检测未出结果,或者非活体,延迟执行该函数 else { if (requestFeatureStatusMap.containsKey(requestId)) { Observable.timer(WAIT_LIVENESS_INTERVAL, TimeUnit.MILLISECONDS) .subscribe(new Observer() { Disposable disposable; @Override public void onSubscribe(Disposable d) { disposable = d; getFeatureDelayedDisposables.add(disposable); } @Override public void onNext(Long aLong) { onFaceFeatureInfoGet(faceFeature, requestId, errorCode); } @Override public void onError(Throwable e) { } @Override public void onComplete() { getFeatureDelayedDisposables.remove(disposable); } }); } } } //特征提取失败 else { if (increaseAndGetValue(extractErrorRetryMap, requestId) > MAX_RETRY_TIME) { extractErrorRetryMap.put(requestId, 0); String msg; // 传入的FaceInfo在指定的图像上无法解析人脸,此处使用的是RGB人脸数据,一般是人脸模糊 if (errorCode != null && errorCode == ErrorInfo.MERR_FSDK_FACEFEATURE_LOW_CONFIDENCE_LEVEL) { msg = getString(R.string.low_confidence_level); } else { msg = "ExtractCode:" + errorCode; } faceHelper.setName(requestId, getString(R.string.recognize_failed_notice, msg)); // 在尝试最大次数后,特征提取仍然失败,则认为识别未通过 requestFeatureStatusMap.put(requestId, RequestFeatureStatus.FAILED); retryRecognizeDelayed(requestId); } else { requestFeatureStatusMap.put(requestId, RequestFeatureStatus.TO_RETRY); } } } @Override public void onFaceLivenessInfoGet(@Nullable LivenessInfo livenessInfo, final Integer requestId, Integer errorCode) { if (livenessInfo != null) { int liveness = livenessInfo.getLiveness(); livenessMap.put(requestId, liveness); // 非活体,重试 if (liveness == LivenessInfo.NOT_ALIVE) { faceHelper.setName(requestId, getString(R.string.recognize_failed_notice, "NOT_ALIVE")); // 延迟 FAIL_RETRY_INTERVAL 后,将该人脸状态置为UNKNOWN,帧回调处理时会重新进行活体检测 retryLivenessDetectDelayed(requestId); } } else { if (increaseAndGetValue(livenessErrorRetryMap, requestId) > MAX_RETRY_TIME) { livenessErrorRetryMap.put(requestId, 0); String msg; // 传入的FaceInfo在指定的图像上无法解析人脸,此处使用的是RGB人脸数据,一般是人脸模糊 if (errorCode != null && errorCode == ErrorInfo.MERR_FSDK_FACEFEATURE_LOW_CONFIDENCE_LEVEL) { msg = getString(R.string.low_confidence_level); } else { msg = "ProcessCode:" + errorCode; } faceHelper.setName(requestId, getString(R.string.recognize_failed_notice, msg)); retryLivenessDetectDelayed(requestId); } else { livenessMap.put(requestId, LivenessInfo.UNKNOWN); } } } }; CameraListener cameraListener = new CameraListener() { @Override public void onCameraOpened(Camera camera, int cameraId, int displayOrientation, boolean isMirror) { Camera.Size lastPreviewSize = previewSize; previewSize = camera.getParameters().getPreviewSize(); drawHelper = new DrawHelper(previewSize.width, previewSize.height, previewView.getWidth(), previewView.getHeight(), displayOrientation , cameraId, isMirror, false, false); Log.i(TAG, "onCameraOpened: " + drawHelper.toString()); // 切换相机的时候可能会导致预览尺寸发生变化 if (faceHelper == null || lastPreviewSize == null || lastPreviewSize.width != previewSize.width || lastPreviewSize.height != previewSize.height) { Integer trackedFaceCount = null; // 记录切换时的人脸序号 if (faceHelper != null) { trackedFaceCount = faceHelper.getTrackedFaceCount(); faceHelper.release(); } faceHelper = new FaceHelper.Builder() .ftEngine(ftEngine) .frEngine(frEngine) .flEngine(flEngine) .frQueueSize(MAX_DETECT_NUM) .flQueueSize(MAX_DETECT_NUM) .previewSize(previewSize) .faceListener(faceListener) .trackedFaceCount(trackedFaceCount == null ? ConfigUtil.getTrackedFaceCount(FaceComparison_RGB.this.getApplicationContext()) : trackedFaceCount) .build(); } } @Override public void onPreview(final byte[] nv21, Camera camera) { if (faceRectView != null) { faceRectView.clearFaceInfo(); } List facePreviewInfoList = faceHelper.onPreviewFrame(nv21); if (facePreviewInfoList != null && faceRectView != null && drawHelper != null) { drawPreviewInfo(facePreviewInfoList); } registerFace(nv21, facePreviewInfoList); clearLeftFace(facePreviewInfoList); if (facePreviewInfoList != null && facePreviewInfoList.size() > 0 && previewSize != null) { for (int i = 0; i < facePreviewInfoList.size(); i++) { Integer status = requestFeatureStatusMap.get(facePreviewInfoList.get(i).getTrackId()); /** * 在活体检测开启,在人脸识别状态不为成功或人脸活体状态不为处理中(ANALYZING)且不为处理完成(ALIVE、NOT_ALIVE)时重新进行活体检测 */ if (livenessDetect && (status == null || status != RequestFeatureStatus.SUCCEED)) { Integer liveness = livenessMap.get(facePreviewInfoList.get(i).getTrackId()); if (liveness == null || (liveness != LivenessInfo.ALIVE && liveness != LivenessInfo.NOT_ALIVE && liveness != RequestLivenessStatus.ANALYZING)) { livenessMap.put(facePreviewInfoList.get(i).getTrackId(), RequestLivenessStatus.ANALYZING); faceHelper.requestFaceLiveness(nv21, facePreviewInfoList.get(i).getFaceInfo(), previewSize.width, previewSize.height, FaceEngine.CP_PAF_NV21, facePreviewInfoList.get(i).getTrackId(), LivenessType.RGB); } } /** * 对于每个人脸,若状态为空或者为失败,则请求特征提取(可根据需要添加其他判断以限制特征提取次数), * 特征提取回传的人脸特征结果在{@link FaceListener#onFaceFeatureInfoGet(FaceFeature, Integer, Integer)}中回传 */ if (status == null || status == RequestFeatureStatus.TO_RETRY) { requestFeatureStatusMap.put(facePreviewInfoList.get(i).getTrackId(), RequestFeatureStatus.SEARCHING); faceHelper.requestFaceFeature(nv21, facePreviewInfoList.get(i).getFaceInfo(), previewSize.width, previewSize.height, FaceEngine.CP_PAF_NV21, facePreviewInfoList.get(i).getTrackId());// Log.i(TAG, "onPreview: fr start = " + System.currentTimeMillis() + " trackId = " + facePreviewInfoList.get(i).getTrackedFaceCount()); } } } } @Override public void onCameraClosed() { Log.i(TAG, "onCameraClosed: "); } @Override public void onCameraError(Exception e) { Log.i(TAG, "onCameraError: " + e.getMessage()); } @Override public void onCameraConfigurationChanged(int cameraID, int displayOrientation) { if (drawHelper != null) { drawHelper.setCameraDisplayOrientation(displayOrientation); } Log.i(TAG, "onCameraConfigurationChanged: " + cameraID + " " + displayOrientation); } }; cameraHelper = new CameraHelper.Builder() .previewViewSize(new Point(previewView.getMeasuredWidth(), previewView.getMeasuredHeight())) .rotation(getWindowManager().getDefaultDisplay().getRotation()) .specificCameraId(rgbCameraID != null ? rgbCameraID : Camera.CameraInfo.CAMERA_FACING_FRONT) .isMirror(false) .previewOn(previewView) .cameraListener(cameraListener) .build(); cameraHelper.init(); cameraHelper.start(); }
人脸注册
private void registerFace(final byte[] nv21, final ListfacePreviewInfoList) { if (registerStatus == REGISTER_STATUS_READY && facePreviewInfoList != null && facePreviewInfoList.size() > 0) { registerStatus = REGISTER_STATUS_PROCESSING; Observable.create( new ObservableOnSubscribe () { @Override public void subscribe(ObservableEmitter emitter) { boolean success = FaceServer.getInstance().registerNv21(FaceComparison_RGB.this, nv21.clone(), previewSize.width, previewSize.height, facePreviewInfoList.get(0).getFaceInfo(), "registered" + faceHelper.getTrackedFaceCount()); emitter.onNext(success); } }) .subscribeOn( Schedulers.computation()) .observeOn( AndroidSchedulers.mainThread()) .subscribe(new Observer () { @Override public void onSubscribe(Disposable d) { } /**判断是否注册成功*/ @Override public void onNext(Boolean success) { //String result = success ? "register success!" : "register failed!"; //ShowToast(result);// AlertDialog.Builder builder = new AlertDialog.Builder( FaceComparison_RGB.this );// AlertDialog dialog = builder.create();// View AlertDialog_View = View.inflate( FaceComparison_RGB.this,R.layout.register_result,null );// dialog.setView( AlertDialog_View );// dialog.show(); ShowPopWindows(success); registerStatus = REGISTER_STATUS_DONE; } @Override public void onError(Throwable e) { e.printStackTrace(); ShowToast("register failed!"); ShowFailPopWindows(); registerStatus = REGISTER_STATUS_DONE; } @Override public void onComplete() { } }); } }
切换前置、后置摄像头
public void switchCamera(View view) { if (cameraHelper != null) { boolean success = cameraHelper.switchCamera(); if (!success) { ShowToast(getString(R.string.switch_camera_failed)); } else { ShowToast(getString(R.string.notice_change_detect_degree)); } } }
到此,相信大家对"Android开发基于ArcSoft实现人脸识别的方法是什么"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
人脸
活体
特征
检测
方法
引擎
状态
开发
成功
切换
处理
内容
图像
数据
次数
激活
相机
结果
学习
延迟
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
外网安全访问内网文件服务器
五度空间网络安全
电视台播出部网络安全建设
软件开发用平面设计吗
软件开发涉及哪些项目文档
海南省台式电脑服务器自动生产线
魅族邮箱无法连接无线服务器
将网络技术带进语文课堂
国内外网络技术现状
河南创梦星球软件开发
我的世界战斗的服务器是哪个
易网服务管理服务器
手机端 服务器
知网阅读授权服务器访问异常
网络安全微课入围名单
加速网络技术服务
戴尔高性价比服务器
oracle查树状数据库
excel服务器有人做吗
上海java软件开发贴吧
dbca创建数据库 监听
游戏服务器的作用
数据库怎么从信息中选出属性
服务器端口开启后数据阻塞
四川电力运维软件开发
软件开发需求及方案
关注海运行业的网络安全
数据库太大 如何迁移
手机小软件开发
第五空间透明时代网络安全观后感