Android 平臺(tái)提供了兩個(gè) Demo:
一個(gè) NDK 開發(fā),目錄為“Demo_NDK”,使用 C++編寫,直接用 NDK 編譯,將編譯好的可執(zhí)行程序連同 so 庫(kù),模型文件一起拷貝到手機(jī)中即可運(yùn)行。
該 demo 包含四個(gè)功能:人臉檢測(cè),人臉質(zhì)量,人臉比對(duì),人臉識(shí)別。demo如下
#Include
#Include
#Include
#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
#Endif // WIN32
// licence
#define CW_LICENCE ""
#define MAX_NUM_FACES 20 //最多檢測(cè)的人臉數(shù)
using namespace std;
// 功能:將一個(gè)全路徑名分解為路徑和文件名
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"<
continue;
}
#Else
if (-1 == access(picPath, 0))
{
cout<<"Pic Not Found"<
continue;
}
#Endif
break;
}
sPathPic = picPath;
string sFileName;
return DivPathAndFileName(sPathPic, sPathFolder, sFileName);
}
int GetFeatureFromPath(void* pDetHandle, void* pRecogHandle, const string &sImagePath, void* pFeatueData)
{
// 給圖像結(jié)構(gòu)體賦值
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;
// 人臉檢測(cè),獲取對(duì)齊人臉
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;
}
// 提取檢測(cè)到的張人臉的特征
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;
// 檢測(cè),關(guān)鍵點(diǎn)與質(zhì)量分
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位檢測(cè)模型不能共用,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(); // 設(shè)置接口功能參數(shù)
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);
}
// 創(chuàng)建紅外活體句柄 ../../CWModels/hd171019.bin
void* CreateNisLivenessHandle(cw_nirliveness_err_t* errCode)
{
return cwCreateNirLivenessHandle(errCode, "../../CWModels/nirLiveness_model__pc.bin","../../CWModels/hd171019.bin","../../CWModels/matrix_para640x480.xml",
"./log", 0.35, CW_LICENCE);
}
// 安裝,如果成功,不要再次調(diào)用
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)
{
// 程序退出時(shí)銷毀句柄
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]:人臉檢測(cè)使用示例
int DemoQuality(); // [9/13/2016 Lit]:人臉質(zhì)量使用示例
int DemoVerify(); // [6/29/2016 Lit]:人臉比對(duì)使用示例(1:1)
int DemoVerify2(); // [8/29/2018 Lit]:人臉比對(duì)使用示例,直接調(diào)用比對(duì)接口
int DemoRecog(); // [6/29/2016 Lit]:人臉識(shí)別使用示例(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" <
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(); // 清空緩沖區(qū)
main();
return 0;
}
}
// [6/29/2016 Lit]:人臉檢測(cè)使用示例
int DemoDetect()
{
// 程序啟動(dòng)時(shí)創(chuàng)建句柄
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);
// 給圖像結(jié)構(gòu)體賦值
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;
// 只做人臉檢測(cè)
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]:人臉質(zhì)量使用示例
int DemoQuality()
{
// 程序啟動(dòng)時(shí)創(chuàng)建句柄
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);
// 給圖像結(jié)構(gòu)體賦值
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;
// 人臉檢測(cè)和人臉質(zhì)量操作 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]:人臉比對(duì)使用示例(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);
}
// 直接調(diào)用比對(duì)接口
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]:人臉識(shí)別使用示例(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);
// 底庫(kù)為圖片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);
}
// 識(shí)別圖片2,底庫(kù)為圖片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]: 人臉屬性識(shí)別檢測(cè)
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);
// 給圖像結(jié)構(gòu)體賦值
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;
// 人臉檢測(cè),獲取對(duì)齊人臉
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]:紅外活體檢測(cè)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 << "可見光圖片錯(cuò)誤";
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 << "紅外圖片錯(cuò)誤";
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 << "可見光檢測(cè)失敗";
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 << "紅外檢測(cè)失敗";
delete[] szImg;
delete[] faceBuffersVis;
delete[] szImgNir;
delete[] faceBuffersNis;
return RetPause(-1, pDetHandle,NULL, NULL, NULL,NULL, pNisLiveness);
}
cout << endl;
// 取紅外和可見光圖片中的個(gè)人臉做活體
cw_nirliv_detinfo_t detInfo;
detInfo.nLandmarks = faceBuffersVis[0].keypt.nkeypt; //關(guān)鍵點(diǎn)個(gè)數(shù)
// 紅外圖片數(shù)據(jù)
detInfo.pNirImg = new cw_nirliv_img_t();
detInfo.pNirImg->data = szImgNir;
detInfo.pNirImg->dataLen = iImgLenNir;
detInfo.pNirImg->format = CW_IMAGE_BINARY; // 這里讀取后都是3通道的bgr圖
// 可見光圖片數(shù)據(jù)
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; // 質(zhì)量分
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; // 質(zhì)量分
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
}