写点什么

基于虹软 SDK,适配 Camera1、Camera2、CameraX,实现人脸识别(Android)

用户头像
小驰嘻嘻
关注
发布于: 6 小时前
基于虹软SDK,适配Camera1、Camera2、CameraX,实现人脸识别(Android)

这篇文章主要介绍基于虹软人脸识别 SDK,适配 Camera1、Camera2、CameraX。文章分下面几点展开。

一、应用设计流程图

二、应用界面展示

三、虹软 SDK 介绍

四、代码实现


ArcSoft 官方的 demo 目前是采用的 Camera1 接口,我前面也写过一篇单独 Camera2 接口集成 Arcsoft 接口的文章。(https://www.jianshu.com/p/cb2f65ead747

一、应用设计流程图

如下图所示,应用流程比较简单,分别从不同的 API 接口获取到 Camera 数据流数据,然后送到 ArcSoft 人脸识别算法库中进行识别,最终将识别结果绘制到界面上。


二、应用界面

CameraX 需要和界面生命周期进行绑定,所以主界面设计成了 2 个 Button 入口,一个入口时 Camera1 和 Camera2 共用,一个是 CameraX 独立的入口。


如下图所示:Camera1 和 Camera2 之间可以互相切换。



CameraX 是单独的界面。


三、虹软 SDK 介绍

本应用基于虹软人脸识别 SDK 3.0 版本,目前有更新的 4.1 版本,支持更多的功能。虹软视觉开放平台: https://ai.arcsoft.com.cn/


我们点击选择进入“开发者中心”。



如上图所示,登录进入开发者中心后,我们可以创建我们的应用,进而获取到对应的 APP_ID 和 SDK_KEY,并且可以下载对应的 SDK。


我们根据自己需要下载对应的 sdk,sdk 里面包含了需要用的 jar 包、so 库,还有详细的集成说明文档,已经 samplecode 供我们参考集成,可谓是集成起来是非常的方便了。

四、代码实现

1) 虹软 SDK 关键代码

i、我们在开发者平台上申请的 APP_ID 和 SDK_KEY,在激活人脸识别引擎的时候需要用到。

public static final String APP_ID = "JDk8rV3BBGnToh6HNYzCFpxYXMowitBjFuCjPGQr4CcC";

public static final String SDK_KEY = "EBH3RG2D55ayfVrGK7SeTivMWxjzsskwNt1RyfVPVbg9";


ii、初始化 SDK 引擎

private void initEngine() {        faceEngine = new FaceEngine();        afCode = faceEngine.init(this, DetectMode.ASF_DETECT_MODE_VIDEO, ConfigUtil.getFtOrient(this),                16, 20,         FaceEngine.ASF_FACE_DETECT | FaceEngine.ASF_AGE | FaceEngine.ASF_FACE3DANGLE | FaceEngine.ASF_GENDER | FaceEngine.ASF_LIVENESS);              if (afCode != ErrorInfo.MOK) {            showToast( getString(R.string.init_failed, afCode));        }    }
复制代码

iii、将实时的 nv21 数据送到 sdk 中进行识别。detectFaces 方法显示检测是否有人脸。检测到人脸后,process 方法是获取识别的人脸详细信息(年龄、性别...)。

