美文网首页
Android 集成虹软人脸识别SDK的问题

Android 集成虹软人脸识别SDK的问题

作者: 简单就是真 | 来源:发表于2019-08-17 16:32 被阅读0次

    如何集成

    如何调用

    -在你集成的应用内Activity或SplashActivity

    编写如下方法,引擎初始化

    /**
         * 激活引擎
         *
         */
        public void activeEngine() {
            Observable.create(new ObservableOnSubscribe<Integer>() {
                @Override
                public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                    FaceEngine faceEngine = new FaceEngine();
                    int activeCode = faceEngine.active(SplashActivity.this, CommMacro.ARC_APPID, CommMacro.ARC_SDKKEY);
                    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) {
                                Toast.makeText(getApplicationContext(),"激活成功",Toast.LENGTH_SHORT).show();
                                Log.d("Arc", "激活成功了: ");
                            } else if (activeCode == ErrorInfo.MERR_ASF_ALREADY_ACTIVATED) {
                                //Toast.makeText(getApplicationContext(),"已激活,无需再次激活",Toast.LENGTH_SHORT).show();
                            } else {
                                Toast.makeText(getApplicationContext(),"激活失败",Toast.LENGTH_SHORT).show();
                            }
    
                        }
    
                        @Override
                        public void onError(Throwable e) {
    
                        }
    
                        @Override
                        public void onComplete() {
    
                        }
                    });
    
        }
    
    • 代码中的APPID 和 SDKKEY就是你在开发者中心申请的

    如何使用

    • 人脸识别初始化
    /**
         * 人脸识别初始化
         */
        private void initArcSetting() {
    
            //本地人脸库初始化
            FaceServer.getInstance().init(SignActivity.this);
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                WindowManager.LayoutParams attributes = getWindow().getAttributes();
                attributes.systemUiVisibility = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
                getWindow().setAttributes(attributes);
            }
    
            // Activity启动后就锁定为启动时的方向
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
    
            previewView = findViewById(R.id.sign_texture_preview);
            faceRectView = findViewById(R.id.sign_face_rect_view);
            previewView.getViewTreeObserver().addOnGlobalLayoutListener(this);
    
            compareResultList = new ArrayList<>();
    
        }
    
    • 其中的FaceServer是在demo中直接使用额


      image.png
    • 声明代码
    
        /**
         * 相机预览显示的控件,可为SurfaceView或TextureView
         */
        private View previewView;
        private ArcCameraHelper cameraHelper;
        private DrawHelper drawHelper;
        private Camera.Size previewSize;
        private FaceRectView faceRectView;
        private Integer rgbCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;//前置摄像头
        private FaceEngine faceEngine;
        private FaceHelper faceHelper;
        private int afCode = -1;
        /**
         * 活体检测的开关
         */
        private boolean livenessDetect = true;
        /**
         * 当FR成功,活体未成功时,FR等待活体的时间
         */
        private static final int WAIT_LIVENESS_INTERVAL = 10;
        private static final int MAX_DETECT_NUM = 10;
        private List<CompareResult> compareResultList;
        private ConcurrentHashMap<Integer, Integer> requestFeatureStatusMap = new ConcurrentHashMap<>();
        private ConcurrentHashMap<Integer, Integer> livenessMap = new ConcurrentHashMap<>();
        private CompositeDisposable getFeatureDelayedDisposables = new CompositeDisposable();
        private static final int ACTION_REQUEST_PERMISSIONS = 0x001;
        private static final float SIMILAR_THRESHOLD = 0.8F;
    
    • 相机初始化代码部分
    private void initCamera() {
            DisplayMetrics metrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(metrics);
    
            final FaceListener faceListener = new FaceListener() {
                @Override
                public void onFail(Exception e) {
                    Log.e(TAG, "onFail: " + e.getMessage());
                }
    
                //请求FR的回调
                @Override
                public void onFaceFeatureInfoGet(@Nullable final FaceFeature faceFeature, final Integer requestId) {
                    //FR成功
                    if (faceFeature != null) {
                        Log.i(TAG, "onPreview: fr end = " + System.currentTimeMillis() + " trackId = " + requestId);
    
                        //不做活体检测的情况,直接搜索
                        if (!livenessDetect) {
                            Log.d(TAG, "不做活体检测的情况,直接搜索: ");
                            searchFace(faceFeature, requestId);
                        }
                        //活体检测通过,搜索特征
                        else if (livenessMap.get(requestId) != null && livenessMap.get(requestId) == LivenessInfo.ALIVE) {
                            Log.d(TAG, "活体检测通过,搜索特征: ");
                            searchFace(faceFeature, requestId);
    
                        }
                        //活体检测未出结果,延迟100ms再执行该函数
                        else if (livenessMap.get(requestId) != null && livenessMap.get(requestId) == LivenessInfo.UNKNOWN) {
                            Log.d(TAG, "活体检测未出结果,延迟10ms再执行该函数: ");
                            getFeatureDelayedDisposables.add(Observable.timer(WAIT_LIVENESS_INTERVAL, TimeUnit.MILLISECONDS)
                                    .subscribe(new Consumer<Long>() {
                                        @Override
                                        public void accept(Long aLong) {
                                            onFaceFeatureInfoGet(faceFeature, requestId);
                                        }
                                    }));
                        }
                        //活体检测失败
                        else {
                            Log.d(TAG, "活体检测失败");
                            requestFeatureStatusMap.put(requestId, CompareResult.NOT_ALIVE);
                        }
    
                    }
                    //FR 失败
                    else {
                        requestFeatureStatusMap.put(requestId, CompareResult.FAILED);
                    }
                }
    
            };
     ArcCameraListener arcCameraListener = new ArcCameraListener() {
                @Override
                public void onCameraOpened(Camera camera, int cameraId, int displayOrientation, boolean isMirror) {
                    Log.i(TAG, "onCameraOpened: " + cameraId + "  " + displayOrientation + " " + isMirror);
                    previewSize = camera.getParameters().getPreviewSize();
    
                    drawHelper = new DrawHelper(previewSize.width, previewSize.height, previewView.getWidth(), previewView.getHeight(), displayOrientation
                            , cameraId, isMirror,false,false);
                    faceHelper = new FaceHelper.Builder()
                            .faceEngine(faceEngine)
                            .frThreadNum(MAX_DETECT_NUM)
                            .previewSize(previewSize)
                            .faceListener(faceListener)
                            .currentTrackId(ConfigUtil.getTrackId(SignActivity.this.getApplicationContext()))
                            .build();
    
                }
    
                @Override
                public void onPreview(byte[] nv21, Camera camera) {
    
                    if (faceRectView != null) {
                        faceRectView.clearFaceInfo();
                    }
    
                    if (faceHelper == null) {
                        return;
                    }
    
                    final List<FacePreviewInfo> facePreviewInfoList = faceHelper.onPreviewFrame(nv21);
                    if (facePreviewInfoList != null && faceRectView != null && drawHelper != null) {
                        List<DrawInfo> drawInfoList = new ArrayList<>();
                        boolean isAlive = false;//活体判断
                        //识别有人脸后进入此处,facePreviewInfoList为已注册过的人脸数据
                        for (int i = 0; i < facePreviewInfoList.size(); i++)
                        {
                            String name = faceHelper.getName(facePreviewInfoList.get(i).getTrackId());
                            /*drawInfoList.add(new DrawInfo(facePreviewInfoList.get(i).getFaceInfo().getRect(), GenderInfo.UNKNOWN, AgeInfo.UNKNOWN_AGE, LivenessInfo.UNKNOWN,
                                    name == null ? String.valueOf(facePreviewInfoList.get(i).getTrackId()) : name));*/
                            //name 置为空字符,为了人脸识别框上不显示文字
    
                            drawInfoList.add(new DrawInfo(drawHelper.adjustRect(facePreviewInfoList.get(i).getFaceInfo().getRect()), GenderInfo.UNKNOWN, AgeInfo.UNKNOWN_AGE, facePreviewInfoList.get(i).getLivenessInfo().getLiveness(),
                                    ""));
                            isAlive = facePreviewInfoList.get(i).getLivenessInfo().getLiveness() == 1 ? true : false;
                        }
                        drawHelper.draw(faceRectView, drawInfoList);
                    }
                    clearLeftFace(facePreviewInfoList);
                    if (facePreviewInfoList != null && facePreviewInfoList.size() > 0 && previewSize != null) {
                        for (int i = 0; i < facePreviewInfoList.size(); i++) {
                            if (livenessDetect) {
                                livenessMap.put(facePreviewInfoList.get(i).getTrackId(), facePreviewInfoList.get(i).getLivenessInfo().getLiveness());
                            }
                            /**
                             * 对于每个人脸,若状态为空或者为失败,则请求FR(可根据需要添加其他判断以限制FR次数),
                             * FR回传的人脸特征结果在{@link FaceListener#onFaceFeatureInfoGet(FaceFeature, Integer)}中回传
                             */
                            if (requestFeatureStatusMap.get(facePreviewInfoList.get(i).getTrackId()) == null
                                    || requestFeatureStatusMap.get(facePreviewInfoList.get(i).getTrackId()) == CompareResult.FAILED) {
                                requestFeatureStatusMap.put(facePreviewInfoList.get(i).getTrackId(), CompareResult.SEARCHING);
                                faceHelper.requestFaceFeature(nv21, facePreviewInfoList.get(i).getFaceInfo(), previewSize.width, previewSize.height, FaceEngine.CP_PAF_NV21, facePreviewInfoList.get(i).getTrackId());
                                Log.i(TAG, "onPreview: fr start = " + System.currentTimeMillis() + " trackId = " + facePreviewInfoList.get(i).getTrackId());
                            }
                        }
                    }
    
                }
    
                @Override
                public void onCameraClosed() {
                    Log.i(TAG, "onCameraClosed: ");
                }
    
                @Override
                public void onCameraError(Exception e) {
    //                Log.i(TAG, "onCameraError: " + e.getMessage());
                }
    
                @Override
                public void onCameraConfigurationChanged(int cameraID, int displayOrientation) {
                    if (drawHelper != null) {
                        drawHelper.setCameraDisplayOrientation(displayOrientation);
                    }
    //                Log.i(TAG, "onCameraConfigurationChanged: " + cameraID + "  " + displayOrientation);
                }
            };
    
            cameraHelper = new ArcCameraHelper.Builder()
                    .previewViewSize(new Point(previewView.getMeasuredWidth(),previewView.getMeasuredHeight()))
                    .rotation(getWindowManager().getDefaultDisplay().getRotation())
                    .specificCameraId(rgbCameraId != null ? rgbCameraId : Camera.CameraInfo.CAMERA_FACING_FRONT)
                    .isMirror(false)
                    .previewOn(previewView)
                    .cameraListener(arcCameraListener)
                    .build();
            cameraHelper.init();
            cameraHelper.start();
    
        }
    
    • 匹配查找人脸
    private void searchFace(final FaceFeature frFace, final Integer requestId) {
            Observable
                    .create(new ObservableOnSubscribe<CompareResult>() {
                        @Override
                        public void subscribe(ObservableEmitter<CompareResult> emitter) {
                            Log.i(TAG, "subscribe: fr search start = " + System.currentTimeMillis() + " trackId = " + requestId);
                            Log.i(TAG, "frFace: " + frFace);
                            CompareResult compareResult = FaceServer.getInstance().getTopOfFaceLib(frFace);
                            Log.i(TAG, "searchFace: " + compareResult);
                            Log.i(TAG, "subscribe: fr search end = " + System.currentTimeMillis() + " trackId = " + requestId);
                            if (compareResult == null) {
                                emitter.onError(null);
                            } else {
                                emitter.onNext(compareResult);
                            }
                        }
                    })
                    .subscribeOn(Schedulers.computation())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<CompareResult>() {
                        @Override
                        public void onSubscribe(Disposable d) {
    
                        }
    
                        @Override
                        public void onNext(CompareResult compareResult) {//循环录过的所有人脸
    
                            if (compareResult == null || compareResult.getUserName() == null) {
                                requestFeatureStatusMap.put(requestId, CompareResult.FAILED);
                                faceHelper.addName(requestId, "VISITOR " + requestId);
                                return;
                            }
    
                            Log.i(TAG, "onNext: fr search get result  = " + System.currentTimeMillis() + " trackId = " + requestId + "  similar = " + compareResult.getSimilar());
                            if (compareResult.getSimilar() > SIMILAR_THRESHOLD) {//在录入过的人脸中对比找出当前人脸
                                boolean isAdded = false;
                                if (compareResultList == null) {
                                    requestFeatureStatusMap.put(requestId, CompareResult.FAILED);
                                    faceHelper.addName(requestId, "VISITOR " + requestId);
                                    return;
                                }
                                for (CompareResult compareResult1 : compareResultList) {
                                    if (compareResult1.getTrackId() == requestId) {
                                        isAdded = true;
                                        break;
                                    }
                                }
                                if (!isAdded) {
                                    //对于多人脸搜索,假如最大显示数量为 MAX_DETECT_NUM 且有新的人脸进入,则以队列的形式移除
                                    if (compareResultList.size() >= MAX_DETECT_NUM) {
                                        compareResultList.remove(0);
                                        //adapter.notifyItemRemoved(0);
                                    }
                                    //添加显示人员时,保存其trackId
                                    compareResult.setTrackId(requestId);
                                    compareResultList.add(compareResult);
                                    //adapter.notifyItemInserted(compareResultList.size() - 1);
                                }
                                requestFeatureStatusMap.put(requestId, CompareResult.SUCCEED);
                                faceHelper.addName(requestId, compareResult.getUserName());
    
                                sign(compareResult.getUserName(),"name");
    
                            } else {
                                requestFeatureStatusMap.put(requestId, CompareResult.FAILED);
                                faceHelper.addName(requestId, "VISITOR " + requestId);
                            }
                        }
    
                        @Override
                        public void onError(Throwable e) {
                            requestFeatureStatusMap.put(requestId, CompareResult.FAILED);
                        }
    
                        @Override
                        public void onComplete() {
    
                        }
                    });
        }
    
    • 以上就是人脸识别的核心代码了,我本人也是Android 小白一枚,这也算是我在集成过程中一点小心得而已,本人在集成过程中也遇到了很多的问题,也查找了很多的资料,当然还是觉得简书的文章最靠谱了,也希望简书越来越好

    相关文章

      网友评论

          本文标题:Android 集成虹软人脸识别SDK的问题

          本文链接:https://www.haomeiwen.com/subject/uicksctx.html