【名 称】:人脸识别5.3算法开发文档
【分 类】: 人脸识别算法
【外形尺寸】:
13312809492 | 13312803641 | 18680266076
19925765051 | 13312804928 | 13312805572
Android 平台提供了两个 Demo:
一个 NDK 开发,目录为“Demo_NDK”,使用 C++编写,直接用 NDK 编译,将编译好的可执行程序连同 so 库,模型文件一起拷贝到手机中即可运行。
该 demo 包含四个功能:人脸检测,人脸质量,人脸比对,人脸识别。demo如下
#include <vector>
#include <time.h>
#include <fstream>
#include "iostream"
#include "string.h"
#include "CWFaceDetection.h"
#include "CWFaceRecognition.h"
#include "CWFaceVersion.h"
#include "CWFaceAttribute.h"
#include "CWFaceNisLiveness.h"
#ifdef WIN32
#include "io.h"
#else
#include <unistd.h>
#endif // WIN32
// 授权licence
#define CW_LICENCE ""
#define MAX_NUM_FACES 20 //最多检测的人脸数
using namespace std;
// 功能:将一个全路径名分解为路径和文件名
bool DivPathAndFileName(const string &sAllName, string &sPath, string &sFileName)
{
int iPos = sAllName.find_last_of('\\');
if (-1 == iPos)
{
iPos = sAllName.find_last_of('/');
if (-1 == iPos)
{
sPath = ".";
sFileName = sAllName;
return true;
}
}
sPath = sAllName.substr(0, iPos);
sFileName = sAllName.substr(iPos + 1, sAllName.length() - iPos - 1);
return true;
}
// 功能:提示用户输入图片路径,并获得文件夹路径
bool GetImageAndPath(string &sPathPic, string &sPathFolder)
{
char picPath[260] = {0};
while (true)
{
cout<<"Please Input Pic Path: ";
cin>>picPath;
#ifdef WIN32
if (-1 == _access(picPath, 0))
{
cout<<"Pic Not Found"<<endl;
continue;
}
#else
if (-1 == access(picPath, 0))
{
cout<<"Pic Not Found"<<endl;
continue;
}
#endif
break;
}
sPathPic = picPath;
string sFileName;
return DivPathAndFileName(sPathPic, sPathFolder, sFileName);
}
int GetFeatureFromPath(void* pDetHandle, void* pRecogHandle, const string &sImagePath, void* pFeatueData)
{
// 给图像结构体赋值
std::ifstream ifs(sImagePath.c_str(), std::ios::binary);
ifs.seekg(0, std::ios::end);
int iImgLen = ifs.tellg();
ifs.seekg(0, std::ios::beg);
char *szImg = new char[iImgLen];
ifs.read(szImg, iImgLen);
cw_img_t srcImg;
srcImg.frameId = 0;
srcImg.data = szImg;
srcImg.dataLen = iImgLen;
srcImg.angle = CW_IMAGE_ANGLE_0;
srcImg.format = CW_IMAGE_BINARY;
srcImg.mirror = CW_IMAGE_MIRROR_NONE;
cw_face_res_t faceBuffers[MAX_NUM_FACES];
int iFaceNum = 0;
// 人脸检测,获取对齐人脸
cw_errcode_t errCode = cwFaceDetection(pDetHandle, &srcImg, faceBuffers, MAX_NUM_FACES, &iFaceNum, CW_OP_DET | CW_OP_ALIGN);
delete[] szImg;
if (errCode != CW_SDKLIT_OK)
{
cout<<"Face detect Error, Code: " << errCode << endl;
return -1;
}
if (iFaceNum < 1)
{
cout<<"No Face Detected" << endl;
return -1;
}
if (faceBuffers[0].detected != 1)
{
cout<<"Low Face Quality" << endl;
return -1;
}
// 提取检测到的第*张人脸的特征
errCode = cwGetFaceFeature(pRecogHandle, &faceBuffers[0].faceAligned, pFeatueData);
if (CW_SDKLIT_OK != errCode)
{
cout<<"Get Feature Error: " << errCode << endl;
return -1;
}
return 0;
}
int GetFaceInfoByImgData(void *pDetHandle, char *pImgData, int iImgLen, cw_face_res_t* pFaceBuffer)
{
if (pImgData == NULL || iImgLen < 1)
{
return 0;
}
cw_img_t srcImg;
srcImg.frameId = 0;
srcImg.data = pImgData;
srcImg.dataLen = iImgLen;
srcImg.angle = CW_IMAGE_ANGLE_0;
srcImg.mirror = CW_IMAGE_MIRROR_NONE;
srcImg.format = CW_IMAGE_BINARY;
int iFaceNum = 0;
// 检测,关键点与质量分
cw_errcode_t errCode = cwFaceDetection(pDetHandle, &srcImg, pFaceBuffer, MAX_NUM_FACES, &iFaceNum, CW_OP_DET |CW_OP_KEYPT| CW_OP_QUALITY);
if (errCode != CW_SDKLIT_OK)
{
cout<<"Face detect Error, Code: " << errCode << endl;
return 0;
}
if (iFaceNum < 1)
{
cout<<"No Face Detected" << endl;
return 0;
}
return iFaceNum;
}
void* CreateDetHandle(cw_errcode_t* errCode)
{
// 32位和64位检测模型不能共用,64位用_configs_frontend.xml,非64位用_configs_frontend_x86_arm.xml
#ifdef DEMO_X64
std::string sModelXmlPath = "../../CWModels/_configs_frontend.xml";
#else
std::string sModelXmlPath = "../../CWModels/_configs_frontend_x86_arm.xml";
#endif // DEMO_X64
void *pDet = cwCreateDetHandle(errCode, sModelXmlPath.c_str(), CW_LICENCE);
if (pDet)
{
cw_det_param_t param;
cwGetFaceParam(pDet, ¶m);
param.minSize = 48;
param.maxSize = 600;
param.pConfigFile = sModelXmlPath.c_str(); // 设置接口功能参数
cwSetFaceParam(pDet, ¶m);
}
return pDet;
}
void* CreateRecogHandle(cw_errcode_t* errCode)
{
#ifdef ANDROID
std::string sModelPath = "../../CWModels/CWR_Config_1_1.xml";
#else
std::string sModelPath = "../../CWModels/CWR_Config_1_1.xml";
#endif
return cwCreateRecogHandle(errCode, sModelPath.c_str(), CW_LICENCE, CW_FEATURE_EXTRACT);
}
void* CreateAttributeHandle(cw_errcode_t* errcode, const char *sModelPath)
{
//加载的模型
return cwCreateAttributeHandle (errcode,sModelPath,CW_LICENCE);
}
// 创建红外活体句柄 ../../CWModels/hd171019.bin
void* CreateNisLivenessHandle(cw_nirliveness_err_t* errCode)
{
return cwCreateNirLivenessHandle(errCode, "../../CWModels/nirLiveness_model_20181102_pc.bin","../../CWModels/hd171019.bin","../../CWModels/matrix_para640x480.xml",
"./log", 0.35, CW_LICENCE);
}
// 安装授权,如果授权成功,不要再次调用
void InstallKey(const char* sAppKey, const char* sAppSecret, const char* sProductId)
{
cw_errcode_t errCode = cwInstallLicence(sAppKey, sAppSecret, sProductId);
cout << "cwInstallLicence: " << errCode << endl;
}
// 安卓获取授权码
void GetLicense(const char* sAppKey, const char* sAppSecret, const char* sProductId)
{
char szLicense[600] = {0};
int iUseLen = 0;
cw_errcode_t errCode = cwGetLicence(sAppKey, sAppSecret, sProductId, szLicense, 600, &iUseLen);
cout << "cwGetLicence: " << errCode << endl;
cout << "license: " << szLicense << endl;
}
int RetPause(int iRet, void *pDetHandle = NULL, void *pRecogHandle = NULL, void *pAgeHandle = NULL,void *pGenderHandle = NULL,void *pRaceHandle = NULL, void *pNisLiveHandle = NULL)
{
// 程序退出时销毁句柄
if (pDetHandle != NULL)
{
cwReleaseDetHandle(pDetHandle);
pDetHandle = NULL;
}
if (pRecogHandle != NULL)
{
cwReleaseRecogHandle(pRecogHandle);
pRecogHandle = NULL;
}
if (pAgeHandle!=NULL)
{
cwReleaseAttributeHandle (pAgeHandle);
pAgeHandle=NULL;
}
if (pGenderHandle!=NULL)
{
cwReleaseAttributeHandle (pGenderHandle);
pGenderHandle=NULL;
}
if (pRaceHandle!=NULL)
{
cwReleaseAttributeHandle (pRaceHandle);
pRaceHandle=NULL;
}
if (pNisLiveHandle != NULL)
{
cwReleaseNirLivenessHandle(pNisLiveHandle);
pNisLiveHandle = NULL;
}
#ifdef WIN32
system("pause");
#endif // WIN32
return iRet;
}
int DemoDetect(); // [6/29/2016 Lit]:人脸检测使用示例
int DemoQuality(); // [9/13/2016 Lit]:人脸质量使用示例
int DemoVerify(); // [6/29/2016 Lit]:人脸比对使用示例(1:1)
int DemoVerify2(); // [8/29/2018 Lit]:人脸比对使用示例,直接调用比对接口
int DemoRecog(); // [6/29/2016 Lit]:人脸识别使用示例(1:N)
int DemoAttribute(); // [16/10/2018 Lit]: 人脸属性使用示例
int DemoNisLiveness(); // [6/11/2018 Lit]: 红外活体使用示例
int main()
{
char szVer[100] = {0};
cwGetSDKVersion(szVer, 100);
cout << "SDK Version: " << szVer;
cout << endl << endl;
int iType = 0;
cout << "demo type:" << endl;
cout << "1 Face Detect" << endl;
cout << "2 Face Quality" << endl;
cout << "3 Face Verify" << endl;
cout << "4 Face Verify2" << endl;
cout << "5 Face Recognition" << endl;
cout << "6 Face Attribute" <<endl;
cout << "7 Face NisLiveness" << endl;
cout << "8 Exit" << endl << endl;
cout << "Please Input Type:";
cin >> iType;
switch (iType)
{
case 1:
return DemoDetect();
case 2:
return DemoQuality();
case 3:
return DemoVerify();
case 4:
return DemoVerify2();
case 5:
return DemoRecog();
case 6:
return DemoAttribute();
case 7:
return DemoNisLiveness();
case 8:
return 0;
default:
cout << "type error" << endl << endl;
cin.clear();
cin.sync(); // 清空缓冲区
main();
return 0;
}
}
// [6/29/2016 Lit]:人脸检测使用示例
int DemoDetect()
{
// 程序启动时创建句柄
cw_errcode_t errCode = CW_SDKLIT_OK;
void *pDetHandle = CreateDetHandle(&errCode);
if (NULL == pDetHandle)
{
std::cout<<"Create detector Error, Code: " << errCode << endl;
return RetPause(-1);
}
cout << endl;
string sPath, sPathPic;
if (!GetImageAndPath(sPathPic, sPath))
{
return RetPause(-1, pDetHandle);
}
std::ifstream ifs(sPathPic.c_str(), std::ios::binary);
ifs.seekg(0, std::ios::end);
int iImgLen = ifs.tellg();
ifs.seekg(0, std::ios::beg);
char *szImg = new char[iImgLen];
ifs.read(szImg, iImgLen);
// 给图像结构体赋值
cw_img_t srcImg;
srcImg.frameId = 0;
srcImg.data = szImg;
srcImg.dataLen = iImgLen;
srcImg.angle = CW_IMAGE_ANGLE_0;
srcImg.format = CW_IMAGE_BINARY;
cw_face_res_t faceBuffers[MAX_NUM_FACES];
int iFaceNum = 0;
// 只做人脸检测
cw_errcode_t errDet = cwFaceDetection(pDetHandle, &srcImg, faceBuffers, MAX_NUM_FACES, &iFaceNum, CW_OP_DET);
delete[] szImg;
if (errDet != CW_SDKLIT_OK)
{
cout<<"Face detect Error, Code: " << errDet << endl;
return RetPause(-1, pDetHandle);
}
if (iFaceNum < 1)
{
cout<<"No Face Detected" << endl;
return RetPause(-1, pDetHandle);
}
cout << "Face Number: " << iFaceNum << endl;
for (int i = 0; i < iFaceNum; i++)
{
cout << "Face " << i + 1 << ": Pos: " << faceBuffers[i].faceRect.x << "," << faceBuffers[i].faceRect.y << "," << faceBuffers[i].faceRect.width << ","
<< faceBuffers[i].faceRect.height << endl;
}
cout << "Face Detect Completely" << endl;
return RetPause(0, pDetHandle);
}
// [9/13/2016 Lit]:人脸质量使用示例
int DemoQuality()
{
// 程序启动时创建句柄
cw_errcode_t errCode = CW_SDKLIT_OK;
void *pDetHandle = CreateDetHandle(&errCode);
if (NULL == pDetHandle)
{
std::cout<<"Create detector Error, Code: " << errCode << endl;
return RetPause(-1);
}
cout << endl;
string sPath, sPathPic;
if (!GetImageAndPath(sPathPic, sPath))
{
return RetPause(-1, pDetHandle);
}
std::ifstream ifs(sPathPic.c_str(), std::ios::binary);
ifs.seekg(0, std::ios::end);
int iImgLen = ifs.tellg();
ifs.seekg(0, std::ios::beg);
char *szImg = new char[iImgLen];
ifs.read(szImg, iImgLen);
// 给图像结构体赋值
cw_img_t srcImg;
srcImg.frameId = 0;
srcImg.data = szImg;
srcImg.dataLen = iImgLen;
srcImg.angle = CW_IMAGE_ANGLE_0;
srcImg.format = CW_IMAGE_BINARY;
cw_face_res_t faceBuffers[MAX_NUM_FACES];
int iFaceNum = 0;
// 人脸检测和人脸质量操作 CW_OP_DET | CW_OP_QUALITY
cw_errcode_t errDet = cwFaceDetection(pDetHandle, &srcImg, faceBuffers, MAX_NUM_FACES, &iFaceNum, CW_OP_DET | CW_OP_QUALITY);
delete[] szImg;
if (errDet != CW_SDKLIT_OK)
{
cout<<"Face detect Error, Code: " << errDet << endl;
return RetPause(-1, pDetHandle);
}
if (iFaceNum < 1)
{
cout<<"No Face Detected" << endl;
return RetPause(-1, pDetHandle);
}
cout << "Face Number: " << iFaceNum << endl;
for (int i = 0; i < iFaceNum; i++)
{
cw_quality_errcode errQuality = faceBuffers[i].quality.errcode;
if (CW_QUALITY_OK == errQuality)
{
cout << "Face " << i + 1 << ": Pos: " << faceBuffers[i].faceRect.x << "," << faceBuffers[i].faceRect.y << "," << faceBuffers[i].faceRect.width << ","
<< faceBuffers[i].faceRect.height << " Quality Score: " << faceBuffers[i].quality.scores[0] << endl;
}
else
{
cout << "Face " << i + 1 << ": Pos: " << faceBuffers[i].faceRect.x << "," << faceBuffers[i].faceRect.y << "," << faceBuffers[i].faceRect.width << ","
<< faceBuffers[i].faceRect.height << " Quality Err: " << errQuality << endl;
}
}
cout << "Face Quality Completely" << endl;
return RetPause(0, pDetHandle);
}
// [6/29/2016 Lit]:人脸比对使用示例(1:1)
int DemoVerify()
{
cw_errcode_t errCode = CW_SDKLIT_OK;
void *pDetHandle = CreateDetHandle(&errCode);
if (NULL == pDetHandle)
{
std::cout<<"Create detector Error, Code: " << errCode << std::endl;
return RetPause(-1);
}
void *pRecogHandle = CreateRecogHandle(&errCode);
if (NULL == pRecogHandle || CW_SDKLIT_OK != errCode)
{
std::cout<<"Create Recog Handle Error, Code: " << errCode << std::endl;
return RetPause(-1, pDetHandle);
}
cout << endl;
string sPath, sPathPic1;
if (!GetImageAndPath(sPathPic1, sPath))
{
return RetPause(-1, pDetHandle);
}
string sPathPic2;
if (!GetImageAndPath(sPathPic2, sPath))
{
return RetPause(-1, pDetHandle);
}
int iFeaLen = cwGetFeatureLength(pRecogHandle);
char *pFeaFiled = new char[iFeaLen];
if (0 != GetFeatureFromPath(pDetHandle, pRecogHandle, sPathPic1, pFeaFiled))
{
cout << "Pic1 Failed\n";
delete[] pFeaFiled;
return RetPause(-1, pDetHandle, pRecogHandle,NULL);
}
char *pFeaProbe = new char[iFeaLen];
if (0 != GetFeatureFromPath(pDetHandle, pRecogHandle, sPathPic2, pFeaProbe))
{
cout << "Pic2 Failed\n";
delete[] pFeaFiled;
delete[] pFeaProbe;
return RetPause(-1, pDetHandle, pRecogHandle,NULL);
}
float scores[1] = {0.0};
errCode = cwComputeMatchScore(pRecogHandle, pFeaProbe, pFeaFiled, 1, scores);
delete[] pFeaFiled;
delete[] pFeaProbe;
if (errCode != CW_SDKLIT_OK)
{
cout << "Recog Error: " << errCode;
return RetPause(-1, pDetHandle, pRecogHandle,NULL);
}
cout << "Verify Score: " << scores[0] << endl;
cout << "Face Verify Completely" << endl;
return RetPause(0, pDetHandle, pRecogHandle,NULL);
}
// 直接调用比对接口
int DemoVerify2()
{
cw_errcode_t errCode = CW_SDKLIT_OK;
void *pDetHandle = CreateDetHandle(&errCode);
if (NULL == pDetHandle)
{
std::cout<<"Create detector Error, Code: " << errCode << std::endl;
return RetPause(-1);
}
void *pRecogHandle = CreateRecogHandle(&errCode);
if (NULL == pRecogHandle || CW_SDKLIT_OK != errCode)
{
std::cout<<"Create Recog Handle Error, Code: " << errCode << std::endl;
return RetPause(-1, pDetHandle);
}
cout << endl;
string sPath, sPathPic1;
if (!GetImageAndPath(sPathPic1, sPath))
{
return RetPause(-1, pDetHandle);
}
string sPathPic2;
if (!GetImageAndPath(sPathPic2, sPath))
{
return RetPause(-1, pDetHandle);
}
std::ifstream ifs(sPathPic1.c_str(), std::ios::binary);
ifs.seekg(0, std::ios::end);
int iImgLen = ifs.tellg();
ifs.seekg(0, std::ios::beg);
char *szImg = new char[iImgLen];
ifs.read(szImg, iImgLen);
cw_img_t srcImg;
srcImg.frameId = 0;
srcImg.data = szImg;
srcImg.dataLen = iImgLen;
srcImg.angle = CW_IMAGE_ANGLE_0;
srcImg.format = CW_IMAGE_BINARY;
srcImg.mirror = CW_IMAGE_MIRROR_NONE;
std::ifstream ifs2(sPathPic2.c_str(), std::ios::binary);
ifs2.seekg(0, std::ios::end);
int iImgLen2 = ifs2.tellg();
ifs2.seekg(0, std::ios::beg);
char *szImg2 = new char[iImgLen2];
ifs2.read(szImg2, iImgLen2);
cw_img_t srcImg2;
srcImg2.frameId = 0;
srcImg2.data = szImg2;
srcImg2.dataLen = iImgLen2;
srcImg2.angle = CW_IMAGE_ANGLE_0;
srcImg2.format = CW_IMAGE_BINARY;
srcImg2.mirror = CW_IMAGE_MIRROR_NONE;
float fScore = 0.0f;
errCode = cwVerifyImageData(pDetHandle, pRecogHandle, &srcImg, &srcImg2, &fScore);
delete[] szImg;
delete[] szImg2;
if (errCode != CW_SDKLIT_OK)
{
cout << "Verify Error: " << errCode;
return RetPause(-1, pDetHandle, pRecogHandle);
}
cout << "Verify Score: " << fScore << endl;
cout << "Face Verify Completely" << endl;
return RetPause(0, pDetHandle, pRecogHandle);
}
// [6/29/2016 Lit]:人脸识别使用示例(1:N)
int DemoRecog()
{
cw_errcode_t errCode = CW_SDKLIT_OK;
void *pDetHandle = CreateDetHandle(&errCode);
if (NULL == pDetHandle)
{
std::cout<<"Create detector Error, Code: " << errCode << std::endl;
return RetPause(-1);
}
void *pRecogHandle = CreateRecogHandle(&errCode);
if (NULL == pRecogHandle || CW_SDKLIT_OK != errCode)
{
std::cout<<"Create Recog Handle Error, Code: " << errCode << std::endl;
return RetPause(-1, pDetHandle);
}
cout << endl;
string sPath, sPathPic1;
if (!GetImageAndPath(sPathPic1, sPath))
{
return RetPause(-1, pDetHandle);
}
string sPathPic2;
if (!GetImageAndPath(sPathPic2, sPath))
{
return RetPause(-1, pDetHandle);
}
int iFeaLen = cwGetFeatureLength(pRecogHandle);
// 底库为图片1和图片2
char *pFeaFiled = new char[iFeaLen * 2];
if (0 != GetFeatureFromPath(pDetHandle, pRecogHandle, sPathPic1, pFeaFiled))
{
cout << "Pic2 Failed\n";
delete[] pFeaFiled;
return RetPause(-1, pDetHandle, pRecogHandle);
}
if (0 != GetFeatureFromPath(pDetHandle, pRecogHandle, sPathPic2, pFeaFiled + iFeaLen))
{
cout << "Pic1 Failed\n";
delete[] pFeaFiled;
return RetPause(-1, pDetHandle, pRecogHandle);
}
// 用于检索
char *pFeaProbe = new char[iFeaLen];
if (0 != GetFeatureFromPath(pDetHandle, pRecogHandle, sPathPic2, pFeaProbe))
{
cout << "Pic2 Failed\n";
delete[] pFeaFiled;
delete[] pFeaProbe;
return RetPause(-1, pDetHandle, pRecogHandle);
}
// 识别图片2,底库为图片1和图片2
float scores[2] = {0.0};
errCode = cwComputeMatchScore(pRecogHandle, pFeaProbe, pFeaFiled, 2, scores);
delete[] pFeaFiled;
delete[] pFeaProbe;
if (errCode != CW_SDKLIT_OK)
{
cout << "Recog Error: " << errCode;
return RetPause(-1, pDetHandle, pRecogHandle);
}
cout << "Recog Score: " << endl << scores[0] << endl << scores[1] << endl;
cout << "Face Recognise Completely" << endl;
return RetPause(0, pDetHandle, pRecogHandle);
}
//[16/10/2018 Lit]: 人脸属性识别检测
int DemoAttribute()
{
cw_errcode errCode=CW_SDKLIT_OK;
void *pDetHandle = CreateDetHandle(&errCode);
if (pDetHandle == NULL)
{
cout << "Create Detector Erroe,Code: "<< errCode << endl;
return RetPause(-1);
}
const char* AgeModelPath ="../../CWModels/attribute/ageGroup/cw_age_group_config.xml";
void *pAgeHandle=CreateAttributeHandle(&errCode,AgeModelPath);
if(NULL==pAgeHandle)
{
cout<< "Create AgeAttribute Handle Error! ErrCode:"<< errCode << endl;
RetPause (-1);
}
const char* GenderModelPath ="../../CWModels/attribute/faceGender/cw_gender_config.xml";
void *pGenderHandle=CreateAttributeHandle(&errCode,GenderModelPath);
if(NULL==pGenderHandle)
{
cout<< "Create GenderAttribute Handle Error! ErrCode:"<< errCode << endl;
RetPause (-1);
}
const char* RaceModelPath ="../../CWModels/attribute/faceRace/cw_race_config.xml";
void *pRaceHandle=CreateAttributeHandle(&errCode,RaceModelPath);
if(NULL==pRaceHandle)
{
cout<< "Create RaceAttribute Handle Error! ErrCode:"<< errCode << endl;
RetPause (-1);
}
cout << endl;
string sPath, sPathPic;
if (!GetImageAndPath(sPathPic, sPath))
{
return RetPause(-1, pDetHandle, NULL);
}
std::ifstream ifs(sPathPic.c_str(), std::ios::binary);
ifs.seekg(0, std::ios::end);
int iImgLen = ifs.tellg();
ifs.seekg(0, std::ios::beg);
char *szImg = new char[iImgLen];
ifs.read(szImg, iImgLen);
// 给图像结构体赋值
cw_img_t srcImg;
srcImg.frameId = 0;
srcImg.data = szImg;
srcImg.dataLen = iImgLen;
srcImg.angle = CW_IMAGE_ANGLE_0;
srcImg.format = CW_IMAGE_BINARY;
srcImg.mirror = CW_IMAGE_MIRROR_NONE;
cw_face_res_t faceBuffers[MAX_NUM_FACES];
int iFaceNum = 0;
// 人脸检测,获取对齐人脸
errCode = cwFaceDetection(pDetHandle, &srcImg, faceBuffers, MAX_NUM_FACES, &iFaceNum, CW_OP_DET | CW_OP_ALIGN);
delete[] szImg;
if (errCode != CW_SDKLIT_OK)
{
cout << "Face detect Error, Code: " << errCode << endl;
return RetPause(-1, pDetHandle, NULL, pAgeHandle,pGenderHandle,pRaceHandle);
}
if (iFaceNum < 1)
{
cout<<"No Face Detected" << endl;
return RetPause(-1, pDetHandle, NULL, pAgeHandle,pGenderHandle,pRaceHandle);
}
int iAge = 0, iGender = 0, iRace = 0;
float fConfidence =0.0;
for (int i = 0; i < iFaceNum; i++)
{
//年龄段
errCode = cwGetAgeEval(pAgeHandle, &faceBuffers[i].faceAligned, &iAge, &fConfidence);
if (CW_SDKLIT_OK == errCode)
{
printf("Face %d AgeGroup: %d, Confidence: %.2f\n", i + 1, iAge, fConfidence);
}
else
{
printf("Face %d Age Error: %d\n", i + 1, errCode);
}
//性别
errCode = cwGetGenderEval(pGenderHandle, &faceBuffers[i].faceAligned, &iGender, &fConfidence);
if (CW_SDKLIT_OK == errCode)
{
printf("Face %d Gender: %d, Confidence: %.2f\n", i + 1, iGender, fConfidence);
}
else
{
printf("Face %d Gender Error: %d\n", i + 1, errCode);
}
//种族
errCode = cwGetRaceEval(pRaceHandle, &faceBuffers[i].faceAligned, &iRace, &fConfidence);
if (CW_SDKLIT_OK == errCode)
{
printf("Face %d Race: %d, Confidence: %.2f\n", i + 1, iRace, fConfidence);
}
else
{
printf("Face %d Race Error: %d\n", i + 1, errCode);
}
}
cout << "Face Attribute Completely" << endl;
return RetPause(0, pDetHandle, NULL, pAgeHandle,pGenderHandle,pRaceHandle);
}
// [9/4/2017 Lit]:红外活体检测Demo
int DemoNisLiveness()
{
cw_errcode_t errCode = CW_SDKLIT_OK;
void *pDetHandle = CreateDetHandle(&errCode);
if (NULL == pDetHandle)
{
std::cout<<"Create detector Error, Code: " << errCode << std::endl;
return RetPause(-1);
}
cw_nirliveness_err_t errNis = CW_NIRLIV_OK;
void *pNisLiveness = CreateNisLivenessHandle(&errNis);
if (pNisLiveness == NULL)
{
std::cout<<"Create NisLiveness Error, Code: " << errNis << std::endl;
return RetPause(-1, pDetHandle);
}
std::cout << endl;
string sPath, sPathPicVis; // 可见光照片
if (!GetImageAndPath(sPathPicVis, sPath))
{
return RetPause(-1, pDetHandle,NULL, NULL, NULL,NULL, pNisLiveness);
}
string sPathPicNir; // 红外照片
if (!GetImageAndPath(sPathPicNir, sPath))
{
return RetPause(-1, pDetHandle,NULL, NULL, NULL,NULL, pNisLiveness);
}
// 可见光图片
std::ifstream ifs(sPathPicVis.c_str(), std::ios::binary);
ifs.seekg(0, std::ios::end);
int iImgLen = ifs.tellg();
if (iImgLen < 1)
{
std::cout << "可见光图片错误";
return RetPause(-1, pDetHandle,NULL, NULL, NULL,NULL, pNisLiveness);
}
ifs.seekg(0, std::ios::beg);
char *szImg = new char[iImgLen];
ifs.read(szImg, iImgLen);
// 红外图片
std::ifstream ifsNir(sPathPicNir.c_str(), std::ios::binary);
ifsNir.seekg(0, std::ios::end);
int iImgLenNir = ifsNir.tellg();
if (iImgLenNir < 1)
{
delete[] szImg;
std::cout << "红外图片错误";
return RetPause(-1, pDetHandle,NULL, NULL, NULL,NULL, pNisLiveness);
}
ifsNir.seekg(0, std::ios::beg);
char *szImgNir = new char[iImgLenNir];
ifsNir.read(szImgNir, iImgLenNir);
#if 0
#else
// 采用原始红外活体接口
cw_face_res_t *faceBuffersVis = new cw_face_res_t[MAX_NUM_FACES];
int iFaceNumVis = GetFaceInfoByImgData(pDetHandle, szImg, iImgLen, faceBuffersVis);
if (iFaceNumVis < 1)
{
cout << "可见光检测失败";
delete[] szImg;
delete[] szImgNir;
delete[] faceBuffersVis;
return RetPause(-1, pDetHandle,NULL, NULL, NULL,NULL, pNisLiveness);
}
cw_face_res_t *faceBuffersNis = new cw_face_res_t[MAX_NUM_FACES];
int iFaceNumNis = GetFaceInfoByImgData(pDetHandle, szImgNir, iImgLenNir, faceBuffersNis);
if (iFaceNumNis < 1)
{
cout << "红外检测失败";
delete[] szImg;
delete[] faceBuffersVis;
delete[] szImgNir;
delete[] faceBuffersNis;
return RetPause(-1, pDetHandle,NULL, NULL, NULL,NULL, pNisLiveness);
}
cout << endl;
// 取红外和可见光图片中的第*个人脸做活体
cw_nirliv_detinfo_t detInfo;
detInfo.nLandmarks = faceBuffersVis[0].keypt.nkeypt; //关键点个数
// 红外图片数据
detInfo.pNirImg = new cw_nirliv_img_t();
detInfo.pNirImg->data = szImgNir;
detInfo.pNirImg->dataLen = iImgLenNir;
detInfo.pNirImg->format = CW_IMAGE_BINARY; // 这里读取后都是3通道的bgr图
// 可见光图片数据
detInfo.pVisImg = new cw_nirliv_img_t();
detInfo.pVisImg->data = szImg;
detInfo.pVisImg->dataLen = iImgLen;
detInfo.pVisImg->format = CW_IMAGE_BINARY; // 这里读取后都是3通道的bgr图
detInfo.pVisInfo = new cw_nirliv_face_param_t(); // 可见光人脸信息
detInfo.pVisInfo->pKeypoints = faceBuffersVis[0].keypt.points;
detInfo.pVisInfo->fKeyScore = faceBuffersVis[0].keypt.keyptScore; // 质量分
detInfo.pVisInfo->fSkinScore = faceBuffersVis[0].quality.scores[6]; // 肤色分
detInfo.pNirInfo = new cw_nirliv_face_param_t(); // 红外人脸信息
detInfo.pNirInfo->pKeypoints = faceBuffersNis[0].keypt.points;
detInfo.pNirInfo->fKeyScore = faceBuffersNis[0].keypt.keyptScore; // 质量分
detInfo.pNirInfo->fSkinScore = faceBuffersNis[0].quality.scores[6]; // 肤色分
cw_nirliv_res_t nisLivenessRes;
errNis = cwFaceNirLivenessDet(pNisLiveness, &detInfo, &nisLivenessRes);
if (errNis == CW_NIRLIV_OK)
{
cout << "state: " << nisLivenessRes.livRst << " score: " << nisLivenessRes.score << endl;
}
else
{
cout << "Face NisLiveness Error: " << errNis << endl;
}
delete[] szImg;
delete[] szImgNir;
delete[] faceBuffersVis;
delete[] faceBuffersNis;
delete detInfo.pNirImg;
delete detInfo.pVisImg;
delete detInfo.pVisInfo;
delete detInfo.pNirInfo;
cout << "\nFace NisLiveness Completely" << endl;
return RetPause(0, pDetHandle, NULL, NULL, pNisLiveness);
#endif
}
400电话:400-636-7012
联系电话:020-29820271
手机号码:18680266076
手机号码:13312809492
手机号码:13312803641
手机号码:13312804928
手机号码:13312805572
手机号码:13380056105
客服QQ:2622477828
客服QQ:1955944208
客服QQ:1454850974
客服QQ:2378428385
客服QQ:908404718
客服QQ:2448728978
Email:2622477828@qq.com
地址:广州市天河区岗顶龙口西路102号