NIR近红外活体和3D结构光活体

活体检测包括3种类型:RGB彩色图活体、NIR近红外活体和3D结构光活体。RGB彩色图活体使用普通摄像头图片判断,抵御能力普通,如果对活体有较高要求,建议直接考虑NIR近红外活体和3D结构光活体。

NIR近红外活体需要配备红外双目摄像头,主要通过红外反射形成的红外图像进行判断。3D结构光活体需要配备3D结构光摄像头,通过两个摄像头图片的微小区别形成深度图像,判断虚假平面类的攻击。两种活体判断都需要人脸离摄像头较近且完整的场景。此外,由于红外图像和深度图像与彩色图像之间可能会有位置偏移,因此SDK要求在进行NIR近红外活体和3D结构光活体时,彩色图像的分辨率务必为640×480。

商米不同型号设备摄像头配置选择可能有区别,请咨询商米销售。另外在选择设备和方案阶段,我们很乐于提供一些实际场景应用的经验。

1. NIR近红外活体检测

1.1 NIR近红外活体检测简介

NIR近红外活体检测利用近红外成像原理,比如屏幕无法成像,不同材质反射率不同等,可以抵御手机和照片等多种攻击。

红外成像有多种类型,比较常见的有两种:第一种是inutive模组采集的pattern红外图,这种红外图是带斑点的;与此相对应的是用Boteye模组采集的clean红外图,这种红外图不带斑点是干净的。商米人脸识别SDK使用clean红外图,商米设备配备的红外摄像头都满足红外活体检测要求。

此外,商米人脸识别演示APP中已经预设了商米配置的双目红外摄像头的偏差值,以下三点设置细节可帮助使用其他途径获得的双目摄像头的情况:

  1. RGB和NIR图像分辨率均为640×480。
  2. NIR近红外活体检测需保证RGB图像和IR图像在时间上是对应的。
  3. RGB图和IR图存在一定的位置偏差,以RGB图检测到的人脸位置为参考,IR图在x方向和y方向的偏差如表1.1.1所示。

表1.1.1 IR摄像头偏移情况

IR摄像头型号IR图相比RGB图在x方向的偏移量IR图相比RGB图在y方向的偏移量
1-400
210-10

1.2 NIR活体使用步骤

NIR近红外活体检测是人脸识别基础上的附加功能,在使用 人脸识别Andriod_SDK_1.4 调用人脸识别功能的过程中(特别注意第3.7、3.9和3.15),如需要NIR近红外活体检测功能,依次添加以下四个步骤:

第一步:在第3.7节的配置SDK时,添加对NIR活体检测阈值设定:

param.setNirLivenessThreshold(0.5f); //阈值越高,活体检测越严格,人脸通过活体检测的难度越大
param.setNirXOffset(-40); //根据设备型号设置红外图相对彩色图x方向偏移量
param.setNirYOffset(0); //根据设备型号设置红外图相对彩色图y方向偏移量

第二步:将RGB图的全部通道从Bitmap类型转成字节数组;将IR图的一个通道从Bitmap类型转成字节数组,两组示例代码如下。

RGB图全部通道从Bitmap类型转成字节数组:

public static byte[] getPixelsBGR(Bitmap image) {
    // 计算图片有多少字节
    int bytes = image.getByteCount();

    ByteBuffer buffer = ByteBuffer.allocate(bytes); // 创建新的buffer
    image.copyPixelsToBuffer(buffer); // 移动字节数据到buffer

    byte[] temp = buffer.array(); // 获取包含数据的底层数组
    byte[] pixels = new byte[(temp.length / 4) * 3]; // 分配空间给BGR

    // 对像素重组
    for (int i = 0; i ‹ temp.length / 4; i++) {
        pixels[i * 3] = temp[i * 4 + 2];        //B
        pixels[i * 3 + 1] = temp[i * 4 + 1];    //G
        pixels[i * 3 + 2] = temp[i * 4];        //R
    }
    return pixels;
}

IR图的一个通道从Bitmap类型转成字节数组:

public static byte[] getSingleChannelPixels(Bitmap image){
    if(image == null){return null;}
    int bytes = image.getByteCount();

    ByteBuffer buffer = ByteBuffer.allocate(bytes); // Create a new buffer
    image.copyPixelsToBuffer(buffer); // Move the byte data to the buffer

    byte [] temp = buffer.array();
    byte[] pixels = new byte[(temp.length / 4)];
    for (int i = 0; i ‹ temp.length / 4; i++) {
        pixels[i] = temp[i * 4];
    } 
    return pixels;

}

第三步:检查第3.15节中提到的执行选择功能不是PredictMode_None;再使用SunmiFaceImage构造函数及上一步得到的彩色图字节流和红外图字节流创建SunmiFaceImage实例;最后通过实例中的setLivenessMode方法指定需要进行的活体检测方法:

SunmiFaceImage image = new SunmiFaceImage(RGBData, RGBbitmap.getHeight(), RGBbitmap.getWidth(), IRData, IRHeight, IRWidth, null, null, null, 1);
image.setPredictMode(SunmiFaceMode.PredictMode_Feature);//执行功能选择不能是PredictMode_None
image.setLivenessMode(SunmiFaceLivenessMode.LivenessMode_None);//不进行活体检测
image.setLivenessMode(SunmiFaceLivenessMode.LivenessMode_NIR);//只进行NIR活体检测
image.setLivenessMode(SunmiFaceLivenessMode.LivenessMode_NIR|SunmiFaceLivenessMode.LivenessMode_RGB)//同时进行NIR和RGB活体检测

第四步:获取活体检测分数及SDK返回的响应值:

SunmiFaceImageFeatures features = new SunmiFaceImageFeatures(); //构造空的人脸特征对象
ret = SunmiFaceSDK.getImageFeatures(image, features); //使用人脸识别SDK进行特征提取
SunmiFaceFeature faceFeature = SunmiFaceLib.SunmiFaceFeatureArrayGetItem(features.getFeatures(), 0);  //提取置信度最高的人脸特征信息
float rgb_liveness_score = faceFeature.getRgbLivenessScore(); //获取置信度最高的人脸RGB活体检测分数
float nir_liveness_score = faceFeature.getNirLivenessScore();//获取置信度最高的人脸NIR活体检测分数

开发者可根据不同的需求对rgb_liveness_score和nir_liveness_score进行后续代码逻辑开发。当返回的ret为FACE_CODE_NOT_LIVENESS时,说明SDK根据当前设定的RGB和NIR活体检测阈值认为当前人脸是假脸;而ret为FACE_CODE_OK时说明当前人脸通过了RGB彩色图和NIR近红外活体检测。

2. 3D结构光活体检测

2.1 3D结构光活体检测简介

商米人脸识别SDK使用奥比中光3D结构光摄像头实现3D结构光活体检测功能。3D摄像头采集到的深度图以字节流的形式输出,其中每个像素点占据2个字节,其物理意义为在图像上该点物体到摄像头的距离(距离单位为毫米)。3D结构光活体检测反欺诈能力相对较强,建议安全性要求较高场景选用。

此外,商米人脸识别演示APP中已经预设了商米配置的3D结构光摄像头的偏差值,一般可以直接使用,两种摄像头的参数略有不同,以下三点设置细节可帮助您了解更多:

  1. RGB图像分辨率为 640×480,3D结构光活体检测深度图分辨率如表2.1.1所示。
  2. 3D结构光活体检测需保证RGB图像和深度图像在时间上是对应的。
  3. 彩色图和深度图存在一定的位置偏差,以彩色图检测到的人脸位置为参考,深度图在x方向和y方向的偏差如表2.1.1所示。

表2.1.1 配置3D摄像头的商米设备情况

设备型号3D摄像头型号深度图分辨率深度图相比彩色图在x方向偏移量深度图相比彩色图在y方向偏移量是否旋转
K1Pro A640*48028-20
K2D2plus400*64075-15

2.2 3D结构光活体检测使用步骤

3D结构光活体检测是人脸识别基础上的附加功能,在使用 人脸识别Andriod_SDK_1.6 调用人脸识别功能的过程中(特别注意第3.7、3.9和3.15),如需要3D结构光活体检测功能,依次添加以下四个步骤:

第一步:在第3.7节的配置SDK时,添加对3D结构光活体检测阈值设定:

param.setDepthLivenessThreshold(0.5f); //阈值越高,活体检测越严格,人脸通过活体检测的难度越大
param.setDepthXOffset(75); //根据设备型号设置深度图相对彩色图x方向偏移量
param.setDepthYOffset(-15); //根据设备型号设置深度图相对彩色图y方向偏移量

第二步:根据使用的摄像头型号,Pro A(常见于K1,T2)或D2plus(常见于K2),具体见表2.1.1,确定图像是否需要旋转,需要旋转的进行彩色图和深度图的旋转,最后再把彩色图从Bitmap类型转换成字节数组,示例代码分别如下:

旋转彩色图:

public static Bitmap rotateBitmap(Bitmap origin, float alpha) {
        if (origin == null) {
            return null;
        }
        int width = origin.getWidth();
        int height = origin.getHeight();
        Matrix matrix = new Matrix();
        matrix.setRotate(alpha);
        // 围绕原地进行旋转
        Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
        if (newBM.equals(origin)) {
            return newBM;
        }

        return newBM;
    }

旋转深度图:

public static byte [] rotateDepthImage(byte[] depthByte, int height, int width){
        if(depthByte == null){return null;}

        int depthLen = height * width * 2;
        byte [] newDepth = new byte [depthLen];
        for (int i = 0; i‹=width-1; i++){
            for(int j = 0; j‹=height-1; j++){
                newDepth[2*(i*height+j)] = depthByte[2*((height-1-j)*width+i)];
                newDepth[2*(i*height+j)+1] = depthByte[2*((height-1-j)*width+i)+1];
            }
        }
        return newDepth;
    }

将彩色图从Bitmap类型转成字节数组:

public static byte[] getPixelsBGR(Bitmap image) {
    // 计算图片有多少字节
    int bytes = image.getByteCount();

    ByteBuffer buffer = ByteBuffer.allocate(bytes); // 创建新的buffer
    image.copyPixelsToBuffer(buffer); // 移动字节数据到buffer

    byte[] temp = buffer.array(); // 获取包含数据的底层数组
    byte[] pixels = new byte[(temp.length / 4) * 3]; // 分配空间给BGR

    // 对像素重组
    for (int i = 0; i ‹ temp.length / 4; i++) {
        pixels[i * 3] = temp[i * 4 + 2];        //B
        pixels[i * 3 + 1] = temp[i * 4 + 1];    //G
        pixels[i * 3 + 2] = temp[i * 4];        //R
    }
    return pixels;
}

第三步:检查第3.15节中提到的执行选择功能不是PredictMode_None;再使用SunmiFaceImage构造函数及上一步得到的彩色图字节流和红外图字节流创建SunmiFaceImage实例;最后通过实例中的setLivenessMode方法指定需要进行的活体检测方法:

SunmiFaceImage image = new SunmiFaceImage(RGBData, RGBbitmap.getHeight(), RGBbitmap.getWidth(), null, null, null, DepthData, DepthHeight, DepthWidth, 1);
image.setPredictMode(SunmiFaceMode.PredictMode_Feature);//执行功能选择不能是PredictMode_None
image.setLivenessMode(SunmiFaceLivenessMode.LivenessMode_None);//不进行活体检测
image.setLivenessMode(SunmiFaceLivenessMode.LivenessMode_Depth);//只进行3d活体检测
image.setLivenessMode(SunmiFaceLivenessMode.LivenessMode_Depth|SunmiFaceLivenessMode.LivenessMode_RGB)//同时进行3d和RGB活体检测

第四步:获取活体检测分数及SDK返回的响应值:

SunmiFaceImageFeatures features = new SunmiFaceImageFeatures(); //构造空的人脸特征对象
ret = SunmiFaceSDK.getImageFeatures(image, features); //使用人脸识别SDK进行特征提取
SunmiFaceFeature faceFeature = SunmiFaceLib.SunmiFaceFeatureArrayGetItem(features.getFeatures(), 0);  //提取置信度最高的人脸特征信息
float rgb_liveness_score = faceFeature.getRgbLivenessScore(); //获取置信度最高的人脸RGB活体检测分数
float depth_liveness_score = faceFeature.getDepthLivenessScore();//获取置信度最高的人脸3D活体检测分数

开发者可根据不同的需求对rgb_liveness_score和depth_liveness_score进行后续代码逻辑开发。当返回的ret为FACE_CODE_NOT_LIVENESS时,说明SDK根据当前设定的RGB和3D结构光活体检测阈值认为当前人脸是假脸;而ret为FACE_CODE_OK时说明当前人脸通过了RGB彩色图和3D结构光活体检测。

人脸识别云服务

商米人脸识别云服务是人脸识别离线SDK包产品的配套服务,主要用于客户通过手机端自助互动进行人脸特征值采集,不单独售卖。

