咱們先來看看效果html
上面是根據圖片檢測出其中的人臉、每一個人臉的年齡還有性別,很是強大java
第一步:android
登陸https://ai.arcsoft.com.cn/,註冊開發者帳號,身份認證,註冊應用,獲得APPID和SDKKEY微信
第二步:ide
閱讀SDK接入文檔https://ai.arcsoft.com.cn/manual/arcface_android_guideV2.htmlui
其中重要的是下面this
Step1:調用FaceEngine的active方法激活設備,一個設備安裝後僅需激活一次,卸載從新安裝後須要從新激活。
Step2:調用FaceEngine的init方法初始化SDK,初始化成功後才能進一步使用SDK的功能。
Step3:調用FaceEngine的detectFaces方法進行圖像數據或預覽數據的人臉檢測,若檢測成功,則可獲得一我的臉列表。(初始化時combineMask須要ASF_FACE_DETECT)
Step4:調用FaceEngine的extractFaceFeature方法可對圖像中指定的人臉進行特徵提取。(初始化時combineMask須要ASF_FACE_RECOGNITION)
Step5:調用FaceEngine的compareFaceFeature方法可對傳入的兩我的臉特徵進行比對,獲取類似度。(初始化時combineMask須要ASF_FACE_RECOGNITION)
Step6:調用FaceEngine的process方法,傳入不一樣的combineMask組合可對Age、Gender、Face3Dangle、Liveness進行檢測,傳入的combineMask的任一屬性都須要在init時進行初始化。
Step7:調用FaceEngine的getAge、getGender、getFace3Dangle、getLiveness方法可獲取年齡、性別、三維角度、活體檢測結果,且每一個結果在獲取前都須要在process中進行處理。
Step8:調用FaceEngine的unInit方法銷燬引擎。在init成功後如不unInit會致使內存泄漏。
引擎必定要先激活,只需激活一次,而後初始化,接着就選擇你須要的方法調用,step3-step7選擇其中一個調用便可,最後的最後必定要銷燬引擎spa
貼出核心代碼:code
/** * 激活引擎 */
public void activeEngine() { if (!checkPermissions(NEEDED_PERMISSIONS)) { ActivityCompat.requestPermissions(this, NEEDED_PERMISSIONS, ACTION_REQUEST_PERMISSIONS); return; } Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { faceEngine = new FaceEngine(); int activeCode = faceEngine.active(MainActivity.this, Constants.APP_ID, Constants.SDK_KEY); emitter.onNext(activeCode); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<Integer>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(Integer activeCode) { if (activeCode == ErrorInfo.MOK) { showToast(getString(R.string.active_success)); } else if (activeCode == ErrorInfo.MERR_ASF_ALREADY_ACTIVATED) { showToast(getString(R.string.already_activated)); } else { showToast(getString(R.string.active_failed, activeCode)); } } @Override public void onError(Throwable e) { } @Override public void onComplete() { } }); }
/** * 初始化引擎 **/
private void initEngine() { faceEngineCode = faceEngine.init(this, FaceEngine.ASF_DETECT_MODE_IMAGE, FaceEngine.ASF_OP_0_HIGHER_EXT, 16, 10, FaceEngine.ASF_FACE_RECOGNITION | FaceEngine.ASF_FACE_DETECT | FaceEngine.ASF_AGE | FaceEngine.ASF_GENDER | FaceEngine.ASF_FACE3DANGLE | FaceEngine.ASF_LIVENESS); VersionInfo versionInfo = new VersionInfo(); faceEngine.getVersion(versionInfo); if (faceEngineCode != ErrorInfo.MOK) { showToast(getString(R.string.init_failed, faceEngineCode)); } }
//bitmap轉bgr
byte[] bgr24 = ImageUtil.bitmapToBgr(bitmap); if (bgr24 == null) { clearDialog(); showToast("圖片轉化失敗"); return; } /** * 2.成功獲取到了BGR24 數據,開始人臉檢測 */ List<FaceInfo> faceInfoList = new ArrayList<>(); faceEngine.detectFaces(bgr24, width, height, FaceEngine.CP_PAF_BGR24, faceInfoList); if (faceInfoList.size() == 0) { clearDialog(); showToast("沒有檢測到人臉"); startActivity(new Intent(this, MainActivity.class)); } if (faceInfoList.size() > 1) { clearDialog(); showToast("請不要同時出現多我的臉"); startActivity(new Intent(this, MainActivity.class)); } if (faceInfoList.size() == 1) { clearDialog(); FaceInfo faceInfo = faceInfoList.get(0); //獲得人臉的寬和高
final int faceWidth = faceInfo.getRect().width(); final int faceHeight = faceInfo.getRect().height(); makeFace(); }
我這裏只作了識別人臉,其餘的功能能夠參考官網的Demoserver
屢次調用ImageView.setImageResource方法,我在開發過程當中遇到了OOM,由於這些加載圖片的方法最終都是經過java層的createBitmap來完成的,須要消耗不少內存
能夠採用BitmapFactory.decodeStream方法,建立出一個bitmap,再將其設爲ImageView的source。decedeStream最大的祕密在於其直接調用JNI>>nativeDecideAsset()來完成decode,無需再使用java層的createBitmap,從而節省了java層的空間
/** * 此方法是爲了防止內存溢出 */
private BitmapDrawable getBitmap(int resId) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.RGB_565; options.inPurgeable = true; options.inInputShareable = true; InputStream is = getResources().openRawResource(resId); Bitmap bitmap = BitmapFactory.decodeStream(is, null, options); try { is.close(); } catch (IOException e) { e.printStackTrace(); } return new BitmapDrawable(getResources(), bitmap); }
歡迎關注個人微信公衆號:安卓圈