android百度离线人脸识别集成及横屏适配

这篇文章仅仅是为了记录过程,方便下次快速集成使用,不做深究技术讨论

百度的人脸识别地址:

人脸识别_人脸识别_准确率99.99%_免费试用-百度AI开放平台

其次有几个注意事项,百度默认的demo是只支持竖屏的设备,手机或者平板。但是不支持模拟器的,所以不要在模拟器上试运行了。

话不多说,开始集成步骤:

一、注册应用获取环境

1.先打开上面的网址后,选择立即使用,登录上去后,先注册个应用

2. 添加一个授权设备,本地化部署-离线识别sdk-添加序列号

3.当你创建好一个单设备后,就会有两种激活方式,一个是在线激活,一个是离线激活。为了方便我使用在线激活,点击后,在设备上输入激活码即可激活。

4.我这里建议你无论做哪个业务的人脸识别,都去这里下载官方demo

这样你下载的demo是比较全的,既有激活代码(离线激活,在线激活,应用激活),还有闸机,考勤,支付,金融,人证核验,驾驶行为分析,注意力检测,属性八大模式,几乎可以针对各种业务场景了。此外还有人脸注册和人脸库管理两块的代码,可以说是很齐全了,UI也还不错,可以直接CV抠代码。

界面如下: 

非核心的代码都是很容易懂得,可以结合界面看代码。

二、融合代码到现有项目

1.集成环境

首先集成module    facelibray,无论你是哪个场景,这个是最基本的,比如导入。

 导入方式:

1. 拷贝示例代码中的lib下的文件到你的app下的lib里

2.在app下的build.gradle下添加如下代码

3.拷贝facelibray到项目工程下

4.修改settings.gradle如下

5.在app下的build.gradle下添加如下代码

 这样主module和lib都搞定了。接下来就是看你的需要了。

示例demo中有这些library

  1. attendancelibrary 考勤模块
  2. attrbutelibrary 属性模块
  3. drivermonitorlibrary 驾驶行为模块
  4. financelibrary 金融模块
  5. gatelibrary 闸机模块
  6. gazelibrary 注意力模块
  7. identifylibrary 认证核验模块
  8. paymentlibrary 支付模块
  9. registerlibrary 人脸注册和人脸管理模块

依据需要进行依赖,依赖步骤如上的主模块是一样的

 三、在线激活的代码如下 startActivity:

private void initLicense() {
        FaceSDKManager.getInstance().init(mContext, new SdkInitListener() {
            @Override
            public void initStart() {

            }

            public void initLicenseSuccess() {

                TimerTask task = new TimerTask() {
                    @Override
                    public void run() {
                        /**
                         *要执行的操作
                         */
                        startActivity(new Intent(mContext, MainActivity.class));
                        finish();
                    }
                };
                Timer timer = new Timer();
                timer.schedule(task, 2000);
            }

            @Override
            public void initLicenseFail(int errorCode, String msg) {
                TimerTask task = new TimerTask() {
                    @Override
                    public void run() {
                        /**
                         *要执行的操作
                         */
                        startActivity(new Intent(mContext, ActivitionActivity.class));
                        finish();
                    }
                };
                Timer timer = new Timer();
                timer.schedule(task, 2000);
            }

            @Override
            public void initModelSuccess() {
            }

            @Override
            public void initModelFail(int errorCode, String msg) {

            }
        });
    }

其中的init就是从本地sp中获取激活码,如果没有就跳转到激活页面。这个比较简单就不多说了