商米人脸识别云服务功能仅限于提取不可逆解读人脸特征值字符串,该人脸特征值和商米人脸识别离线SDK包特征值一致。商米人脸识别云服务不提供照片人脸库和人脸特征值库的云端存储。

1. 云端人脸识别API接口服务

商米提供云端人脸识别API接口服务,用户可以用标准的HTTP请求来获取人脸检测框和人脸特征。其中,人脸特征可用于批量构建人脸底库,使用sqlite数据库进行人脸库的存储,其构建表结构如下:

CREATE TABLE SUNMI_FACE (
AUTOID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
                 "ID VARCHAR(64), "
                 "NAME VARCHAR(64), "
                 "IMG_ID VARCHAR(64), "
                 "FEATURE BLOB,"
                 "CreatedTime TimeStamp NOT NULL DEFAULT CURRENT_TIMESTAMP);

数据表中各个字段的赋值,需注意以下几点:

  • ID是用户的唯一标识,同一个用户ID相同,不用用户ID不同。
  • NAME是用户姓名,允许重复。
  • IMG_ID是对应人脸图片在数据库中的唯一标识,不可重复,需要采用UUID0算法生成唯一不重复的uuid。
  • FEATURE是通过人脸API服务获取的人脸特征。

1.1. 人脸检测-请求参数

url地址:请联系商米获取云服务的url 地址

参数名称是否必选类型默认值说明
imagestring/图片信息 (总数据大小应小于2M),图片上传方式根据image_type来判断
image_typestring/图片类型 BASE64:图片的base64值。base64编码后的图片数据,其图片大小不超过2M;URL:图片的 URL地址(可能由于网络等原因导致下载图片时间过长)
max_face_countint1最多处理人脸的数目,默认值为1,仅检测图片中人脸置信度最高的那个人脸;最大值10,检测图片中面积最大的几张人脸。
predict_modeint参考下面的预测模式定义。7即为默认人脸检测+人脸特征+人脸属性。(年龄和性别都包含在人脸属性中)

预测模式定义示例代码如下:

typedef enum {
    PredictMode_None = 0,
    PredictMode_Detect = 1 ‹‹ 0,                                // face detect
    PredictMode_Feature = (1 ‹‹ 1) + PredictMode_Detect,        // face detect and extract features
    PredictMode_Age = (1 ‹‹ 2) + PredictMode_Detect,            // face detect and age predict
    PredictMode_Gender = PredictMode_Age,                       // face detect and gender predict
} SunmiFaceMode;

1.2. 人脸识别API返回数据

字段必选类型说明
face_numint检测到的图片中的人脸数量
face_listarray人脸信息列表,具体参数参考下面的列表
+locationarray人脸在图片中的位置
++leftdouble人脸框左上角x坐标
++topdouble人脸框左上角y坐标
++widthdouble人脸框宽度
++heightdouble人脸框高度
+ face_probabilitydouble人脸置信度
+ anglearray人脸旋转角度
++ yawdouble左右旋转角[-90(左), 90(右)]
++ pitchdouble俯仰旋转角[-90(上), 90(下)]
++ rolldouble平面内旋转角[-90(逆时针), 90(顺时针)]
+ landmarkarray5个关键点位置,左眼中心、右眼中心、鼻尖、左嘴角,右嘴角。
+ liveness_scoredouble2D活体检测得分,值越高说明是真人的概率高
+ featurearray人脸256维特征值

返回结果如为json格式,如以下示例:

{
    "face_num": 1,
    "face_list": [
        {
            "location": {
                "left": 216.1408233642578,
                "top": 157.1695556640625,
                "width": 90.74900817871094,
                "height": 115.81448364257812
            },
            "face_probability": 0.9972383975982666,
            "angle": {
                "yaw": 5.858273506164551,
                "pitch": 19.634262084960938,
                "roll": -1.6777983903884888
            },
            "landmark": [
                {
                    "x": 239.48606872558594,
                    "y": 203.29200744628906
                },
                {
                    "x": 280.5645446777344,
                    "y": 203.55821228027344
                },
                {
                    "x": 258.20745849609375,
                    "y": 226.3636016845703
                },
                {
                    "x": 242.2882080078125,
                    "y": 243.4677734375
                },
                {
                    "x": 276.392333984375,
                    "y": 243.5858917236328
                }
            ],
            "liveness_score": 0.9542617797851562,
            "gender_info": {
                "gender": "female",
                "score": 1.0
            },
            "age_info": {
                "age": 25,
                "score": 0.8857287168502808
            },
            "feature": [
                0.0012834692606702447,
                0.027195502072572708,
                -0.1606169044971466,
                -0.1035875454545021,
                -0.055142492055892944,
                …
                0.043723493814468384,
                0.07170124351978302,
                -0.10330264270305634
            ]
        }
    ]
}

1.3. 人脸识别API返回状态码

因API不提供自定义配置参数设置,如SDK中的人脸姿态阈值、光照阈值等,在API中均采用默认值,而FACE_CODE_BAD_ILLUMINATION,FACE_CODE_POSE_ERROR等依赖配置参数,所以下表提供的返回值仅针对默认配置参数。

人脸姿态可直接根据返回的json中的“angle”字段进行判断,人脸大小可根据“location”字段判断。

商米人脸识别状态码如下表所示:

枚举成员状态码说明
FACE_CODE_OK0正确
FACE_CODE_UNINIT1SDK没有初始化
FACE_CODE_EMPTY_IMAGE2图片为空
FACE_CODE_NO_MODEL3无加载模型文件
FACE_CODE_CONFIG_ERROR4配置错误
FACE_CODE_BAD_ILLUMINATION5光线条件不好
FACE_CODE_POSE_ERROR6面部位置不符合要求
FACE_CODE_SMALL_FACE_SIZE7人脸尺寸太小
FACE_CODE_LOW_IMAGE_QUALITY8人脸图像模糊
FACE_CODE_NOT_LIVENESS9非活体人脸图像
FACE_CODE_LICENSE_ERROR10授权文件无效
FACE_CODE_LICENSE_EXPIRED11授权文件过期
FACE_CODE_IMAGE_ID_ERROR101删除时图像id不存在
FACE_CODE_OTHER_ERROR1000其他错误

2. Python示例代码

2.1. 图片采用BASE64格式

对于BASE64格式的图片,使用如下示例进行API接口的调用,获取url请联系商米工作人员:

import numpy as np
import cv2
import requests
import base64
import json
​
if __name__ == '__main__':
    url = "****"
    with open("test.jpg", "rb") as f:
        base64_data = base64.b64encode(f.read())
    data = {"image": base64_data, "image_type": "BASE64", "max_face_count": 1}
    r = requests.post(url, data=data)
    s = json.loads(r.content)
    print(s['msg'])

2.2. 图片采用URL格式

对于URL格式的图片,使用如下示例进行API接口的调用:

import numpy as np
import cv2
import requests
import base64
import json
​
if __name__ == '__main__':
    url = "****"
    data = {"image": "https://wifi.cdn.sunmi.com/UAT/IMG/FACE/AM4RDZ2LP5HWTIJ8G70KN8NFNY0766WK1", "image_type": "URL", "max_face_count": 1}
    r = requests.post(url, data=data)
    s = json.loads(r.content)
    print(s['msg'])

试用&购买授权

商米人脸识别SDK的试用和购买都需要获得设备授权,试用授权主要用于调试阶段,一般软件开发方可以免费获得1-3台设备的三个月试用授权,购买授权将获得设备的终身授权。

请联系您的商米销售获取试用授权或者直接购买授权,若无专属销售,请邮件发送详细需求至AI部门(meijuan@sunmi.com)获取试用授权。另,若设备可正常连接wifi,推荐使用第一种远程授权方式,操作更简便快速。

1.授权方式

1.1 远程授权

1.获取设备SN号发送给商米,并保持设备有线网在线wifi在线
2.商米将通过远程协助功能,发送授权文件至设备,默认路径为” /sdcard/SunmiRemoteFiles/license_face.txt “;
3.重启APP即可试用。

注:1)若三个月免费授权到期,可联系商米继续申请三个月免费授权,一般商米提供试用授权至开发调试结束。
2) 远程授权默认路径为”/sdcard/SunmiRemoteFiles/license_face.txt”, 开发者可根据需求移动授权文件,可以存放在SD卡某个路径下,也可以存放在APP文件路径下 ,能够被正常读取即可。
3)通过wifi在线授权,之后在使用过程中需要保持wifi开关为打开状态(无需联网)。

1.2 离线授权

1. 取设备硬件指纹信息发送给商米,具体有以下两种方式:

方式一:通过调用”商米人脸识别SDK”的接口获取硬件指纹信息,示例代码如下:

String fingerprint = SunmiFaceSDK.getDeviceFingerprint(context);

方式二:通过”adb命令”获取硬件指纹,命令行代码如下(SN示例:E26J117D3520363 ):

adb -s E26J117D3520363 pull /sdcard/device_fingerprint.txt ./
// 注:运行一次demo APP后,在/sdcard下面会生成device_fingerprint.txt,即可获得硬件指纹。

2.商米将根据硬件指纹信息提供授权文件” license_face.txt “;

3.将 ” license_face.txt ” 授权文件上传至APP可读取路径,命令行代码如下:

adb -s E26J117D3520363 push license_face.txt /sdcard/SunmiRemoteFiles

注:1) 需保证wifi开关为打开状态
2)建议上传至路径”/sdcard/SunmiRemoteFiles/license_face.txt”(与远程授权路径保持一致,若无 SunmiRemoteFiles文件夹,可自行创建)
3)”E26J117D3520363 “为示例SN号,需要修改成当前设备的SN号;

2. Demo试用

2.1 SunmiSDKDemo的安装

Step1:确保adb命令已安装。如没有安装,可参考如下步骤安装。

  • Mac:在Terminal终端,使用“brew cask android-platform-tools”命令进行安装。
  • Windows:将包含adb工具的文件夹路径配置到环境变量中即可。

安装完成打开cmd终端,输入“adb”命令进行查看,出现版本信息则可正常使用。

Step2:连接商米设备,使用“adb devices”命令查看设备名称。

Step3:使用“cd”命令进入到apk的存放路径,使用“adb -s E26J117D3520363 install app-debug.apk”安装apk。(注:如果设备上已安装人脸识别apk,则会显示安装失败,apk的名称已最新发布为准)。

Step4:获取授权,保持设备在线并发送SN号给商米,可远程获取授权。

具体可参考上文授权方式,若无法连接wifi,可使用离线授权方式。

Step5:使用“adb -s E26J117D3520363 logcat”命令查看log。

2.2 SunmiSDKDemo的使用

在Demo使用前,请打开apk的所有权限。开启APP时会显示“初始化人脸识别API成功”,则说明设备已授权,Demo可正常使用。

注:很多错误的原因都是权限问题。

2.2.1 人脸注册

在识别人员身份前,先要为人员进行注册。请被采集人来到摄像头前,使用如下步骤注册人脸到离线人脸库:

  1. 点击“人脸注册”
  2. 输入“会员ID”
  3. 点击“开始采集人脸”
  4. 点击“为会员拍照”

2.2.2 人脸识别

人脸识别模块主要包含实时识别功能,具体操作步骤如下:

  1. 点击“人脸识别”
  2. 点击“开始识别”, 如检测到人脸库中人员,屏幕左上方将显示人员入库时的原始照片;否则会显示“该用户尚未注册为会员”。

注:1)建议使用红外摄像头进行人脸识别时,非使用状态及时退出APP防止长时间使用导致摄像头过热损坏。
2)若正常人脸识别过程中, 屏幕左上方显示“未检测到人脸特征”,需检查授权文件是否有效。

2.2.3 人证比对

人证比对模块包含“拍摄身份证比对”和“选择身份证照片”比对两个功能,具体操作步骤如下:

拍摄身份证比对:

  1. 点击“拍摄身份证”;
  2. 点击“开始核验”,可实时进行比对,并在左上方显示比对结果。

选择身份证照片比对:

  1. 通过“浏览”获取照片路径;
  2. 点击“获取身份证照片特征”进行特征提取,提取成功之后会直接进入到识别界面;
  3. 点击“开始核验”,可实时进行比对,并在左上方显示比对结果。

2.2.4 人脸库管理

人脸库管理模块主要包括人脸注册信息的搜索、查看和删除等基本功能。

  1. 输入查询的用户名,点击“搜索”进行人脸记录查询;
  2. 对于单行人脸记录,点击“查看”,则显示人脸注册时录入的照片;
  3. 点击“删除”,则删除此行人脸记录,此用户将无法被识别。

常见问题

1.SDK下载和Demo从哪下载?
可以在页面上直接下载:https://docs.sunmi.com/sbs-value-add/facesdk/

