From b7340a34ff68f018a4aa0e7aada3b7feaabd2fe1 Mon Sep 17 00:00:00 2001 From: chenshijun <csj_sky@126.com> Date: 星期二, 22 十月 2019 14:52:49 +0800 Subject: [PATCH] 增加人脸跟踪检测的通道分辨率调整接口face_track_resize --- csrc/buz/face/face.cpp | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 219 insertions(+), 0 deletions(-) diff --git a/csrc/buz/face/face.cpp b/csrc/buz/face/face.cpp new file mode 100644 index 0000000..aa101a0 --- /dev/null +++ b/csrc/buz/face/face.cpp @@ -0,0 +1,219 @@ +#include "face.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#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; + } +} \ No newline at end of file -- Gitblit v1.8.0