基于虹软免费SDK实现Android人脸识别开发
1、项目的目标我们需要实现一个人脸识别功能。简单来说,就是机的后置摄像头,识别摄像头中实时拍到的人脸信息,如果人库注册过,则显示识别后的人脸信息,如登记的名字;如果不在,提示未注册。人脸识别的过程人脸识别包括两个必备的过程,人脸注册和实时识别。人脸注册是指把人脸的特征信息注册到人脸信息库中。人脸特征提取是一个不可逆的过程,你无法从人脸特征信息还原一个人的脸部照片。在线库在使用时,需要传递照片信息,或者提取图像特征值,离线的SDK相对安全,但是,在线的SDK通常提供更多的接入和调用方式,这个要结合实际情况来选择。人脸注册和识别的过程可以用下面的图来表示

3、其中,第一个Face Detection,人脸检测。第二个Face Recognition,人脸识别。第三个Face Tracking,人脸跟踪。这三包的结构基本相同,我们需要把它们解压。- doc 此目录中存放GUIDE文档,是说明文档,里面介绍了公开发布的一些API,并提供了示例代码。- libs 开发中需要用到的库,需要把它们目录结构不变的全部引用到你的项目项目中。- sampleCode 示例代码(注意:开发中还需要APP_Id和SDK_Key的激活码,这些激活码可以在账号管理–》您的申请记录,对应的下载应用中找到相应的激活码。)
4、版本与环境要求根据SDK的说明,我们使用的版本为android arm32,版本为5.0.我们使用的IDE为android studio,你也可以使用eclipse,不过依然建议你使用android studio,因为它现在已经是事实上的标准。一步一步实现人脸识别功能本文将以这三个库为基础,从人脸注册开始,到人脸识别结束。全程演示人脸识别的流程。如果你不想从头开始,你可以到github下载完整的示例程序新建项目打开android studio,建立项目,API兼容性选择4.0。导入依赖包虹软人脸SDK的包是so包,你可以在下载的压缩包中把这些文件找到并导入。导入后的工程文件夹如下所示。

