1. 概述
人脸识别技术(Automatic Face Recognition),简称AFR,是生物识别技术的一种,通过人的面部特征,进行身份鉴别。
本文档旨在讲解如何快速地集成灵云AFR功能到开发者应用中。关于各服务接口更详细的说明,请参考灵云SDK开发手册。在集成过程中如有疑问,可登录灵云开发者论坛,查找答案或与其他开发者交流。
1.1 概念解释
对指南中涉及的名词作简要描述,使开发者在阅读开发指南时,对此有一些大致的了解和预备知识的了解。
名称 | 说明 |
---|---|
Session | Session用来标记一个能力运行过程的上下文。一个应用最多可同时创建的Session数受到授权的限制 |
云端识别 | 由云端服务器提供识别结果的方式。使用云端能力需要加上hci_afr_cloud_recog模块 |
本地识别 | 通过本地运算来得到识别结果的方式。使用本地能力需要加上hci_afr_local_recog模块和本地资源文件 |
人脸检测 | 通过对会话图像进行检测,提取其中的人脸特征。通过hci_afr_detect函数实现 |
人脸注册 | 通过对人脸模型进行多次训练,达到提高识别速度和正确率的目的。通过hci_afr_enroll函数实现 |
人脸确认 | 使用人脸ID与已注册的用户ID的特征进行匹配性确认。通过hci_afr_verify函数实现 |
人脸辨识 | 在一组用户中进行指定人脸ID的用户辨识。通过hci_afr_identify函数实现 |
1.2 能力定义(capkey)
AFR 支持多种能力,通过 capkey 区分不同能力的调用和配置。其中常用 capkey 如下所示:
capkey | 所需本地资源文件 |
---|---|
afr.cloud.recog | 无 |
1.3 识别流程
2. 能力使用说明
2.1 准备工作
在集成 ASR 之前,开发者需要在灵云开发者社区创建相关应用,并保存appkey,developerkey等信息。
2.3 使用C++版SDK
必选模块
- hci_sys.dll
- libhci_curl.dll
- hci_afr.dll
云端识别
- hci_afr_cloud_recog.dll
本地识别
- AFREngine.dll
- hci_afr_local_recog.dll
- mkl_avx.dll
- mkl_avx2.dll
- mkl_core.dll
- mkl_intel_thread.dll
- mkl_p4n.dll
- mkl_rt.dll
- mkl_sequential.dll
- mkl_vml_avx.dll
- mkl_vml_avx2.dll
- mkl_vml_cmpt.dll
- mkl_vml_p4n.dll
- opencv_core342.dll
- opencv_dnn342.dll
- opencv_imgcodecs342.dll
- opencv_imgproc342.dll
- opencv_objdetect342.dll
- opencv_video342.dll
- tensorflow.dll
- TFCore.dll
- iReadText.dll
3. 能力集成说明
3.1 通用模块初始化
在调用ASR能力之前,需要初始化灵云SDK的通用模块。详见灵云SDK开发手册
在调用能力之前,需要初始化灵云SDK的通用模块。详见灵云SDK开发手册
- C++示例代码
HCI_ERR_CODE err_code = HCI_ERR_NONE;
//配置串是由"字段=值"的形式给出的一个字符串,多个字段之间以','隔开。字段名不分大小写。
string init_config = "";
//灵云应用序号
init_config += "appKey=1234abcd";
//灵云开发者密钥
init_config += ",developerKey=1234567890";
//灵云云服务的接口地址
init_config += ",cloudUrl=http://api.hcicloud.com:8888";
//授权文件所在路径,保证可写
init_config += ",authpath=../../bin";
//日志的路径
init_config += ",logfilepath=../../bin";
//日志的等级
init_config += ",loglevel=5";
//日志文件的大小
init_config += ",logfilesize=512";
//其他配置使用默认值,不再添加,如果想设置可以参考开发手册
err_code = hci_init( init_config.c_str() );
提示 因灵云SDK8.1使用Visual Studio 2015开发的原因,在windows下的开发运行环境需要确认安装运行组件
vc_redist.x64.exe
,vc_redist.x86.exe
, 具体请参考https://www.microsoft.com/zh-cn/download/details.aspx?id=48145
3.2 授权检测
在初始化灵云SDK的通用模块后,还需要调用授权检测函数获取云端授权。
C++示例代码
//获取过期时间
int64 expire_time;
int64 current_time = (int64)time( NULL );
HCI_ERR_CODE err_code = hci_get_auth_expire_time( &expire_time );
if( err_code == HCI_ERR_NONE )
{
//获取成功则判断是否过期
if( expire_time > current_time )
{
//没有过期
printf( "auth can use continue\n" );
return true;
}
}
//获取过期时间失败或已经过期
//手动调用更新授权
err_code = hci_check_auth();
if( err_code == HCI_ERR_NONE )
{
//更新成功
printf( "check auth success \n" );
return true;
}
else
{
//更新失败
printf( "check auth return (%d)\n", err_code);
return false;
}
3.3 AFR初始化
C++示例代码
//AFR 初始化 string afr_init_config = "dataPath="; afr_init_config += data_path; afr_init_config += ",initCapkeys="; afr_init_config += capkey; errCode = hci_afr_init(afr_init_config.c_str()); if (errCode != HCI_ERR_NONE) { printf("hci_afr_init return (%d) \n",errCode); return; }
3.4 开启会话(session)
AFR 是通过会话(session)来管理识别过程的。在AFR能力初始化成功之后,需要通过开启识别会话来完成识别。
C++示例代码
int session_id = -1; //用户模型路径,默认是授权文件路径 string session_config = "capkey=afr.local.recog,usermodelpath=e://"; HCI_ERR_CODE err_code = hci_afr_session_start(session_config.c_str(), &session_id); if( err_code != HCI_ERR_NONE ) { printf("hci_afr_session_start return (%d) \n",err_code); return; } printf( "hci_afr_session_start success\n" );
3.5 人脸注册
在启动会话(session)成功后,即可可以进行 AFR的人脸注册。
C++示例代码
//AFR人脸检测 errCode = hci_afr_set_image_buffer(sessionId, file.buff_, file.buff_len_); if (errCode != HCI_ERR_NONE) { printf("failed to set image.\n"); return errCode; } errCode = hci_afr_detect(sessionId, sessionConfig.c_str(), &detectResult); if (errCode != HCI_ERR_NONE) { printf("failed to detect face from image.\n"); return errCode; } else { PrintDetectResult(detectResult); } // 保存人脸检测结果用户ID列表。 for (int i = 0; i < detectResult.nFaceCount; i++) { faceIds.push_back(detectResult.pFaceList[i].pszFaceId); printf("detect face id = %s\n", detectResult.pFaceList[i].pszFaceId); } //AFR 人脸注册 string enrollConfig; enrollConfig += ",faceId=" + faceIds[0]; if (userId != "") { enrollConfig += ",userId=" + userId; } printf("hci_afr_enroll config [%s]\n", enrollConfig.c_str()); AFR_ENROLL_RESULT enrollResult; errCode = hci_afr_enroll(sessionId,enrollConfig.c_str(),&enrollResult); if (errCode != HCI_ERR_NONE) { printf("hci_afr_enroll return (%d) \n",errCode); return errCode; } userId = enrollResult.pszUserId; hci_afr_free_enroll_result(&enrollResult); // 释放人脸检测结果。 hci_afr_free_detect_result(&detectResult);
3.6 人脸确认
C++示例代码
// AFR人脸检测 err_code = hci_afr_set_image_buffer(sessionId, file.buff_, file.buff_len_); if (err_code != HCI_ERR_NONE) { printf("failed to set image.\n"); break; } err_code = hci_afr_detect(sessionId, sessionConfig.c_str(), &detectResult); if (err_code != HCI_ERR_NONE) { printf("failed to detect face from image.\n"); break; } else { PrintDetectResult(detectResult); } //保存人脸检测结果用户ID列表。 for (int i = 0; i < detectResult.nFaceCount; i++) { faceIds.push_back(detectResult.pFaceList[i].pszFaceId); } //Verify string verifyConfig = "userid=" + userId; verifyConfig += ",faceId=" + faceIds[0]; printf("hci_afr_verify config [%s]\n", verifyConfig.c_str()); AFR_VERIFY_RESULT verifyResult; err_code = hci_afr_verify(sessionId, verifyConfig.c_str(), &verifyResult); if( err_code != HCI_ERR_NONE ) { printf("hci_afr_verify return (%d) \n",err_code); break; } printf( "hci_afr_verify success\n" ); verifySuccess = true; if (verifyResult.eStatus == AFR_VERIFY_STATUS_MATCH) { printf( "face matches with user id:%s\n",userId.c_str() ); printf("the result score is :%d\n",verifyResult.uiScore); } else { printf("voice data doesn't match with user id:%s !\n",userId.c_str()); } isUserFace = verifyResult.eStatus == AFR_VERIFY_STATUS_MATCH; hci_afr_free_verify_result(&verifyResult); //释放人脸检测结果。 hci_afr_free_detect_result(&detectResult);
### 3.7 人脸辨识 {#H-3-7}
C++示例代码
//人脸检测 err_code = hci_afr_set_image_buffer(sessionId, file.buff_, file.buff_len_); if (err_code != HCI_ERR_NONE) { printf("failed to set image.\n"); return err_code; } err_code = hci_afr_detect(sessionId, sessionConfig.c_str(), &detectResult); if (err_code != HCI_ERR_NONE) { printf("failed to detect face from image.\n"); return err_code; } else { PrintDetectResult(detectResult); } //保存人脸检测结果用户ID列表。 for (int i = 0; i < detectResult.nFaceCount; i++) { faceIds.push_back(detectResult.pFaceList[i].pszFaceId); } string config = "groupId=" + groupId; config += ",faceId=" + faceIds[0]; printf("hci_afr_verify config [%s]\n", config.c_str()); //人脸辨识 AFR_IDENTIFY_RESULT result; err_code = hci_afr_identify(sessionId, config.c_str(), &result); if( err_code != HCI_ERR_NONE ) { printf("hci_afr_identify return (%d) \n",err_code); return err_code; } else { for (int i = 0; i < result.uiIdentifyResultItemCount; i++) { printf("identify result userid = %s, score = %d\n", result.pIdentifyResultItemList[i].pszUserId, result.pIdentifyResultItemList[i].uiScore); } } userId = result.pIdentifyResultItemList[0].pszUserId; hci_afr_free_identify_result(&result); // 释放人脸检测结果。 hci_afr_free_detect_result(&detectResult);
3.8 结束识别
最后我们需要反初始化,依次关闭会话,终止AFR能力,关闭灵云系统。
C++示例代码
//关闭AFR识别会话 errCode = hci_afr_session_stop(nSessionId); //终止AFR能力 errCode = hci_afr_release(); //终止灵云系统 errCode = hci_release();
4. FAQ
Q: 我运行你们的 SDK 报 19 号错误:START LOG FAILED, 应该如何解决? A: 出现此问题,一般由两种原因造成。
工程文件里引入了中文路径,导致SDK启动时,读写对应的日志路径报错。 日志文件定义的路径由于权限问题不可读写,比如在 Android 平台上运行时,没有 WRITE_EXTERNAL_STORAGE的权限。
Q: 我运行你们的 SDK 报 23 号错误:LOAD_FUNCTION_FROM_DLL FAILED,应该如何解决? A: 这种情况,通常是由于缺库。最常见的场景是使用本地能力的 capkey,如 afr.loacl.recog,没有将库文件对应组入(我们 SDK 示例程序,与 example 同层有全套库文件,示例程序内默认只组入了云端库),将相关库补齐即可使用。此外,由于 AFR能力引用了第三方的 MKL 库,因此如果第三方库没有拷入,也会导致此问题。
Q: 我运行你们的 SDK 报 14 号错误:LOCAL_RES_MISSING,应该如何解决? A: 本地能力常会遇到此问题,此问题是由于没有组入对应的本地资源文件。请在我们开发者社区下载需求的本地资源(VPR本地模型)等,并将资源文件组入代码 datapath 指定路径,然后再次尝试运行程序。
Q: 我运行你们的 SDK 报 11 号错误:SERVICE_RESPONSE_FAILED ,应该如何解决? A: 此问题原因较为复杂,可能是传入的参数问题与服务器不匹配,如调用私有云时,没有传入 property 等配置项。也可能是服务端内部的返回原因,请联系技术支持排查。
Q: 我运行你们的SDK报 7 号错误:CONFIG_UNSUPPORT ,应该如何解决? A: 与 11号错误类似,还是配置串问题,7 号错误原因为传入了不支持的配置串。请仔细检查各接口传入的所有配置串,并联系技术支持排查。
Q: 我运行你们的SDK报 9 号错误: SERVICE_TIMEOUT ,应该如何解决? A: 这个是因为您请求我们服务器到返回结果的时间,超过了上限。请检查网络环境相关的原因,并协助提供日志。
Q: 我运行你们的 SDK 报 16 号错误: SESSION_INVALID ,应该如何解决? A: 这个需要检查详细的代码调用过程,调用每个能力核心接口时,都是需要传入 sessionid 的,如果在 sessionstart 的时候,已经发生了错误,或者使用的id,并不是 sessionstart 时候创建的,就会返回此错误,请联系技术支持排查。
Q: 我运行你们的 SDK 报 0 号错误: ERROR NONE,应该如何解决? A: SDK 报 0 号错误, ERROR NONE,代表执行成功,请您继续后续的集成。