From d3b3f6b835cb7fcbb3712f876e84c8ed625170a2 Mon Sep 17 00:00:00 2001 From: zhangmeng <775834166@qq.com> Date: 星期三, 15 一月 2020 11:30:08 +0800 Subject: [PATCH] Merge branch 'cuda-8.0' of ssh://192.168.5.5:29418/libgowrapper/face into cuda-8.0 --- csrc/face.h | 51 ++++ /dev/null | 20 - csrc/face.cpp | 225 ++++++++++++++++++++ csrc/struct.h | 23 - cface.cpp | 137 ++++++------ cface.h | 64 ++--- goface.go | 103 +++++--- 7 files changed, 446 insertions(+), 177 deletions(-) diff --git a/cface.cpp b/cface.cpp index fc20813..99ab41c 100644 --- a/cface.cpp +++ b/cface.cpp @@ -1,85 +1,86 @@ #ifdef __cplusplus extern "C"{ #endif - + +#include <stdio.h> #include "cface.h" - + #ifdef __cplusplus } #endif - -#include "csrc/all.hpp" - -using namespace csdk_wrap; - -static VecFunc dtors_; - -int c_api_face_detector_init(const int tm, const int gi, const int minFaces, const int rollAngle){ - return init_face_detector(tm, gi, minFaces, rollAngle, dtors_); + +#include "csrc/face.h" + +#include "csrc/struct.h" + +#include "csrc/face.cpp" + +using namespace cppface; + +void *create_sdkface(){ + return new sdkface(); } - -int c_api_face_property_init(const int tm){ - return init_face_property(tm, dtors_); -} - -int c_api_face_extractor_init(const int tm, const int gi){ - return init_face_extractor(tm, gi, dtors_); -} - -int c_api_face_tracker_init(const int tm, const int gi, const int wid, const int hei, - const int maxFaces, const int detinterval, const int sampleSize){ - - return init_face_tracker(tm, gi, wid, hei, maxFaces, detinterval, sampleSize, dtors_); -} - -int c_api_face_track_resize(const int chan, const int wid, const int hei){ - return face_track_resize(chan, wid, hei); -} - -void c_api_release(){ - for(auto &i : dtors_){ - i(); + +void release(void *handle){ + if (handle){ + sdkface *s = (sdkface*)handle; + delete s; } - dtors_.clear(); } - -//////////////////////////////////////////////// - -cFacePos* c_api_face_detect(int *faceCount, uchar*data, const int w, const int h, const int channel){ - const cIMAGE img{data, w, h, 3}; - return face_detect(faceCount, &img, channel); + +int init_detector(void *handle, const int min_faces, const int roll_angles, + const int threads_max, const int gpu){ + sdkface *s = (sdkface*)handle; + return s->detector(min_faces, roll_angles, threads_max, gpu); } - -cThftResult c_api_face_property(const cFacePos* pos, uchar*data, const int w, const int h, const int channel){ - - const cIMAGE img{data, w, h, 3}; - return face_property(*pos, &img, channel); + +int init_extractor(void *handle, const int threads_max, const int gpu){ + sdkface *s = (sdkface*)handle; + return s->extractor(threads_max, gpu); } - -uchar* c_api_face_extract(int *featLen, const cFacePos* pos, uchar*data, const int w, const int h, const int channel){ - - const cIMAGE img{data, w, h, 3}; - return face_extract_feature(featLen, *pos, &img, channel); + +int init_propertizer(void *handle, const int threads_max){ + sdkface *s = (sdkface*)handle; + return s->propertizer(threads_max); } - -float c_api_face_compare(uchar *feat1, uchar *feat2){ - return face_compare(feat1, feat2); + +int init_tracker(void *handle, const int width, const int height, + const int max_faces, const int interval, const int sample_size, + const int threads_max, const int gpu){ + sdkface *s = (sdkface*)handle; + return s->tracker(width, height, max_faces, interval, sample_size, threads_max, gpu); } - -cRECT* c_api_face_track_only(int *fCount, uchar *data, const int wid, const int hei, const int channel){ - const cIMAGE img{data, wid, hei, 3}; - - return face_track_only(fCount, &img, channel); + +int detect(void *handle, const void *data, const int w, const int h, const int c, const int chan, void **fpos, int *fcnt){ + sdkface *s = (sdkface*)handle; + cIMAGE img{(unsigned char*)data, w, h, c}; + return s->detect(&img, chan, fpos, fcnt); } - -cFaceInfo* c_api_face_track_detect(int *fCount, uchar *data, const int wid, const int hei, const int channel){ - const cIMAGE img{data, wid, hei, 3}; - - return face_track_detect(fCount, &img, channel); + +int extract(void *handle, const cFacePos *pos, const void*data, const int w, const int h, const int c, const int chan, void **feat, int *featLen){ + sdkface *s = (sdkface*)handle; + cIMAGE img{(unsigned char*)data, w, h, c}; + return s->extract(*pos, &img, chan, feat, featLen); } - -cFaceInfo* c_api_face_track(int *fCount, uchar *data, const int wid, const int hei, const int channel){ - const cIMAGE img{data, wid, hei, 3}; - return face_track(fCount, &img, channel); + +float compare(void *handle, unsigned char *feat1, unsigned char *feat2){ + sdkface *s = (sdkface*)handle; + return s->compare(feat1, feat2); } - + +int propertize(void *handle, const cFacePos *pos, const void *data, const int w, const int h, const int c, const int chan, void **res){ + sdkface *s = (sdkface*)handle; + cIMAGE img{(unsigned char*)data, w, h, c}; + return s->propertize(*pos, &img, chan, res); +} + +int track(void *handle, const void *data, const int w, const int h, const int c, const int chan, void **fInfo, int *fcnt){ + sdkface *s = (sdkface*)handle; + cIMAGE img{(unsigned char*)data, w, h, c}; + return s->track(&img, chan, fInfo, fcnt); +} + +int track_resize(void *handle, const int w, const int h, const int chan){ + sdkface *s = (sdkface*)handle; + return s->track_resize(w, h, chan); +} diff --git a/cface.h b/cface.h index c1d0076..e9a3234 100644 --- a/cface.h +++ b/cface.h @@ -1,40 +1,36 @@ -#ifndef _c_wrapper_sdk_h_ -#define _c_wrapper_sdk_h_ - +#ifndef _c_face_h_ +#define _c_face_h_ + #ifdef __cplusplus extern "C"{ #endif - -#include "csdk_struct.h" - -#ifndef uchar -typedef unsigned char uchar; -#endif - -typedef void* YoloHandle; - -int c_api_face_detector_init(const int tm, const int gi, const int minFaces, const int rollAngle); -int c_api_face_property_init(const int tm); -int c_api_face_extractor_init(const int tm, const int gi); -int c_api_face_tracker_init(const int tm, const int gi, const int wid, const int hei, - const int maxFaces, const int detinterval, const int sampleSize); -int c_api_face_track_resize(const int chan, const int w, const int h); -void c_api_release(); -/////////////////////////////////////////// - -/// face api -cFacePos* c_api_face_detect(int *faceCount, uchar*data, const int w, const int h, const int channel); -cThftResult c_api_face_property(const cFacePos* pos, uchar*data, const int w, const int h, const int channel); - -uchar* c_api_face_extract(int *featLen, const cFacePos* pos, uchar*data, const int w, const int h, const int channel); -float c_api_face_compare(uchar *feat1, uchar *feat2); -cRECT* c_api_face_track_only(int *fCount, uchar *data, const int wid, const int hei, const int channel); -cFaceInfo* c_api_face_track_detect(int *fCount, uchar *data, const int wid, const int hei, const int channel); -cFaceInfo* c_api_face_track(int *fCount, uchar *data, const int wid, const int hei, const int channel); - + +#include "csrc/struct.h" + +void *create_sdkface(); +void release(void *handle); + +int init_detector(void *handle, const int min_faces, const int roll_angles, + const int threads_max, const int gpu); + +int init_extractor(void *handle, const int threads_max, const int gpu); +int init_propertizer(void *handle, const int threads_max); + +int init_tracker(void *handle, const int width, const int height, + const int max_faces, const int interval, const int sample_size, + const int threads_max, const int gpu); + +int detect(void *handle, const void *data, const int w, const int h, const int c, const int chan, void **fpos, int *fcnt); +int extract(void *handle, const cFacePos *pos, const void*data, const int w, const int h, const int c, const int chan, void **feat, int *featLen); +float compare(void *handle, unsigned char *feat1, unsigned char *feat2); + +int propertize(void *handle, const cFacePos *pos, const void *data, const int w, const int h, const int c, const int chan, void **res); + +int track(void *handle, const void *data, const int w, const int h, const int c, const int chan, void **fInfo, int *fcnt); +int track_resize(void *handle, const int w, const int h, const int chan); + #ifdef __cplusplus } #endif - - -#endif \ No newline at end of file + +#endif diff --git a/csrc/all.hpp b/csrc/all.hpp deleted file mode 100644 index bbe31af..0000000 --- a/csrc/all.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _c_wrapper_face_detector_all_hpp_ -#define _c_wrapper_face_detector_all_hpp_ - -#include "buz/face/detector.cpp" -#include "buz/face/extractor.cpp" -#include "buz/face/property.cpp" -#include "buz/face/tracker.cpp" - -#endif \ No newline at end of file diff --git a/csrc/buz/base.hpp b/csrc/buz/base.hpp deleted file mode 100644 index c8e6763..0000000 --- a/csrc/buz/base.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _c_sdk_wrap_base_class_hpp_ -#define _c_sdk_wrap_base_class_hpp_ - -#include <vector> -#include <functional> - -using VecFunc = std::vector<std::function<void()> >; - -#endif \ No newline at end of file diff --git a/csrc/buz/face/detector.cpp b/csrc/buz/face/detector.cpp deleted file mode 100644 index e191ea8..0000000 --- a/csrc/buz/face/detector.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "detector.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "THFaceImage_i.h" - -#include "csdk_struct.h" - -namespace csdk_wrap -{ - int init_face_detector(const int tm, const int gi, const int minFaces, const int rollAngle, - VecFunc &vec){ - 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{ - vec.emplace_back([]{THFI_Release();}); - } - - return ret; - } - - cFacePos* face_detect(int *faceCount, const cIMAGE *img, const int channel){ - if(channel < 0 || !img){ - return NULL; - } - cFacePos *fpos = NULL; - ::THFI_FacePos facesPos[30]; - int faceNum = THFI_DetectFace(channel, (BYTE*)(img->data), 24, img->width, img->height, facesPos, 30); - - if (faceNum > 0) { - fpos = (cFacePos*)malloc(faceNum * sizeof(cFacePos)); - *faceCount = faceNum; - memcpy(fpos, facesPos, sizeof(THFI_FacePos) * faceNum); - - }else{ - // printf ("no face detected\n"); - } - return fpos; - } - -} // csdk_wrap diff --git a/csrc/buz/face/detector.h b/csrc/buz/face/detector.h deleted file mode 100644 index 8a4497d..0000000 --- a/csrc/buz/face/detector.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _c_wrapper_face_detector_hpp_ -#define _c_wrapper_face_detector_hpp_ - -#include "../base.hpp" - - -struct _cFacePos; -struct _cIMAGE; - -namespace csdk_wrap{ - - int init_face_detector(const int tm, const int gi, const int minFaces, const int rollAngle, - VecFunc &vec); - cFacePos* face_detect(int *faceCount, const cIMAGE *img, const int channel); - -} - -#endif \ No newline at end of file diff --git a/csrc/buz/face/extractor.cpp b/csrc/buz/face/extractor.cpp deleted file mode 100644 index 594eb1f..0000000 --- a/csrc/buz/face/extractor.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "extractor.h" - -#include "THFeature_i.h" -#include "csdk_struct.h" - -namespace csdk_wrap{ - - int init_face_extractor(const int tm, const int gi, VecFunc &vec){ - 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{ - vec.emplace_back([]{EF_Release();}); - } - return ret; - } - - unsigned char* face_extract_feature(int *featLen, const cFacePos &pos, const cIMAGE *img, const int chan){ - if(!img){ - printf("face extract error, image or pos null\n"); - return NULL; - } - *featLen = EF_Size(); - unsigned char *feat = (unsigned char*)malloc(*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); - free(feat); - *featLen = 0; - return NULL; - } - return feat; - } - - float face_compare(unsigned char *feat1, unsigned char *feat2){ - if (!feat1 || !feat2){ - return 0.0f; - } - - return EF_Compare(feat1, feat2); - } - -} \ No newline at end of file diff --git a/csrc/buz/face/extractor.h b/csrc/buz/face/extractor.h deleted file mode 100644 index 31bb712..0000000 --- a/csrc/buz/face/extractor.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _c_wrapper_face_extractor_h_ -#define _c_wrapper_face_extractor_h_ - -#include "../base.hpp" - -struct _cFacePos; -struct _cIMAGE; - -namespace csdk_wrap{ - int init_face_extractor(const int tm, const int gi, VecFunc &vec); - unsigned char* face_extract_feature(int *featLen, const cFacePos &pos, const cIMAGE *img, const int chan); - float face_compare(unsigned char *feat1, unsigned char *feat2); -} -#endif \ No newline at end of file diff --git a/csrc/buz/face/property.cpp b/csrc/buz/face/property.cpp deleted file mode 100644 index 74d4774..0000000 --- a/csrc/buz/face/property.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "property.h" - -#include "THFaceProperty_i.h" -#include "csdk_struct.h" - -namespace csdk_wrap{ - - int init_face_property(const int tm, VecFunc &vec){ - auto ret = THFP_Create(tm); - if(ret != tm){ - printf("create face property error\n"); - }else{ - vec.emplace_back([]{THFP_Release();}); - } - return ret; - } - - cThftResult 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; - } - -} \ No newline at end of file diff --git a/csrc/buz/face/property.h b/csrc/buz/face/property.h deleted file mode 100644 index 39d3976..0000000 --- a/csrc/buz/face/property.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _c_wrapper_face_property_h_ -#define _c_wrapper_face_property_h_ - -#include "../base.hpp" - -struct _cThftResult; -struct _cFacePos; -struct _cIMAGE; - -namespace csdk_wrap{ - int init_face_property(const int tm, VecFunc &vec); - cThftResult face_property(const cFacePos &pos, const cIMAGE *img, const int chan); -} -#endif \ No newline at end of file diff --git a/csrc/buz/face/tracker.cpp b/csrc/buz/face/tracker.cpp deleted file mode 100644 index cb2744a..0000000 --- a/csrc/buz/face/tracker.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include "tracker.h" - -#include <stdio.h> -#include "THFaceTracking_i.h" - -namespace csdk_wrap{ - static THFT_Param param; - int init_face_tracker(const int tm, const int gi,const int w, const int h, - const int maxFaces, const int detinterval, const int sampleSize, - VecFunc &vec){ - 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{ - vec.emplace_back([]{THFT_Release();}); - } - return nNum; - } - - cRECT* face_track_only(int *faceCount, const cIMAGE *img, const int chan){ - - *faceCount = 0; - - cRECT *pFaces = (cRECT*)malloc(param.nMaxFaceNum * sizeof(cRECT)); - auto nNum = THFT_FaceOnly(chan, img->data, img->width, img->height, (tagRECT*)pFaces, param.nMaxFaceNum, param.nSampleSize); - if (nNum > 0) - { - *faceCount = nNum; - }else{ - free(pFaces); - pFaces = NULL; - } - return pFaces; - } - - cFaceInfo* face_track_detect(int *faceCount, const cIMAGE *img, const int chan){ - *faceCount = 0; - - cFaceInfo* pFaceInfos = (cFaceInfo*)malloc(param.nMaxFaceNum * sizeof(cFaceInfo)); - auto nNum = THFT_FaceDetect(chan, img->data, img->width, img->height, (THFT_FaceInfo*)pFaceInfos, param.nMaxFaceNum, param.nSampleSize); - if (nNum > 0){ - *faceCount = nNum; - }else{ - free(pFaceInfos); - pFaceInfos = NULL; - } - return pFaceInfos; - } - - cFaceInfo* face_track(int *faceCount, const cIMAGE *img, const int chan){ - *faceCount = 0; - - cFaceInfo* pFaceInfos = (cFaceInfo*)malloc(param.nMaxFaceNum * sizeof(cFaceInfo)); - auto nNum = THFT_FaceTracking(chan, img->data, (THFT_FaceInfo*)pFaceInfos); - if (nNum > 0){ - *faceCount = nNum; - }else{ - free(pFaceInfos); - pFaceInfos = NULL; - } - return pFaceInfos; - } - - //THFACETRACKING_API int THFT_Reset(short nChannelID, THFT_Param* pParam); - int 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 diff --git a/csrc/buz/face/tracker.h b/csrc/buz/face/tracker.h deleted file mode 100644 index 6498bc9..0000000 --- a/csrc/buz/face/tracker.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _c_wrapper_face_tracker_h_ -#define _c_wrapper_face_tracker_h_ - -#include "../base.hpp" - -struct _cRECT; -struct _cFaceInfo; -struct _cIMAGE; - -namespace csdk_wrap{ - int init_face_tracker(const int tm, const int gi,const int w, const int h, - const int maxFaces, const int detinterval, const int sampleSize, - VecFunc &vec); - cRECT* face_track_only(int *faceCount, const cIMAGE *img, const int chan); - cFaceInfo* face_track_detect(int *faceCount, const cIMAGE *img, const int chan); - - cFaceInfo* face_track(int *faceCount, const cIMAGE *img, const int chan); - int face_track_resize(const int chan, const int w, const int h); -} -#endif \ No newline at end of file diff --git a/csrc/face.cpp b/csrc/face.cpp new file mode 100644 index 0000000..328111a --- /dev/null +++ b/csrc/face.cpp @@ -0,0 +1,225 @@ +#include "face.h" + +#include <memory.h> + +#include "THFaceImage_i.h" +#include "THFeature_i.h" +#include "THFaceProperty_i.h" +#include "THFaceTracking_i.h" + +namespace cppface +{ + sdkface::sdkface() + :fpos_(NULL) + ,feature_size_(0) + ,feature_(NULL) + ,finfos_(NULL) + {} + + sdkface::~sdkface() + { + for (auto i : dtors_){ + i(); + } + if (fpos_) free(fpos_); + if (feature_) free(feature_); + if (finfos_) free(finfos_); + } + + int sdkface::detector(const int min_faces, const int roll_angles, + const int threads_max, const int gpu){ + int ret = 0; + if (gpu < 0) { + THFI_Param *param = new THFI_Param[threads_max]; + ret = THFI_Create(threads_max, param); + delete[] param; + } else { + THFI_Param_Ex *param = new THFI_Param_Ex[threads_max]; + THFI_Param detParam; + detParam.nMinFaceSize = min_faces; + detParam.nRollAngle = roll_angles; + for (int i = 0; i < threads_max; i++) { + param[i].tp = detParam; + param[i].nDeviceID = gpu; + } + ret = THFI_Create_Ex(threads_max, param); + delete[] param; + } + if(ret != threads_max){ + printf("create face detector failed!\n"); + }else{ + dtors_.emplace_back([]{THFI_Release();}); + } + + return ret; + } + + int sdkface::extractor(const int threads_max, const int gpu){ + int ret = 0; + if (gpu < 0) { + ret = EF_Init(threads_max); + } else { + EF_Param *param = new EF_Param[threads_max]; + for (int i = 0; i < threads_max; i++) { + param[i].nDeviceID = gpu; + } + ret = EF_Init_Ex(threads_max, param); + delete[] param; + } + if(ret != threads_max){ + printf("create face extractor failed!\n");; + }else{ + dtors_.emplace_back([]{EF_Release();}); + } + return ret; + + } + + int sdkface::propertizer(const int threads_max){ + auto ret = THFP_Create(threads_max); + if(ret != threads_max){ + printf("create face property error\n"); + }else{ + dtors_.emplace_back([]{THFP_Release();}); + } + return ret; + } + +static const int maxFacePos = 30; + int sdkface::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::extract(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 (feature_size_ < *featLen){ + free(feature_); + feature_ = (unsigned char*)malloc(*featLen); + feature_size_ = *featLen; + } + + auto ret = EF_Extract(chan, (BYTE*)(img->data), img->width, img->height, 3, + (THFI_FacePos*)(&pos), feature_); + + if(ret != 1){ + printf("face extract error %d\n", ret); + return ret; + } + + *feat = feature_; + + return *featLen; + } + + float sdkface::compare(unsigned char *feat1, unsigned char *feat2){ + if (!feat1 || !feat2){ + return 0.0f; + } + + return EF_Compare(feat1, feat2); + } + + int sdkface::propertize(const cFacePos &pos, const cIMAGE *img, const int chan, void **res){ + if(chan < 0 || !img || !img->data || img->width <= 0 || img->height <= 0){ + printf("face propertize error, image or pos null\n"); + return -1; + } + + cThftResult *thft = (cThftResult*)malloc(sizeof(cThftResult)); + + *res = NULL; + auto ret = THFP_Execute_V2(chan, (BYTE*)(img->data), img->width, img->height, + (THFI_FacePos*)(&pos), (THFP_Result_V2*)thft); + if(ret == 0){ + *res = thft; + // printf("property face gender %s, age %d, race %s, beauty level %d, smile_level %d\n", + // res.gender ?"male":"female", + // res.age, + // res.race==2?"yello":"other", + // res.beauty_level, res.smile_level); + } + return ret; + } + +static THFT_Param param; + int sdkface::tracker(const int width, const int height, + const int max_faces, const int interval, const int sample_size, + const int threads_max, const int gpu){ + + param.nDeviceID = gpu; + param.nImageWidth = width; + param.nImageHeight = height; + param.nMaxFaceNum = max_faces; + param.nSampleSize = sample_size > 0 ? sample_size : width/2; + param.nDetectionIntervalFrame = interval; + + printf("##########start threads: %d gi: %d size: %dx%d maxface: %d, sample: %d, interval: %d\n", + threads_max, gpu, width, height, max_faces, sample_size, interval); + + auto nNum = THFT_Create(threads_max, ¶m); + if(nNum != threads_max){ + printf("create face detector failed!\n"); + }else{ + dtors_.emplace_back([]{THFT_Release();}); + } + + printf("##########end threads: %d gi: %d size: %dx%d maxface: %d, sample: %d, interval: %d\n", + threads_max, gpu, width, height, max_faces, sample_size, interval); + + return nNum; + } + + int sdkface::track(const cIMAGE *img, const int chan, void **fInfo, int *fcnt){ + if (!finfos_){ + finfos_ = (cFaceInfo*)malloc(param.nMaxFaceNum * sizeof(cFaceInfo)); + } + + *fcnt = 0; + + auto nNum = THFT_FaceTracking(chan, img->data, (THFT_FaceInfo*)finfos_); + if (nNum > 0){ + *fcnt = nNum; + *fInfo = finfos_; + }else{ + *fInfo = NULL; + } + return nNum; + } + + int sdkface::track_resize(const int w, const int h, const int chan){ + 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("##########resize track\n"); + + return THFT_Reset(chan, &tmpParam); + } + +} // namespace cppface diff --git a/csrc/face.h b/csrc/face.h new file mode 100644 index 0000000..d0b5233 --- /dev/null +++ b/csrc/face.h @@ -0,0 +1,51 @@ +#ifndef _cpp_face_hpp_ +#define _cpp_face_hpp_ + +#include <vector> +#include <functional> + +using VecFunc = std::vector<std::function<void()> >; + +#include "struct.h" + +namespace cppface +{ + class sdkface{ + public: + sdkface(); + ~sdkface(); + + public: + int detector(const int min_faces, const int roll_angles, + const int threads_max, const int gpu); + int extractor(const int threads_max, const int gpu); + int propertizer(const int threads_max); + + int tracker(const int width, const int height, + const int max_faces, const int interval, const int sample_size, + const int threads_max, const int gpu); + + public: + int detect(const cIMAGE *img, const int chan, void **fpos, int *fcnt); + int extract(const cFacePos &pos, const cIMAGE *img, const int chan, void **feat, int *featLen); + float compare(unsigned char *feat1, unsigned char *feat2); + + int propertize(const cFacePos &pos, const cIMAGE *img, const int chan, void **res); + + int track(const cIMAGE *img, const int chan, void **fInfo, int *fcnt); + int track_resize(const int w, const int h, const int chan); + private: + VecFunc dtors_; + + cFacePos *fpos_; + + int feature_size_; + unsigned char *feature_; + + cFaceInfo *finfos_; + + }; +} // namespace cppface + + +#endif \ No newline at end of file diff --git a/csdk_struct.h b/csrc/struct.h similarity index 90% rename from csdk_struct.h rename to csrc/struct.h index e733027..9be7c4c 100644 --- a/csdk_struct.h +++ b/csrc/struct.h @@ -1,34 +1,32 @@ -#ifndef _c_wrapper_c_structure_h_ -#define _c_wrapper_c_structure_h_ - -#include <string.h> - +#ifndef _face_struct_h_ +#define _face_struct_h_ + typedef struct _cPOINT { int x; int y; } cPOINT; - + typedef struct _cRECT { int left; int top; int right; int bottom; } cRECT; - + typedef struct _cIMAGE{ unsigned char *data; int width; int height; int channel; } cIMAGE; - + typedef struct _cFaceAngle { int yaw; int pitch; int roll; float confidence; } cFaceAngle; - + typedef struct _cThftResult { int gender;//1-male,0-female int age;//range[0-100] @@ -36,7 +34,7 @@ int beauty_level;//range[0-100] int smile_level;//range[0-100] } cThftResult; - + typedef struct _cFacePos { cRECT rcFace; cPOINT ptLeftEye; @@ -48,7 +46,7 @@ unsigned char pFacialData[512]; } cFacePos; - + typedef struct _cFaceInfo{ cRECT rcFace; cPOINT ptLeftEye; @@ -61,6 +59,5 @@ unsigned char pFacialData[8*1024]; long nFaceID;//face tracking id } cFaceInfo; - - + #endif \ No newline at end of file diff --git a/goface.go b/goface.go index e77e23c..7891acf 100644 --- a/goface.go +++ b/goface.go @@ -22,6 +22,7 @@ // SDKFace sdk type SDKFace struct { + handle unsafe.Pointer detector bool extractor bool propertizer bool @@ -31,8 +32,13 @@ // NewSDK sdk func NewSDK(fn func(...interface{})) *SDKFace { + h := C.create_sdkface() + if h == nil { + return nil + } return &SDKFace{ + handle: h, detector: false, extractor: false, propertizer: false, @@ -43,7 +49,9 @@ // Free free func (s *SDKFace) Free() { - C.c_api_release() + if s != nil && s.handle != nil { + C.release(s.handle) + } } func (s *SDKFace) printLog(l ...interface{}) { @@ -53,14 +61,12 @@ } // Detector detector -func (s *SDKFace) Detector(minFaces, rollAngle, threadMax, gpu int) bool { +func (s *SDKFace) Detector(minFaces, rollAngles, threadMax, gpu int) bool { if s.detector { return true } - - ret := C.c_api_face_detector_init(C.int(threadMax), C.int(gpu), C.int(minFaces), C.int(rollAngle)) - + ret := C.init_detector(s.handle, C.int(minFaces), C.int(rollAngles), C.int(threadMax), C.int(gpu)) if ret <= 0 { s.printLog("->face--> CREATE Detector ERROR: ", ret) return false @@ -75,7 +81,7 @@ if s.extractor { return true } - ret := C.c_api_face_extractor_init(C.int(threadMax), C.int(gpu)) + ret := C.init_extractor(s.handle, C.int(threadMax), C.int(gpu)) if ret <= 0 { s.printLog("->face--> CREATE Extractor ERROR: ", ret) return false @@ -90,7 +96,7 @@ if s.propertizer { return true } - ret := C.c_api_face_property_init(C.int(threadMax)) + ret := C.init_propertizer(s.handle, C.int(threadMax)) if ret <= 0 { s.printLog("->face--> CREATE Propertizer ERROR: ", ret) return false @@ -103,9 +109,10 @@ func (s *SDKFace) Tracker(w, h, maxFaces, interval, sampleSize, threadMax, gpu int) bool { if s.tracker { - return true + return s.tracker } - ret := C.c_api_face_tracker_init(C.int(threadMax), C.int(gpu), C.int(w), C.int(h), C.int(maxFaces), C.int(interval), C.int(sampleSize)) + ret := C.init_tracker(s.handle, C.int(w), C.int(h), C.int(maxFaces), C.int(interval), C.int(sampleSize), C.int(threadMax), C.int(gpu)) + if ret <= 0 { s.printLog("->face--> CREATE Tracker ERROR: ", ret) return false @@ -134,32 +141,29 @@ return nil } + var cfpos unsafe.Pointer var count C.int - cfpos := C.c_api_face_detect(&count, (*C.uchar)(unsafe.Pointer(&data[0])), C.int(w), C.int(h), C.int(ch)) - if cfpos != nil { - defer C.free(unsafe.Pointer(cfpos)) - return CFacePosArrayToGoArray(unsafe.Pointer(cfpos), int(count)) + ret := C.detect(s.handle, unsafe.Pointer(&data[0]), C.int(w), C.int(h), C.int(c), C.int(ch), &cfpos, &count) + if ret > 0 { + return CFacePosArrayToGoArray(cfpos, int(count)) } - - s.printLog("->face--> Detect No One") + s.printLog("->face--> Detect No One, Ret: ", ret) return nil } // Extract extract func (s *SDKFace) Extract(fpos sdkstruct.CFacePos, data []byte, w, h, c int, ch int) []byte { - if !s.extractor { - return nil - } - var featLen C.int pos := (*C.cFacePos)(unsafe.Pointer(&fpos)) - p := C.c_api_face_extract(&featLen, pos, (*C.uchar)(unsafe.Pointer(&data[0])), C.int(w), C.int(h), C.int(ch)) - if p != nil { - defer C.free(unsafe.Pointer(p)) - return C.GoBytes(unsafe.Pointer(p), featLen) + //(void *handle, const cFacePos *pos, const void*data, const int w, const int h, const int c, const int chan, void **feat, int *featLen); + var feat unsafe.Pointer + var featLen C.int + ret := C.extract(s.handle, pos, unsafe.Pointer(&data[0]), C.int(w), C.int(h), C.int(c), C.int(ch), &feat, &featLen) + if ret > 0 { + return C.GoBytes(feat, featLen) } - s.printLog("->face--> Extract Nothing") + s.printLog("->face--> Extract Nothing, Ret: ", ret) return nil } @@ -170,20 +174,27 @@ return 0 } - res := C.c_api_face_compare((*C.uchar)(unsafe.Pointer(&feat1[0])), (*C.uchar)(unsafe.Pointer(&feat2[0]))) + res := C.compare(s.handle, (*C.uchar)(unsafe.Pointer(&feat1[0])), (*C.uchar)(unsafe.Pointer(&feat2[0]))) return float32(res) } // Propertize prop -func (s *SDKFace) Propertize(fpos sdkstruct.CFacePos, data []byte, w, h, c int, ch int) sdkstruct.CThftResult { +func (s *SDKFace) Propertize(fpos sdkstruct.CFacePos, data []byte, w, h, c int, ch int) *sdkstruct.CThftResult { if !s.propertizer { - return sdkstruct.CThftResult{Age: 0} + return nil } pos := (*C.cFacePos)(unsafe.Pointer(&fpos)) - result := C.c_api_face_property(pos, (*C.uchar)(unsafe.Pointer(&data[0])), C.int(w), C.int(h), C.int(ch)) - s.printLog("->face--> Propertize") - return *(*sdkstruct.CThftResult)(unsafe.Pointer(&result)) + + var thft unsafe.Pointer + ret := C.propertize(s.handle, pos, unsafe.Pointer(&data[0]), C.int(w), C.int(h), C.int(c), C.int(ch), &thft) + if ret == 0 { + gothft := *(*sdkstruct.CThftResult)(thft) + C.free(thft) + return &gothft + } + s.printLog("->face--> Propertize Nothing, Ret: ", ret) + return nil } // CFaceInfoArrayToGoArray convert cFaceInfo array to go @@ -207,14 +218,17 @@ //img, const int chan, void **fInfo, int *fcnt); var fCount C.int - cFinfo := C.c_api_face_track(&fCount, (*C.uchar)(unsafe.Pointer(&data[0])), C.int(w), C.int(h), C.int(ch)) - // fmt.Println("cFinfo detected:", cFinfo) - if cFinfo == nil { - return nil + var finfos unsafe.Pointer + ret := C.track(s.handle, unsafe.Pointer(&data[0]), C.int(w), C.int(h), C.int(c), C.int(ch), &finfos, &fCount) + + if ret > 0 { + faces := CFaceInfoArrayToGoArray(finfos, int(fCount)) + //if len(faces) > 0{ + // fmt.Println("faces detected:", len(faces)) + //} + return faces } - defer C.free(unsafe.Pointer(cFinfo)) - faces := CFaceInfoArrayToGoArray(unsafe.Pointer(cFinfo), int(fCount)) - return faces + return nil } // FaceInfo2FacePos info -> pos @@ -235,13 +249,18 @@ } // TrackerResize init face tracker -func (s *SDKFace) TrackerResize(w, h, ch int) int { +func (s *SDKFace) TrackerResize(w, h, ch int) bool { if !s.tracker { s.printLog("->face--> TrackerResize Failed, No Tracker Init") - return -1 + return false } - return int(C.c_api_face_track_resize(C.int(ch), C.int(w), C.int(h))) + ret := C.track_resize(s.handle, C.int(w), C.int(h), C.int(ch)) + if ret == 1 { + return true + } + s.printLog("->face--> TrackerResize Failed, Ret: ", ret, " SDK Channel: ", ch, " Size: ", w, "x", h) + return false } // Run run @@ -272,7 +291,7 @@ //杩愯sd dec := FaceInfo2FacePos(d) - p := s.Propertize(dec, data, w, h, c, dchan) + p := s.Propertize(dec, data, w, h, c, 0) feat := s.Extract(dec, data, w, h, c, dchan) /// filter rules @@ -280,7 +299,7 @@ // size := (d.RcFace.Right - d.RcFace.Left) * (d.RcFace.Bottom - d.RcFace.Top) // angle := d.FAngle // if !filter(rMsg.Msg.Tasklab.Taskid, sdkid, angle.Confidence, float32(angle.Yaw), int(size)) { - // continue + // continue // } /// filter rules -- Gitblit v1.8.0