2. 使用授权码,显示注册失败?
检查是不是1.3.0以上版本的sdk;检查wifi开关是否打开。

3.正常识别的人脸阈值调到多少合适?
阈值设为0.9

4.识别距离有点远,改变哪个参数可以调近一点?
通过接口返回的人脸框大小来筛选。SunmiFaceConfigParam里设置setMinFaceSize,如果脸小于这个尺寸就会返回code=FACE_CODE_SMALL_FACE_SIZE

5.SDK对于识别人脸的数量有没有上限(本地保存人脸的数量)?
测试过8K底库,基本可以达到实时识别

6.人脸底片有无规格参数?
人脸sdk只要一个格式BGR的图像buffer作为参数即可。

7.离线sdk,我们有办法把人脸数据上传到云端统一管理吗?
人脸识别很多情况下都是要私域使用,所以在自身的账户系统增加一个人脸数据和图片管理,做一个简单的各个设备同步能实现云端统一管理。我们的云端考虑的大部分客户对隐私的需求,不提供云端人脸库管理功能

8. sdk里面为什么没有so文件?
so文件已经包含在了facelib-v1.3.0.aar里面了,so路径不用改,保持原样就好

错误码

常见错误码如下:

枚举成员状态码说明
FACE_CODE_OK0正确
FACE_CODE_UNINIT1SDK没有初始化
FACE_CODE_EMPTY_IMAGE2图片为空
FACE_CODE_NO_MODEL3无加载模型文件
FACE_CODE_CONFIG_ERROR4配置错误
FACE_CODE_BAD_ILLUMINATION5光线条件不好
FACE_CODE_POSE_ERROR6面部位置不符合要求
FACE_CODE_SMALL_FACE_SIZE7人脸尺寸太小
FACE_CODE_LOW_IMAGE_QUALITY8人脸图像模糊
FACE_CODE_NOT_LIVENESS9非活体人脸图像
FACE_CODE_LICENSE_ERROR10授权文件无效
FACE_CODE_LICENSE_EXPIRED11授权文件过期
FACE_CODE_FACE_DB_ERROR 12人脸库加载失败
FACE_CODE_IMAGE_ID_ERROR101删除时图像id不存在
FACE_CODE_OTHER_ERROR1000其他错误

人脸识别Andriod_SDK_1.6

商米人脸识别DemoAPP_v1.6.2(47.1M):下载
商米人脸识别SDK包_v1.6.1(37.1M):下载

注意:使用1.3.1开发包的用户请参考对应文档:人脸识别Andriod_SDK_1.3

1. 概述

商米人脸识别SDK是一种面向安卓设备的人脸技术开发包。此SDK开发包包含人脸检测、人脸识别和人证比对等功能,以aar包+models的形式发布。本文档介绍了SDK的使用说明以及数据结构和接口的定义,便于开发者在调用SDK接口时参考。

1.1.文档使用范围

该人脸识别接口文档主要适用于人脸识别开发的相关人员参考阅读。

1.2.功能清单

商米人脸识别SDK主要提供如下功能:

模块功能
人脸检测检测图片中出现人脸的位置,并标记出人脸的五个关键点位置
人脸识别将当前人脸和数据库中的人脸进行匹配,确定当前人脸身份信息
人证比对采集身份证上的照片,并且判断当前人脸是否和身份证上的人脸匹配
人脸属性预测根据图片上出现的脸,预测人的性别及年龄
活体检测判断图片上出现的脸是否来自于真人;当采用3D摄像头时预测结果更准确

1.3. 开发包SDK的说明

商米人脸识别SDK包含sunmi_facelib.aar文件和models文件夹。其中models文件夹包含一个配置文件和六个模型文件:

文件/文件夹名说明
sunmi_facelib.aarSDK lib库相关代码的aar
models配置文件:config.json,模型文件:face.json、face.params、detect.json、detect.params、rgb_liveness.json、rgb_liveness.params、depth_detector.yml、attribute.json、attribute.params、nir_liveness.json、nir_liveness.params

注: 商米人脸识别SDK 只有一个实例,是线程不可重入的。只能同时由一个线程调用,不能在多个线程里面同时调用。

2. 环境信息

系统环境平台编译环境
Android7及以上arm32, arm64NDK

3. JavaSDK使用说明

3.1. 获取授权文件

商米人脸识别SDK的授权需要绑定Android系统信息。在第一次使用前,开发者需要获取人脸识别SDK的license授权文件,请参考文档 授权&购买授权

3.2. 导入SDK

在Android Studio项目中导入SDK aar包即可。

3.3. 存放模型文件

模型文件(.json和.params文件)可以存放在SD卡某个路径下,也可以存放在APP文件路径下。请务必保证模型所在路径可以被访问。

3.4. 配置config.json文件

使用模型包中config.json文件作为模板,或者自行创建一个config.json文件,拷贝如下代码。根据3.3中11个文件face.json、face.params、detect.json、detect.params、rgb_liveness.json、rgb_liveness.params、nir_liveness.json、nir_liveness.params、depth_detector.yml、attribute.json和attribute.params存放的实际路径进行修改。SDK需通过读取此config.json配置文件进行初始化。

{  
	// 人脸识别库文件,此文件在SDK Jnilibs里,一般不需要修改
	"face_lib_path":"libface.so", 
	// 人脸识别库网络描述文件,需要绝对路径 
	"face_graph_path":"/storage/emulated/0/faceTest/face.json",  
	// 人脸识别库网络参数文件,需要绝对路径 
	"face_param_path":"/storage/emulated/0/faceTest/face.params",  
	// 人脸检测库文件,此文件在SDK Jnilibs里,一般不需要修改  
	"detect_lib_path":"libdetect.so", 
	// 人脸检测库网络描述文件,需要绝对路径 
	"detect_graph_path":"/storage/emulated/0/faceTest/detect.json",  
	// 人脸检测库网络参数文件,需要绝对路径 
	"detect_param_path":"/storage/emulated/0/faceTest/detect.params",  
	// rgb活体检测库文件,此文件在SDK Jnilibs里,一般不需要修改 
	"rgb_liveness_lib_path":"librgb_liveness.so",  
	// rgb活体检测库网络描述文件,需要绝对路径
	"rgb_liveness_graph_path":"/storage/emulated/0/faceTest/rgb_liveness.json",
	// rgb活体检测库网络参数文件,需要绝对路径
	"rgb_liveness_param_path":"/storage/emulated/0/faceTest/rgb_liveness.params",
	// nir活体检测库文件,此文件在SDK Jnilibs里,一般不需要修改
	"nir_liveness_lib_path":"libnir_liveness.so"
	// nir活体检测库网络描述文件,需要绝对路径 
	"nir_liveness_graph_path":"/storage/emulated/0/faceTest/nir_liveness.json",
	// nir活体检测库网络参数文件,需要绝对路径
	"nir_liveness_param_path":"/storage/emulated/0/faceTest/nir_liveness.params",
	// 人脸库存放路径,需要绝对路径  
	"face_db_file":"/storage/emulated/0/faceTest/sunmi_face.db", 
	// 3D活体检测模型,需要绝对路径
	"depth_detector":"/storage/emulated/0/faceTest/depth_detector.yml"
	// 人脸属性预测库文件,此文件在SDK Jnilibs里,一般不需要修改
	"attr_lib_path":"libattribute.so",
	// 人脸属性预测网络描述文件,需要绝对路径
	"attr_graph_path":"/storage/emulated/0/faceTest/attribute.json",
	//  人脸属性预测库网络参数文件,需要绝对路径
	"attr_param_path":"/storage/emulated/0/faceTest/attribute.params",
}

3.5. 始化SDK

以下为SDK调用init接口执行初始化的示例。init接口参数为3.4中的config.json文件的路径。

String confPath = Environment.getExternalStorageDirectory() + 
"/faceTest/config.json";
int code = SunmiFaceSDK.init(confPath);

3.6. 验证授权文件

使用类似如下代码读取授权文件内容到Java String中,再通过verifyLicense接口验证。若验证通过,可正常调用SDK其他接口。若验证失败,调用SDK其他接口将返回授权错误代码。错误代码为“10”,则表示授权文件无效;错误代码为“11”,则表示授权文件过期。如有授权问题,请联系商米解决。
注:需保证wifi开关为打开状态。

String license = readToString(Environment.getExternalStorageDirectory() + 
"/faceTest/license_face.txt");
int code = SunmiFaceSDK.verifyLicense(context, license); // context为Android Context

3.7. 配置SDK

商米人脸识别SDK参数都可动态配置,建议先通过getConfig得到当前参数,根据需要将参数修改完成后,再用setConfig接口进行设置。示例代码如下:

SunmiFaceConfigParam param = new SunmiFaceConfigParam();
SunmiFaceSDK.getConfig(param);
param.setDistanceThreshold(0.9f); //当SDK应用于支付场景,推荐值是0.9;当应用于人证比对场景时,推荐值为1.1;阈值越小,SDK对于相同人的判定越严格
param.setYawThreshold(50.0f);//人脸姿态阈值,设置较小的人脸姿态阈值,阈值越小,人脸姿态要求越严格,保证相对正面的人脸姿态做识别
param.setPitchThreshold(50.0f);
param.setRollThreshold(50.0f);
param.setMinFaceSize(60);//最小人脸检测尺寸,较大较清晰的人脸识别较准确
param.setImageQualityThreshold(10);//阈值越高,人脸清晰度越好,人脸识别越准确
param.setMinLuminance(10);//最小光照
param.setMaxLuminance(180);//最大光照
param.setThreadNum(1); //使用一个cpu核心执行人脸检测,人脸识别
int code = SunmiFaceSDK.setConfig(param);

3.8 释放内存

在SDK调用过程中,通过调用SunmiFaceFeatureArrayGetItem和SunmiFaceLmkArrayGetItem方法得到的对象,可调用delete方法手动立即释放内存。如果未调用delete方法,java垃圾回收会自动释放内存 。示例代码如下:

SunmiFaceFeature faceFeature = SunmiFaceLib.SunmiFaceFeatureArrayGetItem(features.getFeatures(), 0);
feature.delete();

3.9. 提取人脸特征

提取步骤:

  1. 获取的Bitmap图片:用户根据需求,从摄像头获取bitmap传给SDK。
  2. 传入图片的尺寸:人脸SDK检测最佳输入图的宽高比为1:1。若宽高比过大,可能导致检测性能略微下降。
  3. 图像格式处理:将获取的Bitmap图片转为BGR byte buffer格式。(可参考如下示例代码)
  4. 接口调用:传入BGR byte buffer,通过SunmiFaceImage构造函数创建SunmiFaceImage。再通过getImageFeatures接口传入SunmiFaceImage图片数据,得到SunmiFaceImageFeatures人脸结果。
  5. 多人脸识别逻辑:如果有多张人脸,SunmiFaceFeature在SunmiFaceImageFeatures中按照置信度score从高到低排列。
  6. 人脸库记录:faceFeature2FaceDBRecord把得到的人脸特征转换为人脸库的记录,设置相关ID,name。
  7. 资源释放:SunmiFaceImageFeatures在SDK中动态分配内存空间,使用完毕后需要调用接口释放资源。

示例代码如下:

public static byte[] getPixelsBGR(Bitmap image) {
    // 计算图片有多少字节
    int bytes = image.getByteCount();

    ByteBuffer buffer = ByteBuffer.allocate(bytes); // 创建新的buffer
    image.copyPixelsToBuffer(buffer); // 移动字节数据到buffer
    byte[] temp = buffer.array(); // 获取包含数据的底层数组
    byte[] pixels = new byte[(temp.length / 4) * 3]; // 分配空间给BGR

    // 对像素重组
    for (int i = 0; i < temp.length / 4; i++){
        pixels[i * 3] = temp[i * 4 + 2]; //B
        pixels[i * 3 + 1] = temp[i * 4 + 1]; //G
        pixels[i * 3 + 2] = temp[i * 4]; //R
    }
    return pixels;
}
private void addFeature(String name) {
    if (bitmap == null) {
        Toast.makeText(context, "请先拍照", Toast.LENGTH_SHORT).show();
        return;
    }
    byte[] srcData = FileUtils.getPixelsBGR(bitmap);
    SunmiFaceImage image = new SunmiFaceImage(srcData, bitmap.getHeight(), bitmap.getWidth(), 1);
    SunmiFaceImageFeatures features = new SunmiFaceImageFeatures();
    SunmiFaceSDK.getImageFeatures(image, features);
    SunmiFaceFeature feature_ary = features.getFeatures();
    Log.e("ma", "face info: " + features.getFeaturesCount());
    if (features.getFeaturesCount() == 0) {
        showId("没有检测到人脸,请重新拍照!");
        return;
    }
    SunmiFaceFeature feature = SunmiFaceLib.SunmiFaceFeatureArrayGetItem(feature_ary, 0);
    SunmiFaceDBRecord record = SunmiFaceSDK.faceFeature2FaceDBRecord(feature);
    record.setId(name);
    record.setName(name);
    SunmiFaceSDK.addDBRecord(record);
    SunmiFaceSDK.releaseImageFeatures(features);
    Log.e("face", "采集成功 " + etName.getText().toString());
    feature.delete();
}

