人臉識別第三方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();