人脸识别第三方sdk比较多,可是大多都是收费的或者限制次数什么的,虹软的效果还不错,全免费也不须要联网android
V1.2版本使用和快速集成:Android集成虹软人脸、人证对比,活体检测api
虹软官网:http://www.arcsoft.com.cn/
官网下载sdk,还要引入一个依赖,用来转换把bitmap以必定的格式转为byte[]的数组
api 'com.guo.android_extend:android-extend:1.0.1'
官网的demo里面其实就写的比较清楚了,总共分为两个部分,一个是人脸注册,一个是人脸识别,先提取人脸特征,再和以前提取的比较得出类似度,能够根据类似度来判断是否是一我的app
人脸注册ide
就是提取人脸的特征,一张图片能够识别出多我的脸特征(若是有多我的脸),特征是一个byte数组,其实不用图片,获取相机的预览回调获取图片数据这种方法也是很好的,反正传入图片数据就能够,分为如下几步: 初始化要提取人脸识别的图片数据设计
//初始化图片数据 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_FSDKFace的集合,用来保存传入引擎检测的人脸信息,其中包括了人脸的角度和一个Rect对象,Rect对象就是人脸在图片中的位置,能够根据这个Rect来把人脸部分标记出来什么的code
//初始化 AFD_FSDKEngine engine = new AFD_FSDKEngine(); AFD_FSDKVersion version = new AFD_FSDKVersion(); List<AFD_FSDKFace> result = new ArrayList<AFD_FSDKFace>(); //设置最多识别5张人脸 AFD_FSDKError err = engine.AFD_FSDK_InitialFaceEngine(FaceDB.appid, FaceDB.fd_key, AFD_FSDKEngine.AFD_OPF_0_HIGHER_EXT, 16, 5); //获取人脸信息 result err = engine.AFD_FSDK_GetVersion(version); err = engine.AFD_FSDK_StillImageFaceDetection(data, mBitmap.getWidth(), mBitmap.getHeight(), AFD_FSDKEngine.CP_PAF_NV21, result);
根据获取到的AFD_FSDKFace集合和原图像获取人脸的特征,每一个AFD_FSDKFace均可以获取到一个AFR_FSDKFace对orm
象,包括就是一个byte[]类型的变量mFeatureData用来保存人脸特征,和一个引擎定义的特征信息数据长度int类型的变量对象
FEATURE_SIZE(不用管这个)blog
//初始化 AFR_FSDKVersion version1 = new AFR_FSDKVersion(); AFR_FSDKEngine engine1 = new AFR_FSDKEngine(); AFR_FSDKFace result1 = new AFR_FSDKFace(); AFR_FSDKError error1 = engine1.AFR_FSDK_InitialEngine(FaceDB.appid, FaceDB.fr_key); error1 = engine1.AFR_FSDK_GetVersion(version1); //获取人脸特征 mAFR_FSDKFace error1 = engine1.AFR_FSDK_ExtractFRFeature(data, mBitmap.getWidth(), mBitmap.getHeight(), AFR_FSDKEngine.CP_PAF_NV21, new Rect(result.get(0).getRect()), result.get(0).getDegree(), result1); if(error1.getCode() == error1.MOK) { mAFR_FSDKFace = result1.clone(); } //销毁引擎,释放内存资源 engine1.AFR_FSDK_UninitialEngine(); engine.AFD_FSDK_UninitialFaceEngine();
其实mAFR_FSDKFace里面的byte[]类型的变量mFeatureData就是须要的人脸特征,本身随便保存一下,人脸识别的时候再拿出来对比 人脸识别 人脸识别方式就是再获取到人脸的特征和以前保存的人脸特征对比,获取的方式有不少,除了上面的图片来获取之外还能够经过调用相机的预览回调来获取数据来获取人脸的特征再去对比,这样体验比较好和如今手机经常使用的人脸识别方法同样,自定义相机就不写出来了,步骤以下:
//初始化 public static List<AFT_FSDKFace> resultAtf; AFT_FSDKEngine engine; AFT_FSDKError err; AFR_FSDKEngine engine2; AFR_FSDKError error2; AFR_FSDKFace result; byte[] faceData; resultAtf = new ArrayList<>(); engine = new AFT_FSDKEngine(); err = engine.AFT_FSDK_InitialFaceEngine(FaceDB.appid, FaceDB.ft_key, AFT_FSDKEngine.AFT_OPF_0_HIGHER_EXT, 16, 5); err = engine.AFT_FSDK_GetVersion(new AFT_FSDKVersion()); engine2 = new AFR_FSDKEngine(); result = new AFR_FSDKFace(); error2 = engine2.AFR_FSDK_InitialEngine(FaceDB.appid, FaceDB.fr_key); error2 = engine2.AFR_FSDK_GetVersion(new AFR_FSDKVersion());
//须要设置相机预览图片的格式 para.setPreviewFormat(ImageFormat.NV21);
//相机预览回调获取数据 byte[] faceData; private Camera.PreviewCallback mPreViewCallback = new Camera.PreviewCallback() { @Override public void onPreviewFrame(final byte[] data, Camera camera) { if (startFaceCheck) { err = engine.AFT_FSDK_FaceFeatureDetect(data, mWidthPicture, mHeightPreview, AFT_FSDKEngine.CP_PAF_NV21, resultAtf); faceData = data.clone(); } } };
获取到数据后获取人脸特征而后开始对比,方法就是这样,逻辑能够本身设计,也能够根据获取到的人脸数据AFD_FSDKFace来实时的画出人脸的位置
//获取到人脸的信息 resultAtf.clear(); startFaceCheck = true; error2 = engine2.AFR_FSDK_ExtractFRFeature(faceData, mWidthPicture, mHeightPreview, AFR_FSDKEngine.CP_PAF_NV21, resultAtf.get(resultAtf.size() - 1).getRect(), resultAtf.get(resultAtf.size() - 1).getDegree(), result); //初始化对比 AFR_FSDKMatching score = new AFR_FSDKMatching(); AFR_FSDKFace input = new AFR_FSDKFace(); //这是获取我保存的人脸数据,就是有个名字加一我的脸特征 List<FaceDiscern> faceDiscernList = MLiteOrm.getInstance().query(FaceDiscern.class); for (int i = 0; i < faceDiscernList.size(); i++) { final String name = faceDiscernList.get(i).getUserName(); input.setFeatureData(faceDiscernList.get(i).getFaceId()); error2 = engine2.AFR_FSDK_FacePairMatching(result, input, score); //获取类似度 float max = 0.0f; max = score.getScore(); if (max > 0.6) { ToastUtils.showLong("验证经过,操做人:" + name); } } //销毁引擎,释放内存资源 engine2.AFR_FSDK_UninitialEngine(); engine.AFT_FSDK_UninitialFaceEngine();