3.10. 人脸库添加人脸特征

注意:商米人脸识别SDK包产品中的离线人脸库只存不可逆的人脸特征值,并不存储原始照片,在每次识别过程中也不存储照片。

SunmiFaceDBRecord包含img_id_、id和name三个参数,其中img_id_无需设置,id和name需要调用者进行设置:

  1. img_id_无需设置。调用addDBRecord将记录成功加入到人脸库后,SunmiFaceDBRecord中img_id_会自动被设置为人脸库中代表此图片的唯一id。img_id_可以理解为录入图片的唯一名字,SDK保证返回的img_id不重复。用户可以以img_id为文件名来保存拍摄的人脸照片。根据此img_id可以调用deleteDBRecord来删除这条记录。
  2. id为被录入人脸的人员的唯一id。SDK考虑开发者调用的灵活性,没有对其唯一性进行限制。在通常情况下,建议调用者务必保证id的唯一性,id可理解为一般不会重号的身份证号,食堂卡号,会员号等。
  3. name可以不唯一,允许出现两个人名相同的情况,同时允许每个人录入多张人脸。

示例:
数据库中记录:
用户A,id为0001,姓名张三,图片1,图片2;
用户B, id为0002,姓名也是张三,图片3,图片4,图片5。
用户A和B同名,并且都有多张图片,存储每张图片提取的人脸特征。

注:通常在私域情形下,在被采集人知情情况下,建议将被识别的人脸底图存储于安全位置, 推荐采用addDBRecord接口返回的SunmiFaceDBRecord里面的getImgId()来命名图片,以绑定图片和人脸库中人脸特征,方便后期对人脸库进行相关操作和比对 

3.11.  获取人脸关键点

通过getLandmark_得到人脸关键点数组,在获取数组中的每个关键点信息。示例代码如下:

SunmiFaceFeature feature = SunmiFaceLib.SunmiFaceFeatureArrayGetItem(feature_ary, 0);
SunmiFaceLmk lmk_ary = feature.getLandmark();
for(int i = 0; i ‹ SunmiFaceLibConstants.SUNMI_FACE_LANDMARK_LEN; i++) {
    SunmiFaceLmk lmk = SunmiFaceLib.SunmiFaceLmkArrayGetItem(lmk_ary, i);
    lmk.delete();
}
feature.delete();

3.12. 搜索人脸库

调用searchDB执行人脸库搜索寻找最相似的人脸。如果SDK判断人脸距离小于阈值,matched设为true,否则为false。示例代码如下:

SunmiFaceDBRecord record = SunmiFaceSDK.faceFeature2FaceDBRecord(feature);
SunmiFaceDBIdInfo info = new SunmiFaceDBIdInfo();
SunmiFaceSDK.searchDB(record, info);
if (info.getIsMatched()) {
	Log.e("ma", “Found”);
}
else {
Log.e("ma", “Not Found”);
}

3.13. 人脸1:1比对

分别对要比对的两张图片进行人脸特征的提取,得到类型为SunmiFaceFeature两个人脸特征feature1,feature2。在调用compare1v1接口得到比对结果。getIsMatched()得到比对结果,getDistance()得到两张人脸的距离度量。

SunmiFaceCompareResult result;
int code = SunmiFaceSDK.compare1v1(feature1, feature2, result)
boolean isMatched = result.getIsMatched()
float distance = result.getDistance();

3.14. 获取人脸属性

人脸属性首先需要获取人脸特征faceFeature,再根据人脸特征获取年龄和性别属性,主要示例代码如下:

SunmiFaceFeature faceFeature = SunmiFaceLib.SunmiFaceFeatureArrayGetItem(features.getFeatures(), 0);
SunmiFaceAge ageInfo = faceFeature.getAge();
int age = ageInfo.getClassification();
float ageScore = ageInfo.getScore();
SunmiFaceGender genderInfo = faceFeature.getGender();
int gender = genderInfo.getClassification();
float genderScore = genderInfo.getScore();
feature.delete();

3.15. 执行功能选择

功能选择是为了方便开发者在实际开发中只选择所需的SDK功能,减少计算资源和时间的浪费。该功能可通过SunmiFaceImage中定义的predict_mode_成员进行控制。

例如:在3.9和3.14中,分别介绍了商米人脸识别SDK提取人脸特征和人脸属性获取的功能。实际上,SDK在这两小节提供的代码中同时完成了人脸检测、人脸特征提取及人脸属性识别。若开发者只需使用其中一个,三个功能同时进行会极大地浪费计算资源和时间。因此,可以使用功能选择进行控制,主要示例代码如下:

image = new SunmiFaceImage(srcData, bitmap.getHeight(), bitmap.getWidth(), 1);   //根据bitmap创建SunmiFaceImage对象
SunmiFaceImageFeatures features = new SunmiFaceImageFeatures();   //创建空的SunmiFaceImageFeatures对象
image.setPredictMode(SunmiFaceMode.PredictMode_Age);    //只进行年龄预测
image.setPredictMode(SunmiFaceMode.PredictMode_Feature);    //只进行特征提取
image.setPredictMode(SunmiFaceMode.PredictMode_Detect);    //只进行人脸检测
image.setPredictMode(SunmiFaceMode.PredictMode_Age|SunmiFaceMode.PredictMode_Feature);    //进行人脸特征提取和年龄预测
image.setPredictMode(SunmiFaceMode.PredictMode_Age|SunmiFaceMode.PredictMode_Feature|PredictMode_Gender);    //进行人脸特征提取及年龄性别预测,即执行SDK的全部功能,此行代码可以不写,SDK默认模式为执行全部功能
ret = SunmiFaceSDK.getImageFeatures(image, features);    //根据选择的模式提取相应特征

3.16. 活体检测

SDK支持三种活体检测,分别是RGB彩色图活体检测、NIR近红外活体检测和3D结构光活体检测,目前SDK仅支持在同一时刻做一种活体检测。由于NIR近红外和3D结构光活体检测对摄像头设备及SDK配置有特定要求,因此本文主要介绍RGB彩色图活体检测,NIR近红外活体和3D结构光活体检测可通过以下链接参考文档 NIR近红外和3D结构光活体检测

RGB彩色图活体使用普通摄像头图片判断,抵御能力普通,此外由于RGB彩色图活体检测需要考虑脸部的细节信息,因此要求适配的摄像头需支持720p以上的分辨率。如果场景对活体有较高要求,建议直接考虑NIR近红外活体和3D结构光活体。

如需要启用RGB彩色图活体检测功能,可依次添加以下三个步骤:

第一步: 在第3.7节的配置SDK时 ,添加对RGB彩色图活体检测阈值设定:

param.setRgbLivenessThreshold(0.5f); //阈值越高,活体检测越严格,人脸通过活体检测的难度越大

第二步:检查第3.15节中提到的执行选择功能不是PredictMode_None ,并且在第3.9节中提到的用SunmiFaceImage构造函数创建SunmiFaceImage实例后,通过实例中的setLivenessMode方法指定需要进行的活体检测方法:

SunmiFaceImage image = new SunmiFaceImage(srcData, bitmap.getHeight(), bitmap.getWidth(), 1);
image.setPredictMode(SunmiFaceMode.PredictMode_Feature);//执行功能选择不能是PredictMode_None
image.setLivenessMode(SunmiFaceLivenessMode.LivenessMode_None);//不进行活体检测
image.setLivenessMode(SunmiFaceLivenessMode.LivenessMode_RGB);//只进行RGB活体检测

第三步:获取活体检测分数及SDK返回的响应值:

SunmiFaceImageFeatures features = new SunmiFaceImageFeatures(); //构造空的人脸特征对象
ret = SunmiFaceSDK.getImageFeatures(image, features); //使用人脸识别SDK进行特征提取
SunmiFaceFeature faceFeature = SunmiFaceLib.SunmiFaceFeatureArrayGetItem(features.getFeatures(), 0);  //提取置信度最高的人脸特征信息
float rgb_liveness_score = faceFeature.getRgbLivenessScore(); //获取置信度最高的人脸活体检测分数
feature.delete();

开发者可根据自己的需求对rgb_liveness_score进行后续代码逻辑开发。当返回的ret为FACE_CODE_NOT_LIVENESS时,说明SDK根据当前设定的活体检测阈值认为当前人脸是假脸;而ret为FACE_CODE_OK时说明当前人脸通过了活体检测。

4. 数据类型定义

4.1. 类型别名

别名类型说明
SunmiFaceStatusintTypedef,定义在face_type.h 文件中
SunmiFaceHandlevoid*Typedef,定义在face.h 文件中

4.2. 宏

接口使用的数据类型定义在face_type.h头文件中,主要数据如下:

成员说明
SUNMI_FACE_FEATURE_LEN256人脸特征向量长度
SUNMI_FACE_ID_LEN64id字符长度限制
SUNMI_FACE_NAME_LEN64人脸用户名长度
SUNMI_FACE_IMG_ID_LEN64人脸采集图片ID长度
SUNMI_FACE_LANDMARK_LEN5人脸关键点数量

4.3. 枚举类型

接口使用的数据结构定义在face_type.h头文件中。

4.3.1. SunmiFaceStatusCode 商米人脸识别状态码

枚举成员状态码说明
FACE_CODE_OK0正确
FACE_CODE_UNINIT1SDK没有初始化
FACE_CODE_EMPTY_IMAGE2图片为空
FACE_CODE_NO_MODEL3无加载模型文件
FACE_CODE_CONFIG_ERROR4配置错误
FACE_CODE_BAD_ILLUMINATION5光线条件不好
FACE_CODE_POSE_ERROR6面部位置不符合要求
FACE_CODE_SMALL_FACE_SIZE7人脸尺寸太小
FACE_CODE_LOW_IMAGE_QUALITY8人脸图像模糊
FACE_CODE_NOT_LIVENESS9非活体人脸图像
FACE_CODE_LICENSE_ERROR10授权文件无效
FACE_CODE_LICENSE_EXPIRED11授权文件过期
FACE_CODE_FACE_DB_ERROR 12人脸库加载失败
FACE_CODE_IMAGE_ID_ERROR101删除时图像id不存在
FACE_CODE_OTHER_ERROR1000其他错误

4.3.2. SunmiFaceGenderType 性别类型

枚举成员说明
FACE_ATTR_FEMALE0性别女
FACE_ATTR_MALE1性别男

4.3.3 SunmiFaceMode 执行功能选择

枚举成员说明
PredictMode_None0不执行任何功能
PredictMode_Detect1执行人脸检测
PredictMode_Feature3执行人脸特征提取
PredictMode_Age5执行年龄预测
PredictMode_Gender5执行性别预测

4.3.4 SunmiFaceLivenessMode 活体检测功能选择

枚举成员说明
LivenessMode_None0不执行活体检测
LivenessMode_RGB1进行RGB活体检测
LivenessMode_NIR2进行NIR活体检测
LivenessMode_Depth4进行深度图活体检测

4.4. 结构体类型

4.4.1. SunmiFaceRect人脸框位置

成员类型说明
x1_float人脸框左上角横坐标
y1_float人脸框左上角纵坐标
x2_float人脸框右下角横坐标
y2_float人脸框右小角纵坐标
score_float置信度

4.4.2. SunmiFaceLmk人脸关键点坐标

成员类型说明
x_float关键点横坐标
y_float关键点纵坐标

4.4.3. SunmiFaceImage人脸识别输入图像

成员类型说明
buf_unsigned char *图片像素字节地址
buf_len_int字节缓冲区长度
img_w_int图像宽度
img_h_int图像高度
max_face_count_int单图人脸数最大返回值
depth_buf_unsigned char *深度图数据字节地址
depth_buf_len_int深度图数据长度
depth_img_w_int深度图宽度
depth_img_h_int深度图高度
nir_buf_unsigned char *红外图数据字节地址
nir_buf_len_int红外图数据长度
nir_img_w_int红外图宽度
nir_img_h_int红外图高度
liveness_mode_int需要执行的活体检测功能选择
predict_mode_int需要执行的功能选择

4.4.4. SunmiFacePose人脸姿态

成员类型说明
pitch_float俯仰角度
yaw_float偏航角度
roll_float翻滚角度

4.4.5. SunmiFaceAge 年龄

成员类型说明
classification_int年龄范围(0-74岁)
score_float置信度

4.4.6. SunmiFaceGender 性别

成员类型说明
classification_int性别分类(0: female ; 1: male)
score_float置信度

4.4.7. SunmiFaceFeature单个特征提取输出信息结构体

