视觉服务

视觉服务提供了人脸检测,人脸识别,人脸追踪等服务。

人脸检测,检测摄像头画面或目标图片是否有人脸,如果是则返回人脸的位置、大小,人脸角度分析结果。

人脸识别,通过提取人的面部特征,计算两张人脸的相似度,从而判断是否为同一人。

人脸追踪,人脸关键点定位与追踪技术,精确定位并追踪面部轮廓区域位置。

初始化

作为视觉服务访问代理的VisualManager对象,提供了视觉服务的主要API,可通过如下方式获取:

VisualManager mVisualManager = VisualManager.getInstance();
mVisualManager.init(getApplicationContext()); // 需要先初始化

开始一次视觉任务

mVisualManager.start(VisualParam param); // param 为视觉参数

视觉参数构建方法

VisualParam param = new VisualParam.Builder()
                    .requestId(requestId)     // 设置请求ID
                    .requestType(requestType) // 设置请求类型
                    .online(online)           // 是否开启在线人脸识别
                    .showUi(showUi)           // 是否显示界面
                    .timeOut(timeOut)         // 设置超时时间
                    .groupId(groupId)         // 在线人脸识别的企业号组id
                    .imageFile(imageFile)     // 图片识别时传入图片的绝对路径
                    .imagePath(imagePath)     // 人脸拍照时设置照片保存的目录
                    .build();

VisualParam参数描述

类型 参数 参数描述 必填
String requestId 为每次请求的唯一ID,信息回调中返回此ID, 可选参数,默认是生成UUID
int requestType int TYPE_DEFAULT = 0; //人脸注册
int TYPE_RECOGNITION = 1; //人脸识别
int TYPE_DETECTION = 2; //人脸检测
int TYPE_IMAGE= 3; //图片识别,有截图界面
int TYPE_IMAGE_BG= 4; //图片识别,没有截图界面
int TYPE_TAKE_PHOTO= 5; //人脸拍照
(人脸注册时,匹配到人脸时, 在线则返回用户信息,离线则返回已存的人脸ID; 匹配不到人脸时都返回新生成的人脸ID)
boolean online 是否开启在线人脸识别,true为在线人脸识别,false为离线人脸识别。(在线时,需要配置groupId)
boolean showUi 是否显示界面,true为显示扫描框界面,false为无感人脸识别(requestType为人脸追踪时默认为没有界面,忽略此参数)
long timeOut 超时时间,单位毫秒,(<= 0 时为不超时)
String groupId CBI为企业号配置的一个组ID,在线人脸识别是需要配置此项。若更换企业号需要更新groupId。(登录CBI网页,可查看企业号对应的groupId 或者 从用户管理文档中查询状态获取getStatus) 在线必填
String imageFile 图片的绝对路径(请求类型为图片识别) 请求类型为图片识别时 必填
String imagePath 人脸拍照的图片保存目录(请求类型为人脸拍照) 请求类型为人脸拍照时 必填

注:requestType为TYPE_DETECTION = 2 时(人脸检测),采用本地人脸检测,没有扫描框界面,忽略参数online,showUi,groupId。

人脸检测,人脸追踪:

private void faceDetection() {
    VisualParam param = new VisualParam.Builder()
            .requestType(VisualParam.TYPE_DETECTION)
            .build();
    mVisualManager.start(param);
}

离线图片识别:

private void imageRecognizeLocal(String imageFile) {
    VisualParam param = new VisualParam.Builder()
        .requestType(VisualParam.TYPE_IMAGE_BG)
        .imageFile(imageFile)   // 传入图片路径
        .online(false)          // 离线
        .build();
    mVisualManager.start(param);
}

在线图片识别:

private void imageRecognizeOnline(String imageFile, String groupId) {
    VisualParam param = new VisualParam.Builder()
        .requestType(VisualParam.TYPE_IMAGE_BG)
        .imageFile(imageFile)  // 传入图片路径
        .online(true)          // 在线
        .groupId(groupId)      // groupId
        .build();
    mVisualManager.start(param);
}

人脸拍照:

private void takeFacePhoto(boolean showUi, String imagePath) {
    VisualParam param = new VisualParam.Builder()
            .requestType(VisualParam.TYPE_TAKE_PHOTO)
            .showUi(showUi)           // 是否显示界面
            .imagePath(imagePath)     // 设置图片保存的目录
            .build();
    mVisualManager.start(param);
}

停止视觉任务

