开放能力
开发平台
行业应用
生态合作
开发与教学
资讯 社区 控制台
技术能力
语音技术
图像技术
文字识别
人脸与人体识别
视频技术
AR与VR
自然语言处理
知识图谱
数据智能
场景方案
部署方案
行业应用
智能教育
智能医疗
智能零售
智能工业
企业服务
智能政务
智能农业
信息服务
智能园区
智能硬件
人脸识别

    集成开发

    本文档为您介绍了纯服务端的接入流程。

    一、 准备工作

    在正式集成前,需要做一些准备工作,完成一些账号、应用及配置,具体如下:

    1.1 注册成为开发者

    1. STEP1:点击百度AI 开放平台导航右侧的控制台,页面跳转到百度云登录界面,登录完毕后,将会进入到百度云后台,点击「控制台」进入百度云控制台页面;您也可以在官网直接点击免费试用,登录完毕后将自动进入到百度云控制台。
    2. STEP2:使用百度账号完成登录,如您还未持有百度账户,可以点击此处注册百度账户。
    3. STEP3:进入百度云欢迎页面,填写企业和个人基本信息,注册完毕,至此成为开发者。(如您之前已经是百度云用户或百度开发者中心用户,STEP3 可略过。)
    4. STEP4:进入百度云控制台,找到人工智能相关服务面板。
    5. STEP5:点击进入「人脸识别」模块。

    1.2 创建应用

    创建好账号后,在正式调用AI 能力之前,需要您创建一下应用,这个是调用服务的基础能力单元。 选择「人脸识别」服务,首先见到此服务的控制台概览页,点击「创建应用」,即可进入应用创建界面,如下图所示:

    创建应用

    如上图所示,点击「创建应用」,即可进入应用创建界面,如下图所示:

    img

    注意:您需要创建一个应用,分别做以下作用:

    • 应用一:勾选身份证识别能力,绑定iOS OCR、Android OCR包名,用于使用OCR能力。
    • 应用二:此应用默认会沟通人脸实名认证能力,用于使用身份验证判断;

    1.3 获取秘钥

    获取秘钥

    在您创建完毕应用后,平台将会分配给您此应用的相关凭证,主要为AppID、API Key、Secret Key,以上三个信息是您应用实际开发的主要凭证,每个应用之间各不相同,请您妥善保管。如上图所示。该AK/SK用于调用在线API 如:身份验证。注:开发中请注意区分多份AK/SK(API Key、Secret Key)

    1.4 生成token

    刚才所创建的应用在调用开放平台API 之前,首先需要获取Access Token(用户身份验证和授权的凭证)您需要使用创建应用所分配到的AppID、API Key 及Secret Key,进行Access Token 的生成,方法详见 Access Token 获取,我们为您准备了几种常见语言的请求示例代码。

    注:Access Token 的有效期为30天(以秒为单位),请您集成时注意在程序中定期请求新的token,或每次请求都获取一次token。

    1.5 SDK License 配置

    • OCR身份证识别SDK License:此License封装了aksk,用于更方便地调用接口。请在刚才创建的两个身份证应用中,点击「应用名称」,进入应用详情页面,找到如下图所示内容:

    img

    点击button,下载此license文件,名称都为aip.license(分别用于iOS和安卓),稍后集成需要使用。

    • 人脸SDK License :此license用于SDK离线功能使用,在您的申请人脸SDK的后台页面,下载两个端的license,如下图所示:

    img

    用于接下来集成使用,不过我们为您提供了自动化配置脚本,如下图所示:

    img

    强烈推荐您在下载核身示例工程的同时,直接下载已经配置好授权信息的版本。

    二、集成逻辑

    2.1 集成流程

    下面我们将以更为复杂的有源身份验证作为范例讲解:

    img

    如上图所示,集成逻辑可以概括为三个核心步骤:

    1. OCR SDK获取身份证信息,本地输出。
    2. 人脸SDK获取活体检测图片,本地输出。
    3. 将姓名、身份证号、人脸图像推送到您的server端,从server端先调用在线身份验证接口,得到结果。

    如何判断业务是否终止,主要分为五个节点:

    1. 身份证不合规:在身份证识别的返回参数中,有如下字段:如判断身份证信息为非正常身份证,可提示用户,并中断验证流程;
    2. 人脸SDK本地有动作活体检测,如果用户无法完成指定动作,也无法继续进行;
    3. 人脸图像质量较低(如选择了此项),流程中止;
    4. 人脸图像经在线活体检测判断分数过低,流程中止;
    5. 前三步都完成,但是人脸实名认证分数过低,也可提示核身验证失败。

    2.2 服务中转

    img

    SDK获取人脸过程中的处理,完全无需联网,但人脸对比、人脸查找、人脸属性分析能力需要调用API使用。产品策略方面,因API使用需要使用在线鉴权token,为token的安全起见,建议将人脸推送到server端再调用API接口。

    对安全有进一步需求的话,为防止人脸传输过程中被篡改,可对SDK本地输出的人脸图像做加密处理,在server端进行相应解密操作,进一步增强安全性。

    2.3 阈值选择

    v3版本的身份验证接口中,对于质量控制、活体控制的阈值设定,都简化为LOWNORMALHIGH三个级别,您只需指定等级作为阈值即可,无需设定具体的数值阈值。

    脸部遮挡指标(质量校验)

    每一项详细判断项,取值范围[0~1],0为无遮挡,1是完全遮挡

    控制度 left_eye right_eye nose mouth left_cheek right_cheek chin_contour
    LOW 0.8 0.8 0.8 0.8 0.8 0.8 0.8
    NORMAL 0.6 0.6 0.6 0.6 0.6 0.6 0.6
    HIGH 0.2 0.2 0.2 0.2 0.2 0.2 0.2

    光照、模糊度、完整度指标(质量校验)

    • illumination:取值范围[0~255],脸部光照的灰度值,0表示光照不好。以及对应客户端SDK中,YUV的Y分量。
    • blurdegree:取值范围[0~1],0是最清晰,1是最模糊。
    • completeness:0或1,0为人脸溢出图像边界,1为人脸都在图像边界内。
    控制度 illumination blurdegree completeness
    LOW 20 0.8 0
    NORMAL 40 0.6 0
    HIGH 100 0.2 1

    活体检测阈值指标

    • 误拒率(FRR):如0.5%,指1000次真人请求,会有5次因为活体分数低于阈值被错误拒绝。
    控制度 对应阈值 说明
    LOW 0.05 万分之一活体误拒率
    NORMAL 0.3 千分之一活体误拒率
    HIGH 0.9 百分之一活体误拒率

    身份验证对比分值的阈值选择

    阈值分数 误识率 识别率
    60 0.781615% 99.550128%
    70 0.096534% 98.307626%
    78 0.015570%(万分之一) 95.672664%
    80 0.009342%(低于万分之一) 94.323051%

    注:识别率与误识率成正比:识别率越高,误识率越高;识别率降低,误识率也降低;

    三、 IOS集成

    3.1 OCR身份证识别集成

    把下载下来的License文件(文件名:aip.license),添加到项目里面,无需更改文件名称,然后在AppDelegate添加以下代码引用进去。

    img

    FaceParameterConfig.h里面设置下载下来的License文件的名字和后缀。

    img

    通过API调用ViewController进行身份证扫描

    img

    详细调用文档,请参考 OCR-iOS-SDK文档

    3.2 人脸SDK集成

    1、打开或者新建一个项目。

    2、右键点击项目,会出现一个添加菜单,在菜单中选择『Add Files to“此处是你的项目名字”…… 』,如下图所示:

    img

    3、在添加文件弹出框里面选择申请到的license和SDK添加进来。如下图:

    注意:license为百度官方提供,刚才在后台下载的文件(文件名称:idl-license.face-ios)

    SDK包含下面三个文件:

    • IDLFaceSDK.framework
    • com.baidu.idl.face.faceSDK.bundle
    • com.baidu.idl.face.model.bundle

    img

    4、确认下 Bundle Identifier 是否是申请license时填报的那一个.

    5、注意:license 和 Bundle Identifier 为一一对应关系,填错了会导致SDK不可用.

    img

    6、 FACE_LICENSE_ID这个参数填写百度官方给的LicenseID

    FaceParameterConfig.h 文件中填写下面三项。

    img

    7、选择链接C++标准库。

    img

    8、如果没有使用pod管理第三方库的话,请在Build Setting Linking Other Linker Flags 上面加入 –ObjC选项。如果用了pod请忽略,因为pod会自动添加上。

    img

    以下为示例工程调用身份验证的代码片段:

    [[NetAccessModel sharedInstance] verifyFaceAndIDCard:self.nameTextField.text idNumber:self.identityCardTextField.text imageStr:imageStr completion:^(NSError *error, id resultObject) {
        if (error == nil) {
            NSDictionary* dict = [NSJSONSerialization JSONObjectWithData:resultObject options:NSJSONReadingAllowFragments error:nil];
            NSLog(@"dict = %@",dict);
            dispatch_async(dispatch_get_main_queue(), ^{
                FaceResultType type = FaceResultTypeFail;
                NSString* tip = @"验证分数";
                NSString* scoreStr = @"";
                NSString* showStr = nil;
                if ([dict[@"error_code"] intValue] == 0) {
                    CGFloat score = [dict[@"result"][@"score"] floatValue];
                    scoreStr = [NSString stringWithFormat:@"%.4f",score];
                    if (score > 80) {
                        type = FaceResultTypeSuccess;
                    }
                } else {
                    tip = [NSString stringWithFormat:@"错误码:%@\n错误信息:%@",dict[@"error_code"],dict[@"error_msg"]];
                }
                NSMutableDictionary* resultDict = [@{} mutableCopy];
                resultDict[@"type"] = @(type);
                resultDict[@"tip"] = tip;
                resultDict[@"score"] = scoreStr;
                resultDict[@"showStr"] = showStr;
                [weakSelf performSegueWithIdentifier:@"Affirm2Result" sender:resultDict];
            });
        } else {
            NSLog(@"网络请求失败");
        }
    }];

    接下来基于接口返回的分数进行业务判断即可,详细业务流程详见2.2.1所示。

    四、安卓集成

    4.1 OCR身份证识别集成

    • 把申请的license(aip.license)放到到项目中assets目录中
    • 修改app的build.gradle和AndroidMainest.xml包名为申请时填入的包名
    • 拷贝ocr-ui到您的工程中

    接下来调用具体请看Demo中的IdCardActivity

    1、初始化OCR SDK

    img

    2、调用api进行身份证扫描

    img

    3、调用api进行身份证识别

    img

    4、获得身份证号码和姓名后进入人脸活体验证步骤

    详细调用文档,请参考 OCR-Android-SDK文档

    4.2 人脸SDK集成

    1、授权参数

    a、把申请的license(idl-license.face-android")放到到项目中assets目录中

    b、修改 Config 类中的参数

    public class Config {
        // 为了apiKey,secretKey为您调用百度人脸在线接口的,如注册,比对等。
    	// 为了的安全,建议放在您的服务端,端把人脸传给服务器,在服务端端
    	// license为调用sdk的人脸检测功能使用,人脸识别 = 人脸检测(SDK功能)+ 人脸比对(服务端API)
        public static String apiKey = "替换为你的apiKey(ak)";
        public static String secretKey = "替换为你的secretKey(sk)";
        public static String licenseID = "替换为你的licenseID,后台SDK管理界面中,已经生成的licenseID,如:test-face-android";
        public static String licenseFileName = "替换为你的license文件";
        /* * 人脸识别 接口 https://aip.baidubce.com/rest/2.0/face/v3/search * 人脸注册 接口 https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add */
        public static String groupID = "替换为你的人脸组groupID";
    }

    c、配置签名(申请license时的md5为打包签名的文件,所以必须用申请license的签名文件)

    app->build.gradle->android->signingConfigs
    signingConfigs {
            def password = "替换为签名密码"
            def alias = "替换为签名别名"
            def filePath = "替换为签名文件路径"  //如 ../facesharp.jks//签名文件路径
            debug {
                keyAlias alias
                keyPassword password
                storeFile file(filePath)
                storePassword(password)
            }
            release {
                keyAlias alias
                keyPassword password
                storeFile file(filePath)
                storePassword(password)
            }
        }

    d、修改包名 app->build.gradle->android->defaultConfig ->您申请license时填的包名

    2、继承 FaceLivenessActivity,初始人脸SDK

    	/** * 初始化SDK */
        private void initLib() {
            // 为了android和ios 区分授权,appId=appname_face_android ,其中appname为申请sdk时的应用名
            // 应用上下文
            // 申请License取得的APPID
            // assets目录下License文件名
            FaceSDKManager.getInstance().init(this, Config.licenseID, Config.licenseFileName);
            setFaceConfig();
        }

    3、设置参数,如不设置,将使用默认值

    	private void setFaceConfig() {
            FaceTracker tracker = FaceSDKManager.getInstance().getFaceTracker(this);
            // SDK初始化已经设置完默认参数(推荐参数),您也根据实际需求进行数值调整
    
            // 模糊度范围 (0-1) 推荐小于0.7
            tracker.set_blur_thr(FaceEnvironment.VALUE_BLURNESS);
            // 光照范围 (0-1) 推荐大于40
            tracker.set_illum_thr(FaceEnvironment.VALUE_BRIGHTNESS);
            // 裁剪人脸大小
            tracker.set_cropFaceSize(FaceEnvironment.VALUE_CROP_FACE_SIZE);
            // 人脸yaw,pitch,row 角度,范围(-45,45),推荐-15-15
            tracker.set_eulur_angle_thr(FaceEnvironment.VALUE_HEAD_PITCH, FaceEnvironment.VALUE_HEAD_ROLL,
                    FaceEnvironment.VALUE_HEAD_YAW);
    
            // 最小检测人脸(在图片人脸能够被检测到最小值)80-200, 越小越耗性能,推荐120-200
            tracker.set_min_face_size(FaceEnvironment.VALUE_MIN_FACE_SIZE);
            //
            tracker.set_notFace_thr(FaceEnvironment.VALUE_NOT_FACE_THRESHOLD);
            // 人脸遮挡范围 (0-1) 推荐小于0.5
            tracker.set_occlu_thr(FaceEnvironment.VALUE_OCCLUSION);
            // 是否进行质量检测
            tracker.set_isCheckQuality(true);
            // 是否进行活体校验
            tracker.set_isVerifyLive(false);
        }

    4、开始进行活体检测

    5、获取活体检测结果

    	@Override
        public void onLivenessCompletion(FaceStatusEnum status, String message, HashMap<String, String> base64ImageMap) {
            super.onLivenessCompletion(status, message, base64ImageMap);
            if (status == FaceStatusEnum.OK && mIsCompletion) {
                // Toast.makeText(this, "活体检测成功", Toast.LENGTH_SHORT).show();
                saveImage(base64ImageMap);
                alertText("检测结果", "活体检测成功");
            } else if (status == FaceStatusEnum.Error_DetectTimeout ||
                    status == FaceStatusEnum.Error_LivenessTimeout ||
                    status == FaceStatusEnum.Error_Timeout) {
                // Toast.makeText(this, "活体检测采集超时", Toast.LENGTH_SHORT).show();
                alertText("检测结果", "活体检测采集超时");
            }
        }

    6、保持活体检测得到图片,以便进行身份核验接口调用

        private void saveImage(HashMap<String, String> imageMap) {
            // imageMap 里保存了最佳人脸和各个动作的图片,若对安全要求比较高,可以传多张图片进行在线活体,目前只用最佳人脸进行了在线活体检测
           
            String bestimageBase64 = imageMap.get("bestImage0");
            Bitmap bmp = base64ToBitmap(bestimageBase64);
    
    		// Bitmap newBmp = detect(bmp);
    		// if (newBmp == null) {
        	// newBmp = bmp;
        	// }
    
            // 如果觉的在线校验慢,可以压缩图片的分辨率,目前没有压缩分辨率,压缩质量置80,在neuxs5上大概30k,后面版本我们将截出人脸部分,大小应该小于10k
            try {
                File file = File.createTempFile("face", ".jpg");
                FileOutputStream outputStream = new FileOutputStream(file);
                bmp.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);
                outputStream.close();
    
                bestImagePath = file.getAbsolutePath();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    7、获取token,用于调用接口

    注意:通过ak,sk获取,为了防止ak,sk泄露,建议把ak/sk放在服务端,移动端通过服务端去拉取token

        private void initAccessToken() {
            APIService.getInstance().init(this);
            // 用ak,sk获取token, 调用在线api,如:注册、识别等。为了ak、sk安全,建议放您的服务器,
            APIService.getInstance().initAccessTokenWithAkSk(new OnResultListener<AccessToken>() {
                @Override
                public void onResult(AccessToken result) {
                    Log.i("wtf", "AccessToken->" + result.getAccessToken());
                }
    
                @Override
                public void onError(FaceException error) {
                    Log.e("xx", "AccessTokenError:" + error);
                    error.printStackTrace();
    
                }
            }, Config.apiKey, Config.secretKey);
        }

    8、根据离线活体得到的人脸,进行在线活体检测和人脸实名认证(参见FaceOnlineVerifyActivity)

    如果参选择 quality_controlliveness_control 这两个参数,则检测顺序将会变为: 图片质量检测-> 活体检测 -> 权威数据源人脸实名认证,其中前两个环节有任意一个条件不通过,则检测流程流程终止,返回信息中会说明不符合的详细内容;如果前两个检测条件全部验证通过,则会执行人脸实名认证接口请求,返回内容包含对比分数。

    提示:为了安全及维护成本考虑,我们建议您将SDK获取的人脸图像,推送到服务器端,由服务器端进行API调用,并将结果返回给客户端APP

    	private void policeVerify(String filePath) {
            if (TextUtils.isEmpty(filePath) || waitAccesstoken) {
                return;
            }
            File file = new File(filePath);
            if (!file.exists()) {
                return;
            }
    
            displayTip(resultTipTV, "权威数据源身份核实中...");
            APIService.getInstance().policeVerify(username, idnumber, filePath, new
                    OnResultListener<LivenessVsIdcardResult>() {
                        @Override
                        public void onResult(LivenessVsIdcardResult result) {
                            if (result != null && result.getScore() >= 80) {
                                delete();
                                displayTip(resultTipTV, "核身成功");
                                displayTip(scoreTV, "人脸实名认证分数:" + result.getScore());
                            } else {
                                displayTip(resultTipTV, "核身失败");
                                displayTip(scoreTV, "人脸实名认证分数过低:" + result.getScore());
                                retBtn.setVisibility(View.VISIBLE);
                            }
                        }
    
                        @Override
                        public void onError(FaceException error) {
                            delete();
                            // TODO 错误处理
                            // 如返回错误码为:216600,则核身失败,提示信息为:身份证号码错误
                            // 如返回错误码为:216601,则核身失败,提示信息为:身份证号码与姓名不匹配
                            Toast.makeText(FaceOnlineVerifyActivity.this,
                                    "权威数据源人脸实名核实失败:" + error.getMessage(), Toast.LENGTH_SHORT)
                                    .show();
                            retBtn.setVisibility(View.VISIBLE);
    
                        }
                    }
            );
        }
    上一篇
    接入说明
    下一篇
    接口文档