成员类型说明
face_rect_SunmiFaceRect人脸矩形框位置
rgb_liveness_score_floatRGB活体检测分数
nir_liveness_score_floatNIR活体检测分数
depth_liveness_score_float深度图活体检测分数
feature_[SUNMI_FACE_FEATURE_LEN]float人脸特征数组
landmark_[SUNMI_FACE_LANDMARK_LEN]SunmiFaceLmk关键点
pose_SunmiFacePose人脸姿态
age_SunmiFaceAge年龄
gender_SunmiFaceGender性别

4.4.8. SunmiFaceImageFeatures多个特征提取输出信息结构体

成员类型说明
features_SunmiFaceFeature *特征数组
features_count_int特征数组长度

4.4.9. SunmiFaceConfigParam人脸配置参数

成员类型说明
thread_num_intSDK人脸检测人脸识别计算使用的线程数量(cpu核数),0代表使用所有的cpu核
distance_threshold_float人脸距离阈值
yaw_threshold_float偏航角度阈值
pitch_threshold_float俯仰角度阈值
roll_threshold_float翻滚角度阈值
min_face_sizeint人脸最小尺寸
image_quality_threshold_float图像质量阈值
min_luminance_int最低亮度
max_luminance_int最高亮度
rgb_liveness_threshold_floatRGB活体检测阈值
depth_liveness_threshold_float3D活体检测阈值
nir_liveness_threshold_floatNIR活体检测阈值
depth_x_offsetint深度图相对于彩色图x方向偏移
depth_y_offsetint深度图相对于彩色图y方向偏移
nir_x_offsetint红外图相对于彩色图x方向偏移
nir_y_offsetint红外图相对于彩色图y方向偏移

4.4.10. SunmiFaceCompareResult人脸匹配结果

成员类型说明
is_matched_bool如果距离小于人脸间距阈值,则为真,否则为假
distance_float人脸距离

4.4.11. SunmiFaceDBRecord人脸数据库记录

成员类型说明
id_[SUNMI_FACE_ID_LEN]char人脸唯一id
name_[SUNMI_FACE_NAME_LEN]char用户名
img_id_[SUNMI_FACE_IMG_ID_LEN]char人脸采集图像唯一id
feature_[SUNMI_FACE_FEATURE_LEN]float人脸特征

4.4.12. SunmiFaceDBIdInfo人脸数据库信息

成员类型说明
id_[SUNMI_FACE_ID_LEN]char人脸唯一id
name_[SUNMI_FACE_NAME_LEN]char用户名
is_matched_bool如果距离小于人脸间距阈值,则为真,否则为假
distance_float人脸距离

5. C++函数接口定义

对外接口的定义在face.h头文件中。

5.1. 函数接口定义

5.1.1. SunmiFaceGetVersion

函数定义:SUNMI_FACE_API const char* SunmiFaceGetVersion();

函数功能:获取Sunmi人脸识别SDK版本

返回值:SDK版本字符串

5.1.2. SunmiFaceCreate

函数定义:SunmiFaceStatus SunmiFaceCreate(SunmiFaceHandle* handle);

函数功能:创建句柄,用户需要保持这个句柄直到释放

变量类型说明
handleSunmiFaceHandle*输出参数,创建人脸SDK句柄

返回值:SunmiFaceStatus

5.1.3. SunmiFaceInit

函数定义:SunmiFaceStatus SunmiFaceInit(SunmiFaceHandle handle,  const std::string& config_file);

函数功能:使用配置文件初始化SDK

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
config_fileconst std::string&配置文件路径

返回值:SunmiFaceStatus

5.1.4. SunmiFaceGetErrorString

函数定义:const char* SunmiFaceGetErrorString(SunmiFaceStatus code);

函数功能:通过SunmiFaceStatus得到错误描述字符串

变量类型说明
codeSunmiFaceStatusSunmiFaceStatus code

返回值:错误描述字符串

5.1.5. SunmiFaceVerifyLicense

函数定义:SunmiFaceStatus SunmiFaceVerifyLicense(SunmiFaceHandle handle, const std::string& fingerprint, const std::string& license);

函数功能:验证设备指纹和授权文件是否合法

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
fingerprintconst std::string&设备指纹字符串
licenseconst std::string&授权文件字符串

返回值:SunmiFaceStatus

5.1.6. SunmiFaceSetConfig

函数定义:SunmiFaceStatus SunmiFaceSetConfig(SunmiFaceHandle handle, const SunmiFaceConfigParam& config);  

函数功能:设置配置信息

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
configconst SunmiFaceConfigParam&配置参数

返回值:SunmiFaceStatus

5.1.7. SunmiFaceGetConfig

函数定义:SunmiFaceStatus SunmiFaceGetConfig(SunmiFaceHandle handle, SunmiFaceConfigParam& config);

函数功能:获取当前SDK参数

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
configSunmiFaceConfigParam&配置参数

返回值:SunmiFaceStatus

5.1.8. SunmiFaceRelease

函数定义:SunmiFaceStatus SunmiFaceRelease(SunmiFaceHandle handle);

函数功能:释放句柄

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄

返回值:SunmiFaceStatus

5.1.9. SunmiFaceGetImageFeatures

函数定义:SunmiFaceStatus SunmiFaceGetImageFeatures(SunmiFaceHandle handle, SunmiFaceImage image, SunmiFaceImageFeatures *features);

函数功能:从图像中获取人脸特征

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
imageSunmiFaceImage输入图片结构体
featuresSunmiFaceImageFeatures *返回人脸特征

返回值:SunmiFaceStatus

5.1.10. SunmiFaceCompare1v1

函数定义:SunmiFaceStatus SunmiFaceCompare1v1(SunmiFaceHandle handle, SunmiFaceFeature *feature1, SunmiFaceFeature *feature2, SunmiFaceCompareResult *compare_result);

函数功能:1:1人脸比对

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
feature1SunmiFaceFeature *比较特征1
feature2SunmiFaceFeature *比较特征2
compare_resultSunmiFaceCompareResult *比对结果

返回值:SunmiFaceStatus

5.1.11. SunmiFaceReleaseImageFeatures

函数定义:SunmiFaceStatus SunmiFaceReleaseImageFeatures(SunmiFaceImageFeatures *features);

函数功能:释放人脸特征

变量类型说明
featuresSunmiFaceImageFeatures *人脸特征

返回值:SunmiFaceStatus

5.1.12. SunmiFaceInitDB

函数定义:SunmiFaceStatus SunmiFaceInitDB(SunmiFaceHandle handle, const char* db_name);

函数功能:打开人脸数据库文件,如果不存在,则创建空的人脸数据库。SDK初始化时会默认打开config.json里面指定的face_db_file

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
db_nameconst char*数据库文件名称

返回值:SunmiFaceStatus

5.1.13. SunmiFaceAddDBRecord

函数定义:SunmiFaceStatus SunmiFaceAddDBRecord(SunmiFaceHandle handle, SunmiFaceDBRecord *record);

函数功能:添加一条人脸记录到人脸数据库中

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
recordSunmiFaceDBRecord *record人脸记录

返回值:SunmiFaceStatus

5.1.14. SunmiFaceSearchDB

函数定义:SunmiFaceStatus SunmiFaceSearchDB(SunmiFaceHandle handle, SunmiFaceDBRecord *record, SunmiFaceDBIdInfo *idInfo);

函数功能:1:N 人脸搜索

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
recordSunmiFaceDBRecord *人脸库记录结构体
idInfoSunmiFaceDBIdInfo *搜索结果

返回值:SunmiFaceStatus

5.1.15. SunmiFaceDeleteDBRecord

函数定义:SunmiFaceStatus SunmiFaceDeleteDBRecord(SunmiFaceHandle handle, char *img_id);

函数功能:根据图像id删除人脸数据库中的一个人脸记录

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
img_idchar *人脸采集图像在人脸库里的唯一ID

返回值:SunmiFaceStatus

6. Java函数接口定义

对外接口的定义在SunmiFaceSDK.java文件中。

6.1. 接口类定义

类名说明
SunmiFaceSDK人脸识别接口类名定义

6.2. 函数接口定义

6.2.1. getVersion

函数定义:public static String getVersion()

函数功能:获取Sunmi人脸识别SDK版本号

返回值:SDK版本字符串

6.2.2. Init

函数定义:public static int init(String configPath)

函数功能:初始化SDK

变量类型说明
configPathString配置文件路径

返回值:SunmiFaceStatusCode

6.2.3. verifyLicense

函数定义:public static int verifyLicense(Context context, String license)

函数功能:验证许可证

变量类型说明
contextContextAndroid context
licenseString许可证字符串

返回值:SunmiFaceStatusCode

6.2.4. getDeviceFingerprint

函数定义:public static String getDeviceFingerprint(Context context)

函数功能:获取Android设备指纹

变量类型说明
contextContextandroid context

返回值:设备指纹字符串

6.2.5. getErrorString

函数定义:public static String getErrorString(int code)

函数功能:获得错误字符串

变量类型说明
codeint错误代码

返回值:错误描述字符串

6.2.6. setConfig

函数定义:public static int setConfig(SunmiFaceConfigParam config)

函数功能:设置配置

变量类型说明
configSunmiFaceConfigParamSDK配置参数

返回值:SunmiFaceStatusCode

6.2.7. getConfig

函数定义:public static int getConfig(SunmiFaceConfigParam config)

函数功能:获取当前SDK配置

变量类型说明
configSunmiFaceConfigParamSDK配置参数

返回值:SunmiFaceStatusCode

6.2.8. getImageFeatures

函数定义:public static int getImageFeatures(SunmiFaceImage image, SunmiFaceImageFeatures features)

函数功能:从图像中进行人脸检测和人脸特征提取

变量类型说明
imageSunmiFaceImage输入图像
featuresSunmiFaceImageFeatures返回人脸特征

返回值:SunmiFaceStatusCode

6.2.9. compare1v1

函数定义:public int compare1v1(SunmiFaceFeature feature1, SunmiFaceFeature feature2, SunmiFaceCompareResult compare_result)

函数功能:人脸1:1比对

变量类型说明
features1SunmiFaceFeature人脸特征1
features2SunmiFaceFeature人脸特征2
compare_resultSunmiFaceCompareResult比对结果

返回值:SunmiFaceStatusCode

6.2.10. releaseImageFeatures

函数定义:public static int releaseImageFeatures(SunmiFaceImageFeatures features)

函数功能:释放人脸特征

变量类型说明
featuresSunmiFaceImageFeatures人脸特征

返回值:SunmiFaceStatusCode

6.2.11. initDB

函数定义:public static int initDB(String db_name)

函数功能:初始化新人脸数据库

变量类型说明
db_nameString人脸数据库文件名

返回值:SunmiFaceStatusCode

6.2.12. faceFeature2FaceDBRecord

函数定义:public static SunmiFaceDBRecord faceFeature2FaceDBRecord(SunmiFaceFeature feature)

函数功能:将人脸特征结构体转换成人脸库记录结构体

变量类型说明
featureSunmiFaceFeature人脸特征

返回值:SunmiFaceDBRecord

6.2.13. addDBRecord

函数定义:public static int addDBRecord(SunmiFaceDBRecord record)

函数功能:添加一条记录到人脸数据库,添加成功后通过img_id_可以的到人脸库中图片的ID,后续可以用来删除操作

变量类型说明
recordSunmiFaceDBRecord人脸库记录结构体

返回值:SunmiFaceStatusCode

6.2.14. searchDB

函数定义:public static int searchDB(SunmiFaceDBRecord record, SunmiFaceDBIdInfo idInfo)

函数功能:数据库中1:N人脸比对

变量类型说明
recordSunmiFaceDBRecord要搜索的人脸记录
idInfoSunmiFaceDBIdInfo搜索结果

返回值:SunmiFaceStatusCode

6.2.15. deleteDBRecord

函数定义:public static int deleteDBRecord(String img_id)

函数功能:根据图像id删除人脸数据库中的一条记录

变量类型说明
img_idString人脸采集图像的ID

返回值:SunmiFaceStatusCode

人脸识别Andriod_SDK_1.3

[更新通知]:人脸识别SDK包版本已更新至1.6.1,请前往至相关页面进行下载:
人脸识别Andriod_SDK_1.6

1. 概述

商米人脸识别SDK是一种面向安卓设备的人脸技术开发包。此SDK开发包包含人脸检测、人脸识别和人证比对等功能,以aar包+models的形式发布。本文档介绍了SDK的使用说明以及数据结构和接口的定义,便于开发者在调用SDK接口时参考。

1.1.文档使用范围

该人脸识别接口文档主要适用于人脸识别开发的相关人员参考阅读。

1.2.功能清单

商米人脸识别SDK主要提供如下功能:

