Android开发基于ArcSoft实现人脸识别的方法是什么
发表于:2025-11-15 作者:千家信息网编辑
千家信息网最后更新 2025年11月15日,本篇内容主要讲解"Android开发基于ArcSoft实现人脸识别的方法是什么",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Android开发基于ArcS
千家信息网最后更新 2025年11月15日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; } List libraryNameList = 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安全错误
数据库的锁怎样保障安全
未来之役服务器在中国吗
数据库查询重复字段
哪些人会购买网络安全软件
数据库技术中实体的概念
淘宝的服务器的ip
日照大学 软件开发
怎么组装服务器网络
服务器机箱怎么隔音
银行项目数据库
手机游戏无法切换服务器
深圳直播软件开发运营需要多少钱
浪潮服务器系统故障红灯常亮
网络安全技术考研科目
巴鲁夫传感器内部数据库
k3服务器怎么分配用户
三亚网络技术
数据库中所支持的主要数据模型
攻击游戏服务器工具
临泽县网络安全法
怎样配置服务器地址
7545 数据库端口号
微信云数据库pc管理工具
客户端服务器ip地址查询
数据库运行sql文件
宝山区软件开发管理
linux服务器文件夹目录
网络安全时事新闻
德州服务器管理系统销售
软件开发 维保 协议书
靖江网络安全宣传周电信日