You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
996 lines
25 KiB
996 lines
25 KiB
#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 "MjEyNDE0bm9kZXZpY2Vjd2F1dGhvcml6ZZ/l5uXj5+Xq3+bg5efm5Of+5eXj4Obg5Yjm5uvl5ubrkeXm5uvl5uai6+Xm5uvl5uTm6+Xm5uDm1efr5+vn6+er4Ofr5+vn66vn5+Xm5+Xn"
|
|
|
|
#define MAX_NUM_FACES 20 //最多检测的人脸数
|
|
|
|
using namespace std;
|
|
|
|
|
|
// [8/7/2015 Lit] 功能:将一个全路径名分解为路径和文件名
|
|
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;
|
|
}
|
|
|
|
// [8/7/2015 Lit] 功能:提示用户输入图片路径,并获得文件夹路径
|
|
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;
|
|
cout << "faceBuffers[i].quality.scores: [ ";
|
|
for(int m =0; m < (sizeof(faceBuffers[i].quality.scores) / sizeof(faceBuffers[i].quality.scores[0])); m++)
|
|
{
|
|
cout << faceBuffers[0].quality.scores[m] << " ";
|
|
}
|
|
cout << " ]\n";
|
|
}
|
|
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/CWR_Config3.0.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);
|
|
if (CW_SDKLIT_OK == errCode)
|
|
{
|
|
printf("Face %d AgeGroup: %d\n", i + 1, iAge);
|
|
}
|
|
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
|
|
|
|
// 采用封装红外活体接口
|
|
cw_img_t srcImgVis;
|
|
srcImgVis.frameId = 0;
|
|
srcImgVis.data = szImg;
|
|
srcImgVis.dataLen = iImgLen;
|
|
srcImgVis.angle = CW_IMAGE_ANGLE_0;
|
|
srcImgVis.format = CW_IMAGE_BINARY;
|
|
srcImgVis.mirror = CW_IMAGE_MIRROR_NONE;
|
|
|
|
cw_img_t srcImgNir;
|
|
srcImgNir.frameId = 0;
|
|
srcImgNir.data = szImgNir;
|
|
srcImgNir.dataLen = iImgLenNir;
|
|
srcImgNir.angle = CW_IMAGE_ANGLE_0;
|
|
srcImgNir.format = CW_IMAGE_BINARY;
|
|
srcImgNir.mirror = CW_IMAGE_MIRROR_NONE;
|
|
|
|
cw_nirliv_res_t nirLivRes;
|
|
errNis = cwFaceNirByImageData(pDetHandle, pNisLiveness, &srcImgVis, &srcImgNir, &nirLivRes);
|
|
if (errNis == CW_NIRLIV_OK)
|
|
{
|
|
std::cout << "liveness state: " << nirLivRes.livRst << ", score: " << nirLivRes.score << std::endl;
|
|
}
|
|
else
|
|
{
|
|
std::cout << "cwFaceNirByImageData Error: " << errNis << std::endl;
|
|
}
|
|
|
|
delete[] szImg;
|
|
delete[] szImgNir;
|
|
|
|
cout << "\nFace NisLiveness Completely" << endl;
|
|
|
|
return RetPause(0, pDetHandle, NULL, NULL, pNisLiveness);
|
|
|
|
#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
|
|
|
|
|
|
}
|
|
|