模块功能
人脸检测检测图片中出现人脸的位置,并标记出人脸的五个关键点位置
人脸识别将当前人脸和数据库中的人脸进行匹配,确定当前人脸身份信息
人证比对采集身份证上的照片,并且判断当前人脸是否和身份证上的人脸匹配
人脸属性预测根据图片上出现的脸,预测人的性别及年龄
活体检测判断图片上出现的脸是否来自于真人;当采用3D摄像头时预测结果更准确

1.3. 开发包SDK的说明

商米人脸识别SDK包含sunmi_facelib.aar文件和models文件夹。其中models文件夹包含一个配置文件和六个模型文件:

文件/文件夹名说明
sunmi_facelib.aarSDK lib库相关代码的aar
models配置文件:config.json模型文件:face_graph.json、face_param.params、detect_graph.json、detect_param.params、liveness_graph.json和liveness_param.params、depth_detector.yml、attribute_graph.json和attribute_param.params

注: 商米人脸识别SDK 只有一个实例,是线程不可重入的。只能同时由一个线程调用,不能在多个线程里面同时调用。

2. 环境信息

系统环境平台编译环境
Android7及以上arm32, arm64NDK

3. JavaSDK使用说明

3.1. 获取授权文件

商米人脸识别SDK的授权需要绑定Android系统信息。在第一次使用前,开发者需要获取人脸识别SDK的license授权文件,请参考文档 授权&购买授权

3.2. 导入SDK

在Android Studio项目中导入SDK aar包即可。

3.3. 存放模型文件

模型文件(.json和.params文件)可以存放在SD卡某个路径下,也可以存放在APP文件路径下。请务必保证模型所在路径可以被访问。

3.4. 配置config.json文件

使用模型包中config.json文件作为模板,或者自行创建一个config.json文件,拷贝如下代码。根据3.3中9个文件face_graph.json、face_param.params、detect_graph.json、detect_param.params、liveness_graph.json、liveness_param.params、depth_detector.yml、attribute_gragh.json和attribute_param.params存放的实际路径进行修改。SDK需通过读取此config.json配置文件进行初始化。