四、激活进入自己的主页面后,最好初始化下摄像头

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        mContext = this;
        initView();

        initRGBCheck();
}
private void initRGBCheck(){
        if (isSetCameraId()){
            return;
        }
        int mCameraNum = Camera.getNumberOfCameras();
        ToastUtils.toast(mContext,mCameraNum+"个");
        if (mCameraNum > 1){
            try {
                mCamera = new Camera[mCameraNum];
                previewTextures = new PreviewTexture[mCameraNum];
                mCamera[0] = Camera.open(0);
                previewTextures[0] = new PreviewTexture(this, checkRBGTexture);
                previewTextures[0].setCamera(mCamera[0], PREFER_WIDTH, PREFER_HEIGHT);
                mCamera[0].setPreviewCallback(new Camera.PreviewCallback() {
                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {
                        int check = StreamUtil.checkNirRgb(data, PREFER_WIDTH, PREFER_HEIGHT);
                        if (check == 1){
                            setRgbCameraId(0);
                        }
                        release(0);
                    }
                });
            }catch (Exception e){
                e.printStackTrace();
            }
            try {
                mCamera[1] = Camera.open(1);
                previewTextures[1] = new PreviewTexture(this, checkNIRTexture);
                previewTextures[1].setCamera(mCamera[1], PREFER_WIDTH, PREFER_HEIGHT);
                mCamera[1].setPreviewCallback(new Camera.PreviewCallback() {
                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {
                        int check = StreamUtil.checkNirRgb(data, PREFER_WIDTH, PREFER_HEIGHT);
                        if (check == 1){
                            setRgbCameraId(1);
                        }
                        release(1);
                    }
                });
            }catch (Exception e){
                e.printStackTrace();
            }
        } else {
            setRgbCameraId(0);
        }
    }

    private void setRgbCameraId(int index){
        com.baidu.idl.main.facesdk.attendancelibrary.model.SingleBaseConfig.getBaseConfig().setRBGCameraId(index);
        com.baidu.idl.main.facesdk.registerlibrary.user.model.SingleBaseConfig.getBaseConfig().setRBGCameraId(index);

        AttendanceConfigUtils.modityJson();
        RegisterConfigUtils.modityJson();

    }
    private boolean isSetCameraId(){
        if (com.baidu.idl.main.facesdk.attendancelibrary.
                        model.SingleBaseConfig.getBaseConfig().getRBGCameraId() == -1 ||
                com.baidu.idl.main.facesdk.registerlibrary.user.model.
                        SingleBaseConfig.getBaseConfig().getRBGCameraId() == -1){
            return false;
        }else {
            return true;
        }
    }

这些代码是它demo里就有可以拷贝。

五、跳转到对应功能页面

@Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.home_checkRl:
                mLiveType = com.baidu.idl.main.facesdk.attendancelibrary.model.SingleBaseConfig.getBaseConfig().getType();
                // 考勤模块
                judgeLiveType(mLiveType,
                        FaceRGBAttendanceActivity.class,
                        FaceNIRAttendanceActivity.class,
                        FaceDepthAttendanceActivity.class,
                        FaceRGBNirDepthAttendanceActivity.class);
                break;
            case R.id.relative_register: // 人脸注册
                dismissPopupWindow();
                SharedPreferences sharedPreferences = this.getSharedPreferences("type", MODE_PRIVATE);
                mLiveType = sharedPreferences.getInt("type", 0);
                com.baidu.idl.main.facesdk.registerlibrary.user.manager.FaceSDKManager.getInstance().setActiveLog();
                judgeLiveType(mLiveType, FaceRegisterNewActivity.class, FaceRegisterNewNIRActivity.class,
                        FaceRegisterNewDepthActivity.class, FaceRegisterNewRgbNirDepthActivity.class);
                break;
        }
    }


    private void judgeLiveType(int type, Class<?> rgbCls, Class<?> nirCls, Class<?> depthCls, Class<?> rndCls) {
        switch (type) {
            case 0: { // 不使用活体
                startActivity(new Intent(HomeActivity.this, rgbCls));
                break;
            }

            case 1: { // RGB活体
                startActivity(new Intent(HomeActivity.this, rgbCls));
                break;
            }

            case 2: { // NIR活体
                startActivity(new Intent(HomeActivity.this, nirCls));
                break;
            }

            case 3: { // 深度活体
                int cameraType = SingleBaseConfig.getBaseConfig().getCameraType();
                judgeCameraType(cameraType, depthCls);
                break;
            }

            case 4: { // rgb+nir+depth活体
                int cameraType = SingleBaseConfig.getBaseConfig().getCameraType();
                judgeCameraType(cameraType, rndCls);
            }
        }
    }

    private void judgeCameraType(int cameraType, Class<?> depthCls) {
        switch (cameraType) {
            case 1: { // pro
                startActivity(new Intent(HomeActivity.this, depthCls));
                break;
            }

            case 2: { // atlas
                startActivity(new Intent(HomeActivity.this, depthCls));
                break;
            }

            case 6: { // Pico
                //  startActivity(new Intent(HomeActivity.this,
                // PicoFaceDepthLivenessActivity.class));
                break;
            }

            default:
                startActivity(new Intent(HomeActivity.this, depthCls));
                break;
        }
    }

