咱们先来看看效果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); }
欢迎关注个人微信公众号:安卓圈