{  
   // 人脸识别库文件,此文件在SDK Jnilibs里,一般不需要修改
   "face_lib_path": "libface_lib.so", 
   // 人脸识别库网络描述文件,需要绝对路径 
   "face_graph_path": "/storage/emulated/0/faceTest/face_graph.json",  
   // 人脸识别库网络参数文件,需要绝对路径 
   "face_param_path": "/storage/emulated/0/faceTest/face_param.params",  
   // 人脸检测库文件,此文件在SDK Jnilibs里,一般不需要修改  
   "detect_lib_path": "libdetect_lib.so", 
   // 人脸检测库网络描述文件,需要绝对路径 
   "detect_graph_path": "/storage/emulated/0/faceTest/detect_graph.json",  
   // 人脸检测库网络参数文件,需要绝对路径 
   "detect_param_path": "/storage/emulated/0/faceTest/detect_param.params",  
   // 2D活体检测库文件,此文件在SDK Jnilibs里,一般不需要修改 
   "liveness_lib_path": "libliveness_lib.so",  
   // 2D活体检测库网络描述文件,需要绝对路径
   "liveness_graph_path":"/storage/emulated/0/faceTest/liveness_graph.json",
   // 2D活体检测库网络参数文件,需要绝对路径
  "liveness_param_path":"/storage/emulated/0/faceTest/liveness_param.params",
   // 人脸库存放路径,需要绝对路径  
   "face_db_file": "/storage/emulated/0/faceTest/sunmi_face.db", 
   // 3D活体检测模型,需要绝对路径
   "depth_detector": "/storage/emulated/0/faceTest/depth_detector.yml"
   // 人脸属性预测库文件,此文件在SDK Jnilibs里,一般不需要修改
   "attr_lib_path": "libattribute_lib.so",
   // 人脸属性预测网络描述文件,需要绝对路径
   "attr_graph_path": "/storage/emulated/0/faceTest/attribute_graph.json",
   //  人脸属性预测库网络参数文件,需要绝对路径
   "attr_param_path": "/storage/emulated/0/faceTest/attribute_param.params",

3.5. 始化SDK

以下为SDK调用init接口执行初始化的示例。init接口参数为3.4中的config.json文件的路径。

String confPath = Environment.getExternalStorageDirectory() + 
"/faceTest/config.json";
int code = SunmiFaceSDK.init(confPath);

3.6. 验证授权文件

使用类似如下代码读取授权文件内容到Java String中,再通过verifyLicense接口验证。若验证通过,可正常调用SDK其他接口。若验证失败,调用SDK其他接口将返回授权错误代码。错误代码为“10”,则表示授权文件无效;错误代码为“11”,则表示授权文件过期。如有授权问题,请联系商米解决。
注:需保证wifi开关为打开状态。

String license = readToString(Environment.getExternalStorageDirectory() + 
"/faceTest/license_valid.txt");
int code = SunmiFaceSDK.verifyLicense(context, license); // context为Android Context

3.7. 配置SDK

商米人脸识别SDK参数都可动态配置,建议先通过getConfig得到当前参数,根据需要将参数修改完成后,再用setConfig接口进行设置。示例代码如下:

SunmiFaceConfigParam param = new SunmiFaceConfigParam();
SunmiFaceSDK.getConfig(param);
param.setDistanceThreshold(0.9f); //当SDK应用于支付场景,推荐值是0.9;当应用于人证比对场景时,推荐值为1.1;阈值越小,SDK对于相同人的判定越严格
param.setYawThreshold(50.0f);//人脸姿态阈值,设置较小的人脸姿态阈值,阈值越小,人脸姿态要求越严格,保证相对正面的人脸姿态做识别
param.setPitchThreshold(50.0f);
param.setRollThreshold(50.0f);
param.setMinFaceSize(60);//最小人脸检测尺寸,较大较清晰的人脸识别较准确
param.setImageQualityThreshold(10);//阈值越高,人脸清晰度越好,人脸识别越准确
param.setMinLuminance(10);//最小光照
param.setMaxLuminance(180);//最大光照
param.setLivenessOn(true);//开启人脸活体检测
param.setThreadNum(1); //使用一个cpu核心执行人脸检测,人脸识别
int code = SunmiFaceSDK.setConfig(param);

3.8 释放内存

在SDK调用过程中,通过调用SunmiFaceFeatureArrayGetItem和SunmiFaceLmkArrayGetItem方法得到的对象,可调用delete方法手动立即释放内存。如果未调用delete方法,java垃圾回收会自动释放内存 。示例代码如下:

SunmiFaceFeature faceFeature = SunmiFaceLib.SunmiFaceFeatureArrayGetItem(features.getFeatures(), 0);
feature.delete();

3.9. 提取人脸特征

提取步骤:

  1. 获取的Bitmap图片:用户根据需求,从摄像头获取bitmap传给SDK。
  2. 传入图片的尺寸:人脸SDK检测最佳输入图的宽高比为1:1。若宽高比过大,可能导致检测性能略微下降。
  3. 图像格式处理:将获取的Bitmap图片转为BGR byte buffer格式。(可参考如下示例代码)
  4. 接口调用:传入BGR byte buffer,通过SunmiFaceImage构造函数创建SunmiFaceImage。再通过getImageFeatures接口传入SunmiFaceImage图片数据,得到SunmiFaceImageFeatures人脸结果。
  5. 多人脸识别逻辑:如果有多张人脸,SunmiFaceFeature在SunmiFaceImageFeatures中按照置信度score从高到低排列。
  6. 人脸库记录:faceFeature2FaceDBRecord把得到的人脸特征转换为人脸库的记录,设置相关ID,name。
  7. 资源释放:SunmiFaceImageFeatures在SDK中动态分配内存空间,使用完毕后需要调用接口释放资源。

示例代码如下:

public static byte[] getPixelsBGR(Bitmap image) {
    // 计算图片有多少字节
    int bytes = image.getByteCount();

    ByteBuffer buffer = ByteBuffer.allocate(bytes); // 创建新的buffer
    image.copyPixelsToBuffer(buffer); // 移动字节数据到buffer

    byte[] temp = buffer.array(); // 获取包含数据的底层数组
    byte[] pixels = new byte[(temp.length / 4) * 3]; // 分配空间给BGR

    // 对像素重组
    for (int i = 0; i ‹ temp.length / 4; i++) {
        pixels[i * 3] = temp[i * 4 + 2];        //B
        pixels[i * 3 + 1] = temp[i * 4 + 1];    //G
        pixels[i * 3 + 2] = temp[i * 4];        //R
    }
    return pixels;
}
private void addFeature(String name) {
    if (bitmap == null) {
        Toast.makeText(context, "请先拍照", Toast.LENGTH_SHORT).show();
        return;
    }
    byte[] srcData = FileUtils.getPixelsBGR(bitmap);
    SunmiFaceImage image = new SunmiFaceImage(srcData, bitmap.getHeight(), bitmap.getWidth(), 1);
    SunmiFaceImageFeatures features = new SunmiFaceImageFeatures();
    SunmiFaceSDK.getImageFeatures(image, features);
    SunmiFaceFeature feature_ary = features.getFeatures();
    Log.e("ma", "face info: " + features.getFeaturesCount());
    if (features.getFeaturesCount() == 0) {
        showId("没有检测到人脸,请重新拍照!");
        return;
    }
    SunmiFaceFeature feature = SunmiFaceLib.SunmiFaceFeatureArrayGetItem(feature_ary, 0);
    SunmiFaceDBRecord record = SunmiFaceSDK.faceFeature2FaceDBRecord(feature);
    record.setId(name);
    record.setName(name);
    SunmiFaceSDK.addDBRecord(record);
    SunmiFaceSDK.releaseImageFeatures(features);
    Log.e("face", "采集成功 " + etName.getText().toString());
    feature.delete();
}

3.10. 人脸库添加人脸特征

注意:商米人脸识别SDK包产品中的离线人脸库只存不可逆的人脸特征值,并不存储原始照片,在每次识别过程中也不存储照片。

SunmiFaceDBRecord包含img_id_、id和name三个参数,其中img_id_无需设置,id和name需要调用者进行设置:

  1. img_id_无需设置。调用addDBRecord将记录成功加入到人脸库后,SunmiFaceDBRecord中img_id_会自动被设置为人脸库中代表此图片的唯一id。img_id_可以理解为录入图片的唯一名字,SDK保证返回的img_id不重复。用户可以以img_id为文件名来保存拍摄的人脸照片。根据此img_id可以调用deleteDBRecord来删除这条记录。
  2. id为被录入人脸的人员的唯一id。SDK考虑开发者调用的灵活性,没有对其唯一性进行限制。在通常情况下,建议调用者务必保证id的唯一性,id可理解为一般不会重号的身份证号,食堂卡号,会员号等。
  3. name可以不唯一,允许出现两个人名相同的情况,同时允许每个人录入多张人脸。

示例:
数据库中记录:
用户A,id为0001,姓名张三,图片1,图片2;
用户B, id为0002,姓名也是张三,图片3,图片4,图片5。
用户A和B同名,并且都有多张图片,存储每张图片提取的人脸特征。

注:通常在私域情形下,在被采集人知情情况下,建议将被识别的人脸底图存储于安全位置, 推荐采用addDBRecord接口返回的SunmiFaceDBRecord里面的getImgId()来命名图片,以绑定图片和人脸库中人脸特征,方便后期对人脸库进行相关操作和比对 

3.11.  获取人脸关键点

通过getLandmark_得到人脸关键点数组,在获取数组中的每个关键点信息。示例代码如下:

SunmiFaceFeature feature = SunmiFaceLib.SunmiFaceFeatureArrayGetItem(feature_ary, 0);
SunmiFaceLmk lmk_ary = feature.getLandmark();
for(int i = 0; i ‹ SunmiFaceLibConstants.SUNMI_FACE_LANDMARK_LEN; i++) {
    SunmiFaceLmk lmk = SunmiFaceLib.SunmiFaceLmkArrayGetItem(lmk_ary, i);
    lmk.delete();
}
feature.delete();

3.12. 搜索人脸库

调用searchDB执行人脸库搜索寻找最相似的人脸。如果SDK判断人脸距离小于阈值,matched设为true,否则为false。示例代码如下:

SunmiFaceDBRecord record = SunmiFaceSDK.faceFeature2FaceDBRecord(feature);
SunmiFaceDBIdInfo info = new SunmiFaceDBIdInfo();
SunmiFaceSDK.searchDB(record, info);
if (info.getIsMatched()) {
	Log.e("ma", “Found”);
}
else {
Log.e("ma", “Not Found”);
}

3.13. 人脸1:1比对

分别对要比对的两张图片进行人脸特征的提取,得到类型为SunmiFaceFeature两个人脸特征feature1,feature2。在调用compare1v1接口得到比对结果。getIsMatched()得到比对结果,getDistance()得到两张人脸的距离度量。

SunmiFaceCompareResult result;
int code = SunmiFaceSDK.compare1v1(feature1, feature2, result)
boolean isMatched = result.getIsMatched()
float distance = result.getDistance();

3.14. 活体检测

2D活体检测使用UVC摄像头实现2D活体检测功能,适用于没有3D摄像头的情况。
3D活体检测使用奥比中光3D结构光摄像头实现3D活体检测功能,其预测效果相比2D活体检测有很大提升。深度图depth为16bit数据,表示物体到摄像头以毫米为单位的距离。需要注意以下几点:

  1. 使用活体检测,要求BGR图像分辨率为 480×640,3D活体检测深度图分辨率如下表所示。
  2. 3D活体检测需保证BGR图像和深度图像在时间上是对应的。
  3. 彩色图和深度图存在一定的位置偏差,以彩色图检测到的人脸位置为参考,深度图在x方向和y方向的偏差如下表所示。
  4. 活体检测存在一定的真人判断为非活体的概率。所以推荐判断非活体需要执行3次左右来确认。非活体判断为真人的概率低于1%。
设备型号3D摄像头型号深度图分辨率深度图x方向偏移量深度图y方向偏移量是否旋转
K1Pro A640*48028-20
K2D2plus400*64075-15
T2

活体检测的使用步骤如下:

  • 1. 开启活体检测,配置阈值。
SunmiFaceConfigParam param = new SunmiFaceConfigParam();
SunmiFaceSDK.getConfig(param);
param.setLivenessOn(true);
param.setDepthLivenessThreshold(0.5f); //2D和3D都推荐阈值在0.5左右
param.setDepthXOffset(75); //3D根据设备型号设置深度图x方向偏移量
param.setDepthYOffset(-15); //3D根据设备型号设置深度图y方向偏移量
ret = SunmiFaceSDK.setConfig(param);
  • 2. 构造SunmiFaceImage,同时传入BGR图像和深度图像。
SunmiFaceImage image = new SunmiFaceImage(srcData, bitmap.getHeight(), bitmap.getWidth(), depth, depth_height, depth_width, 1); // 3D活体检测

SunmiFaceImage image = new SunmiFaceImage(srcData, bitmap.getHeight(), bitmap.getWidth(), 1); // 2D活体检测
public static Bitmap rotateBitmap(Bitmap origin, float alpha) {
        if (origin == null) {
            return null;
        }
        int width = origin.getWidth();
        int height = origin.getHeight();
        Matrix matrix = new Matrix();
        matrix.setRotate(alpha);
        // 围绕原地进行旋转
        Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
        if (newBM.equals(origin)) {
            return newBM;
        }

        return newBM;
    }

注:当摄像头需要旋转时,在传入BGR和深度图像时之前需要对两幅图进行90度旋转,BGR图旋转的代码如下:

深度图旋转代码如下:

  • 3. 查看活体判断结果,如果code为FACE_CODE_OK则判断为活体。如果code为FACE_CODE_NOT_LIVENESS则判断为非活体。
public static byte [] rotateDepthImage(byte[] depthByte, int height, int width){
        if(depthByte == null){return null;}

        int depthLen = height * width * 2;
        byte [] newDepth = new byte [depthLen];
        for (int i = 0; i‹=width-1; i++){
            for(int j = 0; j‹=height-1; j++){
                newDepth[2*(i*height+j)] = depthByte[2*((height-1-j)*width+i)];
                newDepth[2*(i*height+j)+1] = depthByte[2*((height-1-j)*width+i)+1];
            }
        }
        return newDepth;
    }
int code = SunmiFaceSDK.getImageFeatures(image, features);

3.15. 获取人脸属性

人脸属性首先需要获取人脸特征faceFeature,再根据人脸特征获取年龄和性别属性,主要示例代码如下:

注: 通过SunmiFaceLmkArrayGetItem获得SunmiFaceAge 要调用delete方法释放内存,否则会造成内存泄漏 。

SunmiFaceFeature faceFeature = SunmiFaceLib.SunmiFaceFeatureArrayGetItem(features.getFeatures(), 0);
SunmiFaceAge ageInfo = faceFeature.getAge();
int age = ageInfo.getClassification();
float ageScore = ageInfo.getScore();
SunmiFaceGender genderInfo = faceFeature.getGender();
int gender = genderInfo.getClassification();
float genderScore = genderInfo.getScore();
feature.delete();

3.16 执行功能选择

功能选择是为了方便开发者在实际开发中只选择所需的SDK功能,减少计算资源和时间的浪费。该功能可通过SunmiFaceImage中定义的predict_mode_成员进行控制。

例如:在3.9和3.15中,分别介绍了商米人脸识别SDK提取人脸特征和人脸属性获取的功能。实际上,SDK在这两小节提供的代码中同时完成了人脸检测、人脸特征提取及人脸属性识别。若开发者只需使用其中一个,三个功能同时进行会极大地浪费计算资源和时间。因此,可以使用功能选择进行控制,主要示例代码如下:

image = new SunmiFaceImage(srcData, bitmap.getHeight(), bitmap.getWidth(), 1);   //根据bitmap创建SunmiFaceImage对象
SunmiFaceImageFeatures features = new SunmiFaceImageFeatures();   //创建空的SunmiFaceImageFeatures对象
image.setPredictMode(SunmiFaceMode.PredictMode_Age);    //只进行年龄预测
image.setPredictMode(SunmiFaceMode.PredictMode_Feature);    //只进行特征提取
image.setPredictMode(SunmiFaceMode.PredictMode_Detect);    //只进行人脸检测
image.setPredictMode(SunmiFaceMode.PredictMode_Age|SunmiFaceMode.PredictMode_Feature);    //进行人脸特征提取和年龄预测
image.setPredictMode(SunmiFaceMode.PredictMode_Age|SunmiFaceMode.PredictMode_Feature|PredictMode_Gender);    //进行人脸特征提取及年龄性别预测,即执行SDK的全部功能,此行代码可以不写,SDK默认模式为执行全部功能
ret = SunmiFaceSDK.getImageFeatures(image, features);    //根据选择的模式提取相应特征

4. 数据类型定义

4.1. 类型别名

别名类型说明
SunmiFaceStatusintTypedef,定义在face_type.h 文件中
SunmiFaceHandlevoid*Typedef,定义在face.h 文件中

4.2. 宏

接口使用的数据类型定义在face_type.h头文件中,主要数据如下:

成员说明
SUNMI_FACE_FEATURE_LEN256人脸特征向量长度
SUNMI_FACE_ID_LEN64id字符长度限制
SUNMI_FACE_NAME_LEN64人脸用户名长度
SUNMI_FACE_IMG_ID_LEN64人脸采集图片ID长度
SUNMI_FACE_LANDMARK_LEN5人脸关键点数量

4.3. 枚举类型

接口使用的数据结构定义在face_type.h头文件中。

4.3.1. SunmiFaceStatusCode 商米人脸识别状态码

枚举成员状态码说明
FACE_CODE_OK0正确
FACE_CODE_UNINIT1SDK没有初始化
FACE_CODE_EMPTY_IMAGE2图片为空
FACE_CODE_NO_MODEL3无加载模型文件
FACE_CODE_CONFIG_ERROR4配置错误
FACE_CODE_BAD_ILLUMINATION5光线条件不好
FACE_CODE_POSE_ERROR6面部位置不符合要求
FACE_CODE_SMALL_FACE_SIZE7人脸尺寸太小
FACE_CODE_LOW_IMAGE_QUALITY8人脸图像模糊
FACE_CODE_NOT_LIVENESS9非活体人脸图像
FACE_CODE_LICENSE_ERROR10授权文件无效
FACE_CODE_LICENSE_EXPIRED11授权文件过期
FACE_CODE_IMAGE_ID_ERROR101删除时图像id不存在
FACE_CODE_OTHER_ERROR1000其他错误

4.3.2. SunmiFaceGenderType 性别类型

枚举成员说明
FACE_ATTR_FEMALE0性别女
FACE_ATTR_MALE1性别男

4.3.3 SunmiFaceMode 执行功能选择

枚举成员说明
PredictMode_None0不执行任何功能
PredictMode_Detect1执行人脸检测
PredictMode_Feature3执行人脸特征提取
PredictMode_Age5执行年龄预测
PredictMode_Gender5执行性别预测

4.4. 结构体类型

4.4.1. SunmiFaceRect人脸框位置

成员类型说明
x1_float人脸框左上角横坐标
y1_float人脸框左上角纵坐标
x2_float人脸框右下角横坐标
y2_float人脸框右小角纵坐标
score_float置信度

4.4.2. SunmiFaceLmk人脸关键点坐标

成员类型说明
x_float关键点横坐标
y_float关键点纵坐标

4.4.3. SunmiFaceImage人脸识别输入图像

成员类型说明
buf_unsigned char *图片像素字节地址
buf_len_int字节缓冲区长度
img_w_int图像宽度
img_h_int图像高度
max_face_count_int单图人脸数最大返回值
depth_buf_unsigned char *深度图数据字节地址
depth_buf_len_int深度图数据长度
depth_img_w_int深度图宽度
depth_img_h_int深度图高度
predict_mode_int需要执行的功能选择

4.4.4. SunmiFacePose人脸姿态

成员类型说明
pitch_float俯仰角度
yaw_float偏航角度
roll_float翻滚角度

4.4.5. SunmiFaceAge 年龄

成员类型说明
classification_int年龄范围(0-74岁)
score_float置信度

4.4.6. SunmiFaceGender 性别

成员类型说明
classification_int性别分类(0: female ; 1: male)
score_float置信度

4.4.7. SunmiFaceFeature单个特征提取输出信息结构体

成员类型说明
face_rect_SunmiFaceRect人脸矩形框位置
liveness_score_float活体分数
feature_[SUNMI_FACE_FEATURE_LEN]float人脸特征数组
landmark_[SUNMI_FACE_LANDMARK_LEN]SunmiFaceLmk关键点
pose_SunmiFacePose人脸姿态
age_SunmiFaceAge年龄
gender_SunmiFaceGender性别

4.4.8. SunmiFaceImageFeatures多个特征提取输出信息结构体

成员类型说明
features_SunmiFaceFeature *特征数组
features_count_int特征数组长度

4.4.9. SunmiFaceConfigParam人脸配置参数

成员类型说明
thread_num_intSDK人脸检测人脸识别计算使用的线程数量(cpu核数),0代表使用所有的cpu核
distance_threshold_float人脸距离阈值
yaw_threshold_float偏航角度阈值
pitch_threshold_float俯仰角度阈值
roll_threshold_float翻滚角度阈值
min_face_sizeint人脸最小尺寸
image_quality_threshold_float图像质量阈值
min_luminance_int最低亮度
max_luminance_int最高亮度
rgb_liveness_threshold_floatRGB活体检测阈值
depth_liveness_threshold_float3D活体检测阈值
liveness_on_bool活体检测开关

4.4.10. SunmiFaceCompareResult人脸匹配结果

成员类型说明
is_matched_bool如果距离小于人脸间距阈值,则为真,否则为假
distance_float人脸距离

4.4.11. SunmiFaceDBRecord人脸数据库记录

成员类型说明
id_[SUNMI_FACE_ID_LEN]char人脸唯一id
name_[SUNMI_FACE_NAME_LEN]char用户名
img_id_[SUNMI_FACE_IMG_ID_LEN]char人脸采集图像唯一id
feature_[SUNMI_FACE_FEATURE_LEN]float人脸特征

4.4.12. SunmiFaceDBIdInfo人脸数据库信息

成员类型说明
id_[SUNMI_FACE_ID_LEN]char人脸唯一id
name_[SUNMI_FACE_NAME_LEN]char用户名
is_matched_bool如果距离小于人脸间距阈值,则为真,否则为假
distance_float人脸距离

5. C++函数接口定义

对外接口的定义在face.h头文件中。

5.1. 函数接口定义

5.1.1. SunmiFaceGetVersion

函数定义:SUNMI_FACE_API const char* SunmiFaceGetVersion();

函数功能:获取Sunmi人脸识别SDK版本

返回值:SDK版本字符串

5.1.2. SunmiFaceCreate

函数定义:SunmiFaceStatus SunmiFaceCreate(SunmiFaceHandle* handle);

函数功能:创建句柄,用户需要保持这个句柄直到释放

变量类型说明
handleSunmiFaceHandle*输出参数,创建人脸SDK句柄

返回值:SunmiFaceStatus

5.1.3. SunmiFaceInit

函数定义:SunmiFaceStatus SunmiFaceInit(SunmiFaceHandle handle,  const std::string& config_file);

函数功能:使用配置文件初始化SDK

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
config_fileconst std::string&配置文件路径

返回值:SunmiFaceStatus

5.1.4. SunmiFaceGetErrorString

函数定义:const char* SunmiFaceGetErrorString(SunmiFaceStatus code);

函数功能:通过SunmiFaceStatus得到错误描述字符串

变量类型说明
codeSunmiFaceStatusSunmiFaceStatus code

返回值:错误描述字符串

5.1.5. SunmiFaceVerifyLicense

函数定义:SunmiFaceStatus SunmiFaceVerifyLicense(SunmiFaceHandle handle, const std::string& fingerprint, const std::string& license);

函数功能:验证设备指纹和授权文件是否合法

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
fingerprintconst std::string&设备指纹字符串
licenseconst std::string&授权文件字符串

返回值:SunmiFaceStatus

5.1.6. SunmiFaceSetConfig

函数定义:SunmiFaceStatus SunmiFaceSetConfig(SunmiFaceHandle handle, const SunmiFaceConfigParam& config);  

函数功能:设置配置信息

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
configconst SunmiFaceConfigParam&配置参数

返回值:SunmiFaceStatus

5.1.7. SunmiFaceGetConfig

函数定义:SunmiFaceStatus SunmiFaceGetConfig(SunmiFaceHandle handle, SunmiFaceConfigParam& config);

函数功能:获取当前SDK参数

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
configSunmiFaceConfigParam&配置参数

返回值:SunmiFaceStatus

5.1.8. SunmiFaceRelease

函数定义:SunmiFaceStatus SunmiFaceRelease(SunmiFaceHandle handle);

函数功能:释放句柄

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄

返回值:SunmiFaceStatus

5.1.9. SunmiFaceGetImageFeatures

函数定义:SunmiFaceStatus SunmiFaceGetImageFeatures(SunmiFaceHandle handle, SunmiFaceImage image, SunmiFaceImageFeatures *features);

函数功能:从图像中获取人脸特征

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
imageSunmiFaceImage输入图片结构体
featuresSunmiFaceImageFeatures *返回人脸特征

返回值:SunmiFaceStatus

5.1.10. SunmiFaceCompare1v1

函数定义:SunmiFaceStatus SunmiFaceCompare1v1(SunmiFaceHandle handle, SunmiFaceFeature *feature1, SunmiFaceFeature *feature2, SunmiFaceCompareResult *compare_result);

函数功能:1:1人脸比对

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
feature1SunmiFaceFeature *比较特征1
feature2SunmiFaceFeature *比较特征2
compare_resultSunmiFaceCompareResult *比对结果

返回值:SunmiFaceStatus

5.1.11. SunmiFaceReleaseImageFeatures

函数定义:SunmiFaceStatus SunmiFaceReleaseImageFeatures(SunmiFaceImageFeatures *features);

函数功能:释放人脸特征

变量类型说明
featuresSunmiFaceImageFeatures *人脸特征

返回值:SunmiFaceStatus

5.1.12. SunmiFaceInitDB

函数定义:SunmiFaceStatus SunmiFaceInitDB(SunmiFaceHandle handle, const char* db_name);

函数功能:打开人脸数据库文件,如果不存在,则创建空的人脸数据库。SDK初始化时会默认打开config.json里面指定的face_db_file

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
db_nameconst char*数据库文件名称

返回值:SunmiFaceStatus

5.1.13. SunmiFaceAddDBRecord

函数定义:SunmiFaceStatus SunmiFaceAddDBRecord(SunmiFaceHandle handle, SunmiFaceDBRecord *record);

函数功能:添加一条人脸记录到人脸数据库中

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
recordSunmiFaceDBRecord *record人脸记录

返回值:SunmiFaceStatus

5.1.14. SunmiFaceSearchDB

函数定义:SunmiFaceStatus SunmiFaceSearchDB(SunmiFaceHandle handle, SunmiFaceDBRecord *record, SunmiFaceDBIdInfo *idInfo);

函数功能:1:N 人脸搜索

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
recordSunmiFaceDBRecord *人脸库记录结构体
idInfoSunmiFaceDBIdInfo *搜索结果

返回值:SunmiFaceStatus

5.1.15. SunmiFaceDeleteDBRecord

函数定义:SunmiFaceStatus SunmiFaceDeleteDBRecord(SunmiFaceHandle handle, char *img_id);

函数功能:根据图像id删除人脸数据库中的一个人脸记录

变量类型说明
handleSunmiFaceHandle输出参数,创建人脸SDK句柄
img_idchar *人脸采集图像在人脸库里的唯一ID

返回值:SunmiFaceStatus

6. Java函数接口定义

对外接口的定义在SunmiFaceSDK.java文件中。

6.1. 接口类定义

类名说明
SunmiFaceSDK人脸识别接口类名定义

6.2. 函数接口定义

6.2.1. getVersion

函数定义:public static String getVersion()

函数功能:获取Sunmi人脸识别SDK版本号

返回值:SDK版本字符串

6.2.2. Init

函数定义:public static int init(String configPath)

函数功能:初始化SDK

变量类型说明
configPathString配置文件路径

返回值:SunmiFaceStatusCode

6.2.3. verifyLicense

函数定义:public static int verifyLicense(Context context, String license)

函数功能:验证许可证

变量类型说明
contextContextAndroid context
licenseString许可证字符串

返回值:SunmiFaceStatusCode

6.2.4. getDeviceFingerprint

函数定义:public static String getDeviceFingerprint(Context context)

函数功能:获取Android设备指纹

变量类型说明
contextContextandroid context

返回值:设备指纹字符串

6.2.5. getErrorString

函数定义:public static String getErrorString(int code)

函数功能:获得错误字符串

变量类型说明
codeint错误代码

返回值:错误描述字符串

6.2.6. setConfig

函数定义:public static int setConfig(SunmiFaceConfigParam config)

函数功能:设置配置

变量类型说明
configSunmiFaceConfigParamSDK配置参数

返回值:SunmiFaceStatusCode

6.2.7. getConfig

函数定义:public static int getConfig(SunmiFaceConfigParam config)

函数功能:获取当前SDK配置

变量类型说明
configSunmiFaceConfigParamSDK配置参数

返回值:SunmiFaceStatusCode

6.2.8. getImageFeatures

函数定义:public static int getImageFeatures(SunmiFaceImage image, SunmiFaceImageFeatures features)

函数功能:从图像中进行人脸检测和人脸特征提取

变量类型说明
imageSunmiFaceImage输入图像
featuresSunmiFaceImageFeatures返回人脸特征

返回值:SunmiFaceStatusCode

6.2.9. compare1v1

函数定义:public int compare1v1(SunmiFaceFeature feature1, SunmiFaceFeature feature2, SunmiFaceCompareResult compare_result)

函数功能:人脸1:1比对

变量类型说明
features1SunmiFaceFeature人脸特征1
features2SunmiFaceFeature人脸特征2
compare_resultSunmiFaceCompareResult比对结果

返回值:SunmiFaceStatusCode

6.2.10. releaseImageFeatures

函数定义:public static int releaseImageFeatures(SunmiFaceImageFeatures features)

函数功能:释放人脸特征

变量类型说明
featuresSunmiFaceImageFeatures人脸特征

返回值:SunmiFaceStatusCode

6.2.11. initDB

函数定义:public static int initDB(String db_name)

函数功能:初始化新人脸数据库

变量类型说明
db_nameString人脸数据库文件名

返回值:SunmiFaceStatusCode

6.2.12. faceFeature2FaceDBRecord

函数定义:public static SunmiFaceDBRecord faceFeature2FaceDBRecord(SunmiFaceFeature feature)

函数功能:将人脸特征结构体转换成人脸库记录结构体

变量类型说明
featureSunmiFaceFeature人脸特征

返回值:SunmiFaceDBRecord

6.2.13. addDBRecord

函数定义:public static int addDBRecord(SunmiFaceDBRecord record)

函数功能:添加一条记录到人脸数据库,添加成功后通过img_id_可以的到人脸库中图片的ID,后续可以用来删除操作

变量类型说明
recordSunmiFaceDBRecord人脸库记录结构体

返回值:SunmiFaceStatusCode

6.2.14. searchDB

函数定义:public static int searchDB(SunmiFaceDBRecord record, SunmiFaceDBIdInfo idInfo)

函数功能:数据库中1:N人脸比对

变量类型说明
recordSunmiFaceDBRecord要搜索的人脸记录
idInfoSunmiFaceDBIdInfo搜索结果

返回值:SunmiFaceStatusCode

6.2.15. deleteDBRecord

函数定义:public static int deleteDBRecord(String img_id)

函数功能:根据图像id删除人脸数据库中的一条记录

变量类型说明
img_idString人脸采集图像的ID

返回值:SunmiFaceStatusCode

功能介绍

产品简介

商米人脸识别离线SDK包,包含人脸识别、人脸对比以及活体检测等功能, 主要通过人脸检测定位人脸坐标并进行面部特征提取,再通过人脸比对技术可快速完成1:N的人脸比对。在增加证件读取信息后,可提供1:1人证比对服务。 商米人脸识别SDK几乎全面适配配备摄像头的商米安卓设备,包括台式,自助,手持,称重等几乎所有畅销型号。

产品优势

高识别率

模型识别率达到99%以上,在多个万级公开人脸库对比测试中处于世界先进水平。特别根据商米机型和常见使用环境进行了调优,提高了实际场景的识别率。

快速响应

秒级响应,主体人脸特征抽取过程小于200ms(D2设备百次平均)。整体识别过程还包括其他诸如相机启动、图片质量检测、人脸位置检测、照片预处理、人脸库比对等,不同设备整体速度实测在500ms至1000ms。

场景丰富

广泛应用于多种场景,比如私域会员识别和支付(企业食堂结账、会员识别优惠、到店顾客转化率分析、访客管理、工厂流水线人员识别等),身份验证(酒店入住身份证验证、医保卡身份验证,社保卡养老金领取身份验证等)多种场景。

离线运行

集成到设备中离线运行,可完全本地化实现人脸识别SDK的相关功能。

核心功能

人脸识别SDK核心能力是将人脸转化为特征码,并在向量空间内可以对不同人脸进行区分。

实际应用时还需要人脸识别SDK中其他能力配合,比如1:N识别场景中的人脸库建立,1:1场景中证件的读取,以及摄像头调用、人脸位置检测、图像质量检测、图片多种大量的预处理过程、具体应用场景特定接口调用方式等。

1:N人脸识别(私域会员识别和支付)

通过提取当前人脸特征,搜索匹配本地人脸库中相似度最高的人脸,并返回成功匹配的人脸信息。

人脸库建立(1:N使用)

人脸库可通过设备采集(增量用户)、批量导入(初始用户)、页面采集等多种方式进行人脸图片收集,并通过离线人脸库和服务器端的交互实现多个设备间的人脸库同步。

1:1人脸识别(身份验证)

通过证件读取器读取证件照片,与当前采集的人脸特征进行人证比对,并返回比对结果。

活体检测

活体检测主要为了抵御使用他人照片或者手机图片等通过人脸识别,获取他人身份账户权益,容易出现在与资金流程相关以及无监控人员的自助场景。大部分场景不一定需要活体检测。

活体检测包括3种类型:RGB彩色图活体、NIR近红外活体和3D结构光活体。RGB彩色图活体使用普通摄像头图片判断,抵御能力普通,如果对活体有要求,建议直接考虑NIR近红外活体和3D结构光活体。

NIR近红外活体和3D结构光活体

商米不同型号设备摄像头配置选择可能有区别,请咨询商米销售。另外在选择设备和方案阶段,我们很乐于提供一些实际场景应用的经验。

使用场景类型举例

私域支付

企业员工餐厅,校园餐厅一般使用私域账户系统扣款。私域环境一般客群固定,使用频次高,对人脸支付接受度高。
使用人脸识别支付提高了结账速度和安全性,顾客获得了更好的体验,餐厅管理方提升了效率,餐厅软件方增加了项目机会,实现了多赢局面。

商米设备推荐:台式T2、D2、D2mini、挂壁式FTmini。

会员识别

美发,美容等有店铺会员卡和熟客占比高的行业,人脸识别可以实现熟客管理。
通过合理配置人脸识别,可以管理客户会员卡真实使用情况,防止会员卡盗用;并且可以记录客户来店频率、时长和区域停留,更好为熟客提供服务。

商米设备推荐:台式T2、D2和IPC摄像头系列

身份验证

人脸识别身份验证主要应用于需要核实身份的场合,包括身份证验证(可以搭配身份证读取器或者身份证云服务),医保卡身份验证(医院场景),社保卡身份验证(政府补贴领取)等。
人脸识别身份验证通常比人工验证更快速准确,并留下记录便于管理,根据不同场景可以设置不同阈值和人工再次确认流程。

商米设备推荐:自助K2或台式设备T2、D2等。

设备适配

商米人脸识别SDK能够全面适配带有摄像头的商米安卓设备,目前 K1、K2、D2、D2mini、T2、 FTmini、V2 Pro、L2K等设备都有不同落地场景。一般来讲,商米设备都可以应用人脸识别离线SDK包,但不是所有商米设备都默认配备有摄像头,请咨询销售和相关技术人员。