#include "face.h" #include #include #include #include "THFaceImage_i.h" #include "THFeature_i.h" #include "THFaceProperty_i.h" #include "THFaceTracking_i.h" #include "csdk_struct.h" namespace csdk_wrap{ sdkface::sdkface() :fpos_(NULL) ,featLen_(0) ,feat_(NULL) ,finfo_(NULL) {} sdkface::~sdkface(){ for(auto &i : dtors_){ i(); } if (fpos_) free(fpos_); if (feat_) free(feat_); if (finfo_) free(finfo_); } int sdkface::init_face_detector(const int tm, const int gi, const int minFaces, const int rollAngle){ int ret = 0; if (gi < 0) { THFI_Param *param = new THFI_Param[tm]; ret = THFI_Create(tm, param); delete[] param; } else { THFI_Param_Ex *param = new THFI_Param_Ex[tm]; THFI_Param detParam; detParam.nMinFaceSize = minFaces; detParam.nRollAngle = rollAngle; for (int i = 0; i < tm; i++) { param[i].tp = detParam; param[i].nDeviceID = gi; } ret = THFI_Create_Ex(tm, param); delete[] param; } if(ret != tm){ printf("create face detector failed!\n"); }else{ dtors_.emplace_back([]{THFI_Release();}); } return ret; } static const int maxFacePos = 30; int sdkface::face_detect(const cIMAGE *img, const int chan, void **fpos, int *fcnt){ if(chan < 0 || !img || !img->data || img->width <= 0 || img->height <= 0){ return -1; } if (fpos_ == NULL){ fpos_ = (cFacePos*)malloc(maxFacePos * sizeof(cFacePos)); } // ::THFI_FacePos facesPos[maxFacePos]; int faceNum = THFI_DetectFace(chan, (BYTE*)(img->data), 24, img->width, img->height, (::THFI_FacePos*)fpos_, maxFacePos); if (faceNum > 0) { // memcpy(fpos_, facesPos, sizeof(THFI_FacePos) * faceNum); *fcnt = faceNum; *fpos = fpos_; } return faceNum; } /////////////////////////////////////////////////// int sdkface::init_face_extractor(const int tm, const int gi){ int ret = 0; if (gi < 0) { ret = EF_Init(tm); } else { EF_Param *param = new EF_Param[tm]; for (int i = 0; i < tm; i++) { param[i].nDeviceID = gi; } ret = EF_Init_Ex(tm, param); delete[] param; } if(ret != tm){ printf("create face extractor failed!\n");; }else{ dtors_.emplace_back([]{EF_Release();}); } return ret; } int sdkface::face_extract_feature(const cFacePos &pos, const cIMAGE *img, const int chan, void **feat, int *featLen){ if(chan < 0 || !img || !img->data || img->width <= 0 || img->height <= 0){ printf("face extract error, image or pos null\n"); return -1; } *featLen = EF_Size(); if (featLen_ < *featLen){ free(feat_); feat_ = (unsigned char*)malloc(*featLen); featLen_ = *featLen; } auto ret = EF_Extract(chan, (BYTE*)(img->data), img->width, img->height, 3, (THFI_FacePos*)(&pos), feat_); if(ret != 1){ printf("face extract error %d\n", ret); return ret; } *feat = feat_; return *featLen; } float sdkface::face_compare(unsigned char *feat1, unsigned char *feat2){ if (!feat1 || !feat2){ return 0.0f; } return EF_Compare(feat1, feat2); } //////////////////////////////////////////// int sdkface::init_face_property(const int tm){ auto ret = THFP_Create(tm); if(ret != tm){ printf("create face property error\n"); }else{ dtors_.emplace_back([]{THFP_Release();}); } return ret; } cThftResult sdkface::face_property(const cFacePos &pos, const cIMAGE *img, const int chan){ cThftResult result; result.gender = result.age = result.race = -1; auto ret = THFP_Execute_V2(chan, (BYTE*)(img->data), img->width, img->height, (THFI_FacePos*)(&pos), (THFP_Result_V2*)(&result)); if(ret == 0){ // printf("property face gender %s, age %d, race %s, beauty level %d, smile_level %d\n", // result.gender ?"male":"female", // result.age, // result.race==2?"yello":"other", // result.beauty_level, result.smile_level); } return result; } ///////////////////////////////////////////////////// static THFT_Param param; int sdkface::init_face_tracker(const int tm, const int gi,const int w, const int h, const int maxFaces, const int detinterval, const int sampleSize){ param.nDeviceID = gi; param.nImageWidth = w; param.nImageHeight = h; param.nMaxFaceNum = maxFaces; param.nSampleSize = sampleSize > 0 ? sampleSize : w/2; param.nDetectionIntervalFrame = detinterval; printf("threads %d gi: %d size: %dx%d maxface: %d, sample: %d, interval: %d\n", tm, gi, w, h, maxFaces, sampleSize, detinterval); auto nNum = THFT_Create(tm, ¶m); if(nNum != tm){ printf("create face detector failed!\n"); }else{ dtors_.emplace_back([]{THFT_Release();}); } return nNum; } int sdkface::face_track(const cIMAGE *img, const int chan, void **fInfo, int *fcnt){ if (!finfo_){ finfo_ = (cFaceInfo*)malloc(param.nMaxFaceNum * sizeof(cFaceInfo)); } *fcnt = 0; auto nNum = THFT_FaceTracking(chan, img->data, (THFT_FaceInfo*)finfo_); if (nNum > 0){ *fcnt = nNum; *fInfo = finfo_; }else{ *fInfo = NULL; } return nNum; } //THFACETRACKING_API int THFT_Reset(short nChannelID, THFT_Param* pParam); int sdkface::face_track_resize(const int chan, const int w, const int h){ THFT_Param tmpParam; tmpParam.nDeviceID = param.nDeviceID; tmpParam.nImageWidth = w; tmpParam.nImageHeight = h; tmpParam.nMaxFaceNum = param.nMaxFaceNum; tmpParam.nSampleSize = param.nSampleSize; tmpParam.nDetectionIntervalFrame = param.nDetectionIntervalFrame; printf("chan %d size: %dx%d", chan, w, h); auto flag = THFT_Reset(chan, &tmpParam); return flag; } }