mVisualManager.stop(); //停止上一次的任务

mVisualManager.stop(String requestId); //停止指定任务,requestId为请求时的唯一ID

监听回调

获取任务结束后的信息,需要注册监听回调

添加监听:

mVisualManager.addListener(VisualListener listener);

移除监听:

mVisualManager.removeListener(VisualListener listener);

注:添加与移除需要配对使用

监听器:

public class MyListener extends VisualListener {
    @Override
    public void onDone(String message) {
        // 根据业务需求解析json
        Log.d(TAG, "onDone : " + message);
        try {
            Result result = new Gson().fromJson(message, Result.class);
            Log.i(TAG, "result : " + result);
        } catch (Exception e) {
            Log.e(TAG, "onDone Exception", e);
        }
    }

    @Override
    public void onFail(int code, String error) {
        // code 为错误码, error 为错误信息
        Log.d(TAG, "onFail code : " + code + ", error : " + error);
    }

    @Override
    public void onProgress(String message) {
        Log.d(TAG, "onProgress : " + message);
    }
}

onDone中返回的Result定义:

类型 参数 参数描述
String requestId 返回值与开始任务视觉参数VisualParam中的requestId一致
int code 人脸识别返回消息码
int DETECT_FAIL = 224; 人脸检测失败
int RECOGNIZE_FAIL= 225; 人脸识别失败
int RECOGNIZE_INTERRUPT = 226; 人脸识别中断
int RECOGNIZE_TIME_OUT= 227; 人脸识别超时
int CAMERA_OPEN_FAIL= 228; 相机打开失败
int CANCEL= 229; 主动取消任务
int IMAGE_EXCEPTION= 230; 图片异常
int RECOGNIZE_FAIL_BROKEN= 8208; 人脸识别阻塞
int PHOTO= 160; 拍照成功
int MATCH= 161; 匹配到人脸库,人脸识别成功
int MISMATCH= 162; 人脸识别没有匹配到人脸库
int EXCEPTION= 163; 人脸识别异常
String message 人脸识别返回消息内容
"fail" 人脸识别没有匹配到人脸库
"success" 人脸识别成功,匹配到人脸库
"exception" 人脸识别异常
"interrupt" 人脸识别中断
"time out;" 人脸识别超时
"cancel" 主动取消任务
"camera open fail" 相机打开失败
"image exception" 图片异常
String faceId 离线人脸识别返回的人脸ID。如查询到匹配的人脸,返回已存的id,否则重新生成UUID。在线人脸识别时可忽略该值。
String imageFile 返回人脸识别时的图片路径位置
PersonDetail personDetail 在线人脸识别: 匹配到人脸返回用户详细信息,包括姓名,性别,称谓,备注,分组,人脸图片地址等,没匹配到人脸返回null; 离线人脸识别:此值返回null

当请求参数为人脸追踪时(requestType = 2),监听回调onProgress中的message:

类型 参数 参数描述
float[] angles 人脸角度,[0] 俯仰角、[1] 左右转角、[2] 倾斜角
Rect rect 人脸的矩形在相机中的位置(注:无扫描框相机分辨率 800 * 600, 有扫描框分辨率1280 * 720)

释放内存

mVisualManager.onDestroy();

视觉服务总开关

// 使能后台相机
public void enableCamera() {
    Intent intent = new Intent();
    intent.putExtra("action", "enable");
    SkillManager skillManager = Robot.globalContext().getSystemService(SkillManager.SERVICE);
    skillManager.dispatchDirective(
            Directive.Builder.fromAction(Directive.SOURCE_INTER_PROCESS, "/visual/setCamera")
                    .setParam(intent, ContentTypes.PARCELABLE)
                    .build())
            .done(aVoid -> Log.i(TAG, "enable done"))
            .fail(e -> Log.e(TAG, "enable fail", e));
}
// 禁用后台相机
public void disadbleCamera() {
    Intent intent = new Intent();
    intent.putExtra("action", "disable");
    SkillManager skillManager = Robot.globalContext().getSystemService(SkillManager.SERVICE);
    skillManager.dispatchDirective(
            Directive.Builder.fromAction(Directive.SOURCE_INTER_PROCESS, "/visual/setCamera")
                    .setParam(intent, ContentTypes.PARCELABLE)
                    .build())
            .done(aVoid -> Log.i(TAG, "disable done"))
            .fail(e -> Log.e(TAG, "disable fail", e));
}