#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 "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"<> 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 }