10、AFD_FSDKFace是人脸识别的结果,定义如下public class AFD_FSDKFace { Rect mRect; int mDegree; }mRect定义一个了一个矩形框Rect在此之前我们需要注意虹软人脸SDK使用的图像格式是NV21的格式,所以我们需要将获取到的图像转化为对应的格式。在Android_extend.jar中提供了对应的转换函数 byte[] data = new byte[mBitmap.getWidth() * mBitmap.getHeight() * 3 / 2]; ImageConverter convert = new ImageConverter(); convert.initial(mBitmap.getWidth(), mBitmap.getHeight(), ImageConverter.CP_PAF_NV21); if (convert.convert(mBitmap, data)) { Log.d(TAG, "convert ok!"); } convert.destroy();现在我们就可以调用AFD_FSDK_StillImageFaceDetection方法了err = engine.AFD_FSDK_StillImageFaceDetection(data, mBitmap.getWidth(), mBitmap.getHeight(), AFD_FSDKEngine.CP_PAF_NV21, result);
11、绘出人脸框在List中保存了检测到的人脸的位置信息和深度信息。我们可以将检测到的人脸位置信息在图片上用一个矩形框绘制出来表示检测到的人脸信息。Canvas canvas = mSurfa艘早祓胂ceHolder.lockCanvas(); if (canvas != null) { Paint mPaint = new Paint(); boolean fit_horizontal = canvas.getWidth() / (float)src.width() < canvas.getHeight() / (float)src.height() ? true : false; float scale = 1.0f; if (fit_horizontal) { scale = canvas.getWidth() / (float)src.width(); dst.left = 0; dst.top = (canvas.getHeight() - (int)(src.height() * scale)) / 2; dst.right = dst.left + canvas.getWidth(); dst.bottom = dst.top + (int)(src.height() * scale); } else { scale = canvas.getHeight() / (float)src.height(); dst.left = (canvas.getWidth() - (int)(src.width() * scale)) / 2; dst.top = 0; dst.right = dst.left + (int)(src.width() * scale); dst.bottom = dst.top + canvas.getHeight(); } canvas.drawBitmap(mBitmap, src, dst, mPaint); canvas.save(); canvas.scale((float) dst.width() / (float) src.width(), (float) dst.height() / (float) src.height()); canvas.translate(dst.left / scale, dst.top / scale); for (AFD_FSDKFace face : result) { mPaint.setColor(Color.RED); mPaint.setStrokeWidth(10.0f); mPaint.setStyle(Paint.Style.STROKE); canvas.drawRect(face.getRect(), mPaint); } canvas.restore(); mSurfaceHolder.unlockCanvasAndPost(canvas); break; }}
12、将人脸注册到人脸库检测到了人脸,我们可以输入相应的描述信息,加入到人脸库中。public void addFace(String name, AFR_FSDKFace face) { try { //check if already registered. boolean add = true; for (FaceRegist frface : mRegister) { if (frface.mName.equals(name)) { frface.mFaceList.add(face); add = false; break; } } if (add) { // not registered. FaceRegist frface = new FaceRegist(name); frface.mFaceList.add(face); mRegister.add(frface); } if (!new File(mDBPath + "/face.txt").exists()) { if (!saveInfo()) { Log.e(TAG, "save fail!"); } } //save name FileOutputStream fs = new FileOutputStream(mDBPath + "/face.txt", true); ExtOutputStream bos = new ExtOutputStream(fs); bos.writeString(name); bos.close(); fs.close(); //save feature fs = new FileOutputStream(mDBPath + "/" + name + ".data", true); bos = new ExtOutputStream(fs); bos.writeBytes(face.getFeatureData()); bos.close(); fs.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }}最后,别忘记了销毁人脸检测引擎哦err = engine.AFD_FSDK_UninitialFaceEngine(); Log.d("com.arcsoft", "AFD_FSDK_UninitialFaceEngine =" + err.getCode());
13、实现人脸识别上面的代码准备完毕后,就可以开始我们的人脸识别的功能了。我们使用一个第三方的扩展库,ExtGLSurfaceView的扩展 库CameraGLSurfaceView,用Imag髫潋啜缅eView和TextView显示检测到的人脸和相应的描述信息。首先是定义layout。因为引擎需要的图像格式是NV21的,所以需要将摄像头中的图像格式预设置为NV21public Camera setupCamera() { // TODO Auto-generated method stub mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK); try { Camera.Parameters parameters = mCamera.getParameters(); parameters.setPreviewSize(mWidth, mHeight); parameters.setPreviewFormat(ImageFormat.NV21); for( Camera.Size size : parameters.getSupportedPreviewSizes()) { Log.d(TAG, "SIZE:" + size.width + "x" + size.height); } for( Integer format : parameters.getSupportedPreviewFormats()) { Log.d(TAG, "FORMAT:" + format); } List<int[]> fps = parameters.getSupportedPreviewFpsRange(); for(int[] count : fps) { Log.d(TAG, "T:"); for (int data : count) { Log.d(TAG, "V=" + data); } } mCamera.setParameters(parameters); } catch (Exception e) { e.printStackTrace(); } if (mCamera != null) { mWidth = mCamera.getParameters().getPreviewSize().width; mHeight = mCamera.getParameters().getPreviewSize().height; } return mCamera;}从摄像头识别人脸,需要使用FT库,FT库在人脸跟踪算法上对人脸检测部分进行了优化,是专门为视频处理而优化的库。
14、初始化人脸检测引擎(FT)和FD一样,我们需要初始化人脸识别FT引擎。
15、运行结果我们来看一下运行的结果。效果还不错吧。钟汉良帅哥一枚。本文档中所有的代码都可以github下载。如果你需要寻找更多的人脸识别的demo,也可以到虹软的论坛中去寻找。