int code = faceEngine.detectFaces(nv21, previewSize.width,                 previewSize.height,                 FaceEngine.CP_PAF_NV21, faceInfoList);
if (code == ErrorInfo.MOK && faceInfoList.size() > 0) { code = faceEngine.process(nv21, previewSize.width, previewSize.height, FaceEngine.CP_PAF_NV21, faceInfoList, processMask);
复制代码

2) Camera1 API 的使用:

 private void startCameraByApi1() {        CameraListener cameraListener = new CameraListener() {            @Override            public void onCameraOpened(Camera camera, int cameraId, int displayOrientation, boolean isMirror) {                 ......            }
@Override public void onPreview(byte[] nv21, Camera camera) { //接收到实时预览数据回调,送入虹软sdk进行人脸识别 drawFaceInfo(nv21); } ...... };
复制代码

3) Camera2 API 的使用:

private final ImageReader.OnImageAvailableListener mOnImageAvailableListener            = new ImageReader.OnImageAvailableListener() {
@Override public void onImageAvailable(ImageReader reader) { Image image = reader.acquireLatestImage();
if(image == null){ return; }
synchronized (mImageReaderLock) { if(!mImageReaderLock.equals(1)){ Log.v(TAG, "--- image not available,just return!!!"); image.close(); return; } if (ImageFormat.YUV_420_888 == image.getFormat()) { Image.Plane[] planes = image.getPlanes();
lock.lock(); if (y == null) { y = new byte[planes[0].getBuffer().limit() - planes[0].getBuffer().position()]; u = new byte[planes[1].getBuffer().limit() - planes[1].getBuffer().position()]; v = new byte[planes[2].getBuffer().limit() - planes[2].getBuffer().position()]; }
if (image.getPlanes()[0].getBuffer().remaining() == y.length) { planes[0].getBuffer().get(y); planes[1].getBuffer().get(u); planes[2].getBuffer().get(v);
if (nv21 == null) { nv21 = new byte[planes[0].getRowStride() * mPreviewSize.getHeight() * 3 / 2]; }
if(nv21 != null && (nv21.length != planes[0].getRowStride() * mPreviewSize.getHeight() *3/2)){ return; }
// 回传数据是YUV422 if (y.length / u.length == 2) { ImageUtil.yuv422ToYuv420sp(y, u, v, nv21, planes[0].getRowStride(), mPreviewSize.getHeight()); } // 回传数据是YUV420 else if (y.length / u.length == 4) { ImageUtil.yuv420ToYuv420sp(y, u, v, nv21, planes[0].getRowStride(), mPreviewSize.getHeight()); }
//调用Arcsoft算法,绘制人脸信息 drawFaceInfo(nv21); } lock.unlock(); } } image.close(); } };
复制代码

3) CameraX API 的使用:

private void startCameraX() {        Log.v(TAG,"--- startCameraX();");        mPreviewSize = new Size(640,480);        setPreviewViewAspectRatio();        initArcsoftDrawHelper();
Rational rational = new Rational(mPreviewSize.getHeight(), mPreviewSize.getWidth()); // 1. preview PreviewConfig previewConfig = new PreviewConfig.Builder() .setTargetAspectRatio(rational) .setTargetResolution(mPreviewSize) .build();
Preview preview = new Preview(previewConfig); preview.setOnPreviewOutputUpdateListener(new Preview.OnPreviewOutputUpdateListener() { @Override public void onUpdated(Preview.PreviewOutput output) { previewView.setSurfaceTexture(output.getSurfaceTexture()); configureTransform(previewView.getWidth(),previewView.getHeight()); } });
// 2. capture ImageCaptureConfig imageCaptureConfig = new ImageCaptureConfig.Builder() .setTargetAspectRatio(rational) .setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY) .build(); final ImageCapture imageCapture = new ImageCapture(imageCaptureConfig);
// 3. analyze HandlerThread handlerThread = new HandlerThread("Analyze-thread"); handlerThread.start();
ImageAnalysisConfig imageAnalysisConfig = new ImageAnalysisConfig.Builder() .setCallbackHandler(new Handler(handlerThread.getLooper())) .setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE) .setTargetAspectRatio(rational) .setTargetResolution(mPreviewSize) .build();
ImageAnalysis imageAnalysis = new ImageAnalysis(imageAnalysisConfig); imageAnalysis.setAnalyzer(new MyAnalyzer());
CameraX.bindToLifecycle(this, preview, imageCapture, imageAnalysis); }
复制代码

四、遇到的问题

1)预览变形

这个是由于设置 Camera 预览的 size 和 TextureView 的 size 比例不一致导致。

我们一般会根据当前设备屏幕的 size,遍历 camera 支持的 preview size,找到适合当前设备的预览 size,再根据当前预览 size,动态调整 textureView 的显示。

2)Arcsoft sdk code 异常

中间遇到的关于 Arcsoft sdk code 异常的,可以在 Arcsoft 开发中心,帮助界面,输入对应的 error code,根据提示信息,可以帮忙我们快速定位排查问题。


五、附录:

1)Demo 地址:

链接:https://pan.baidu.com/s/1rKyncLbxPfH5ajDTINBhCg提取码:xcbj

2)ArcSoft 官网 sdk 下载地址:

https://ai.arcsoft.com.cn/



发布于: 6 小时前阅读数: 6
用户头像

小驰嘻嘻

关注

公众号: 小驰笔记 2021.03.30 加入

14年开始从事Android Camera相关软件开发 做过车载、手机、执法记录仪~

评论

发布
暂无评论
基于虹软SDK,适配Camera1、Camera2、CameraX,实现人脸识别(Android)