这是点击自己的按钮跳转到各个场景页面的方式。

记得加上权限

<uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission
        android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.hardware.camera.autofocus" />
    <uses-permission
        android:name="android.permission.WRITE_SETTINGS"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature
        android:name="android.hardware.camera.autofocus"
        android:required="true" />
    <uses-feature
        android:name="android.hardware.camera.front"
        android:required="true" />
    <uses-feature
        android:name="android.hardware.camera.front.autofocus"
        android:required="true" />

横屏处理问题:

1.人脸注册:

我是到FaceRegisterNewActivity下,对圆形采相控件进行动态根据屏幕大小设置宽高。

其次因为百度采集人像,还没反应过来就采集成功了,于是我加了个倒计时控件,其实就是个普通文本控件在采相控件的中间。然后用timer+timerTask+handler搞定的

private void initView() {
        tvNum=findViewById(R.id.tv_num); //这是我自己加的倒计时控件,在镜头中心
        mAutoTexturePreviewView = findViewById(R.id.auto_camera_preview_view);
        mFaceRoundProView = findViewById(R.id.round_view);

        // 屏幕的宽
        int displayWidth = DensityUtils.getDisplayWidth(FaceRegisterNewActivity.this);
        // 屏幕的高
        int displayHeight = DensityUtils.getDisplayHeight(FaceRegisterNewActivity.this);

        int min=Math.min(displayWidth,displayHeight);

        ViewGroup.LayoutParams lp1 = mAutoTexturePreviewView.getLayoutParams();
        lp1.width=min-DensityUtils.dip2px(FaceRegisterNewActivity.this,30);
        lp1.height=min-DensityUtils.dip2px(FaceRegisterNewActivity.this,30);
        mAutoTexturePreviewView.setLayoutParams(lp1);

        ViewGroup.LayoutParams lp2 = mFaceRoundProView.getLayoutParams();
        lp2.width=min-DensityUtils.dip2px(FaceRegisterNewActivity.this,30);
        lp2.height=min-DensityUtils.dip2px(FaceRegisterNewActivity.this,30);
        mAutoTexturePreviewView.setLayoutParams(lp2);

        ViewGroup.LayoutParams lp3 = tvNum.getLayoutParams();
        lp3.width=min-DensityUtils.dip2px(FaceRegisterNewActivity.this,30);
        lp3.height=min-DensityUtils.dip2px(FaceRegisterNewActivity.this,30);
        mAutoTexturePreviewView.setLayoutParams(lp3);
        tvNum.setText("3");
        tvNum.setVisibility(View.VISIBLE);

        ....
}

2.业务场景:

到各个场景里,例如这里是考勤的页面,注释掉下面的话,就可以横屏全部了,剩下的无非是调节下小控件的宽高

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;
        initListener();
        FaceSDKManager.getInstance().initDataBases(this);
        setContentView(R.layout.activity_face_rgb_attendancelibrary);
        initView();
        // 屏幕的宽
//        int displayWidth = DensityUtils.getDisplayWidth(mContext);
        // 屏幕的高
//        int displayHeight = DensityUtils.getDisplayHeight(mContext);
        // 当屏幕的宽大于屏幕宽时
//        if (displayHeight < displayWidth) {
//            // 获取高
//            int height = displayHeight;
//            // 获取宽
//            int width = (int) (displayHeight * ((9.0f / 16.0f)));
//            // 设置布局的宽和高
//            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(width, height);
//            // 设置布局居中
//            params.gravity = Gravity.CENTER;
//            relativeLayout.setLayoutParams(params);
//        }
    }

好了,先记录到这,这些基本上可以做到,安卓设备离线情况下,在客户端进行人脸注册,管理人脸库和考勤了

本人个人原创,如有雷同,纯属巧合,或者与本人联系,做改动。请转载或者CV组合标明出处,谢谢!(如有疑问或错误欢迎指出,本人QQ:752231513)

猜你喜欢

转载自blog.csdn.net/qq_30548105/article/details/120566366