我司最近要做和人脸识别相关的产品,原来使用的是某在线人脸识别平台,识别率和识别速度很满意,但是随着量起来的话,成本也是越来越不能接受(目前该功能我们是免费给用户使用的),而且一旦我们的设备掉线了就无法使用人脸识别功能。基于这些考虑,我司需要寻找其他的方案。
通过搜索,目前发现,开源或免费支持离线的方案也有不少。目前初步考虑虹软 ArcFace和Dlib。通过官方的demo 和 网上的资料,写了个工程,也可以在这里看。
这里说一下要注意的
摄像头是使用了 OpenCV 来处理的,这里可能会涉及到预览图和屏幕方向不一致的情况,我主要是通过一下代码处理
// 转换图片矩阵 这个也是主要使用 OpenCV 来处理的private Mat rotateMat(Mat srcMat){ int _cameraDisplayRotation = cameraDisplayRotation; if(mCameraIndex == CAMERA_ID_BACK){ // 后置摄像头 _cameraDisplayRotation = 180 + _cameraDisplayRotation; } Point center = new Point(srcMat.cols()/2,srcMat.rows()/2); Mat dstMat = srcMat; Mat rotImage = Imgproc.getRotationMatrix2D(center, _cameraDisplayRotation, 1); // 获取旋转矩阵 逆时针旋转。参数说明 center:表示旋转的中心点;angle:表示旋转的角度 ;scale:图像缩放因子 Imgproc.warpAffine(srcMat, dstMat, rotImage, dstMat.size()); // 实现坐标系仿射变换。参数说明 src: 输入源图像;dst: 输出图像;M: 仿射变换矩阵;dsize: 输出图像的尺寸 if(mCameraIndex == CAMERA_ID_FRONT){ Core.flip(dstMat,dstMat,1);//整理表示水平翻转,0表示垂直翻转,负数表示既有水平也有垂直翻转 } if(rotImage!=null)rotImage.release(); return dstMat;}
Dlib 和虹软 ArcFace要做人脸识别前都需要先检测人脸,要不然后续提取不到人脸特征
人脸特征比对时,建议将需要识别的人脸特征库预先加载到内存,这样可以加快速度(当然也占用比较大的内存)在使用 Dlib 做人脸检测时要注意,人脸方向和屏幕方向不一致时检测不到人脸(虹软 ArcFace 不存在这个问题),如果不一致,需要将图片的人脸方向转为和屏幕方向一致时再来做人脸检测虹软 ArcFace 做人脸识别时,要注意你下载的凭条 SDK 与 APP_Id、SDK_key 要一致(这个是没懂要搞这么多验证数据)。库的引用直接安装文档操作即可。虹软 ArcFace 做人脸识别时,要使用人脸检测时的人脸角度,要不然提取不到人脸特征,可以参考一下代码说明// data 图片数据 注意数据格式是NV21的,目前虹软只支持这种格式,可以通过摄像头参数设置,也可以通过相关工具转换得到// width 图片宽// height 图片高// AFD_FSDKEngine.CP_PAF_NV21 图片数据格式 目前虹软只支持这种格式// faceDB 我的人脸特征库Listresult_FD = new ArrayList<>(); // 用来存放检测到的人脸信息列表AFD_FSDKError error_FD = engine_detection.AFD_FSDK_StillImageFaceDetection(data, width, height, AFD_FSDKEngine.CP_PAF_NV21, result_FD); // 检测人脸AFR_FSDKFace face = new AFR_FSDKFace(); // 用来存放提取到的人脸信息AFR_FSDKMatching score = new AFR_FSDKMatching(); //score用于存放人脸对比的相似度值for(int i=0; i < result_FD.size(); i++){ AFD_FSDKFace item = result_FD.get(i); Rect itemRect = item.getRect(); // 人脸位置 int degree = item.getDegree(); // 人脸方向 这个比 Dlib 好的地方 AFR_FSDKError error_FR = engine_recognition.AFR_FSDK_ExtractFRFeature(data, width, height, AFR_FSDKEngine.CP_PAF_NV21, itemRect, degree, face); // 提取人脸信息 error_FR = engine_recognition.AFR_FSDK_FacePairMatching(face, item, score); for(int j=0; j myThreshold){ // 找到相似的人脸 。。。 } }}
测试结果
原图是1280x960,经压缩处理是320x240,经测试发现虹软的压缩和不压缩图片,效果是差不多的Dlib测试结果
机型 一次人脸检测耗时 一次一个人脸特征提取耗时 一次人脸特征比对耗时 坚果 U1 280毫秒左右 6800毫秒左右 0.03毫秒左右 坚果 pro2 93毫秒左右 1060毫秒左右 0.002毫秒左右虹软测试结果
机型 一次人脸检测耗时 一次一个人脸特征提取耗时 一次人脸特征比对耗时 坚果 U1 43毫秒左右 943毫秒左右 0.883毫秒左右 坚果 pro2 20毫秒左右 314毫秒左右 0.308毫秒左右从该测试可以看出 Dlib 和 虹软 ArcFace 的优缺点,两个的性能瓶颈都在人脸特征提取,Dlib尤为突出。相对比Dlib,虹软 ArcFace更适合于手机端平台。