From 1b388e4b0207003630c326ba1e71af8c8746070f Mon Sep 17 00:00:00 2001 From: chenshijun <csj_sky@126.com> Date: 星期二, 22 十月 2019 15:14:23 +0800 Subject: [PATCH] Merge branch 'master' of ssh://192.168.5.5:29418/valib/gosdk --- csdk.h | 2 csrc/buz/face/property.h | 14 + c2go.go | 4 csrc/buz/face/property.cpp | 34 +++ csrc/buz/face/detector.h | 18 + csrc/buz/yolo/detector.cpp | 139 ++++++++++++ csrc/buz/yolo/detector.h | 21 + csrc/buz/face/detector.cpp | 60 +++++ csrc/buz/face/tracker.h | 20 + csrc/all.hpp | 8 /dev/null | 41 --- csdk.cpp | 80 ++---- csrc/buz/face/extractor.h | 14 + csrc/buz/face/extractor.cpp | 54 ++++ gosdk.go | 35 +++ csrc/buz/face/tracker.cpp | 89 ++++++++ 16 files changed, 542 insertions(+), 91 deletions(-) diff --git a/c2go.go b/c2go.go index 9947532..d843381 100644 --- a/c2go.go +++ b/c2go.go @@ -3,6 +3,10 @@ /* #include <string.h> #include "csdk_struct.h" + +int get_facepos_size(){ + return sizeof(cFacePos); +} */ import "C" import ( diff --git a/csdk.cpp b/csdk.cpp index b1caa41..6c51871 100644 --- a/csdk.cpp +++ b/csdk.cpp @@ -12,29 +12,24 @@ using namespace csdk_wrap; -static sdkface *face = NULL; -static sdkyolo *yolo = NULL; +static VecFunc dtors_; int c_api_face_detector_init(const int tm, const int gi, const int minFaces, const int rollAngle){ - if (!face) face = new sdkface(); - return face->init_face_detector(tm, gi, minFaces, rollAngle); + return init_face_detector(tm, gi, minFaces, rollAngle, dtors_); } int c_api_face_property_init(const int tm){ - if (!face) face = new sdkface(); - return face->init_face_property(tm); + return init_face_property(tm, dtors_); } int c_api_face_extractor_init(const int tm, const int gi){ - if (!face) face = new sdkface(); - return face->init_face_extractor(tm, 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){ - if (!face) face = new sdkface(); - if (face) printf("create sdk face success\n"); - return face->init_face_tracker(tm, gi, wid, hei, maxFaces, detinterval, sampleSize); + 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){ @@ -44,76 +39,65 @@ YoloHandle c_api_yolo_init( const char *fcfg, const char *fweights, const char *fname, const int gpu_index){ - - if (!yolo) yolo = new sdkyolo; - return yolo->init_yolo(fcfg, fweights, fname, gpu_index); + + return init_yolo_detector(fcfg, fweights, fname, gpu_index, dtors_); } void c_api_release(){ - if (face) delete face; - if (yolo) delete yolo; + for(auto &i : dtors_){ + i(); + } + dtors_.clear(); } //////////////////////////////////////////////// cFacePos* c_api_face_detect(int *faceCount, uchar*data, const int w, const int h, const int channel){ - if (!face) return NULL; - const cIMAGE img{data, w, h, 3}; - cFacePos *fpos = NULL; - - int ret = face->face_detect(&img, channel, (void**)&fpos, faceCount); - - if (ret <= 0) return NULL; - return fpos; + return face_detect(faceCount, &img, channel); } cThftResult c_api_face_property(const cFacePos* pos, uchar*data, const int w, const int h, const int channel){ - if (!face) return cThftResult{-1,-1,-1,-1,-1}; const cIMAGE img{data, w, h, 3}; - return face->face_property(*pos, &img, channel); + return face_property(*pos, &img, channel); } uchar* c_api_face_extract(int *featLen, const cFacePos* pos, uchar*data, const int w, const int h, const int channel){ - if (!face) return NULL; const cIMAGE img{data, w, h, 3}; - uchar *feat = NULL; - int ret = face->face_extract_feature(*pos, &img, channel, (void**)&feat, featLen); - if (ret <= 0) return NULL; - return feat; + return face_extract_feature(featLen, *pos, &img, channel); } float c_api_face_compare(uchar *feat1, uchar *feat2){ - if (!face) return NULL; - return face->face_compare(feat1, feat2); + return face_compare(feat1, feat2); +} + +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); +} + +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); } cFaceInfo* c_api_face_track(int *fCount, uchar *data, const int wid, const int hei, const int channel){ - if (!face) return NULL; const cIMAGE img{data, wid, hei, 3}; - - cFaceInfo *info = NULL; - int ret = face->face_track(&img, channel, (void**)&info, fCount); - if (ret <= 0) return NULL; - return info; + return face_track(fCount, &img, channel); } /// yolo api cObjInfo* c_api_yolo_detect(YoloHandle handle, int *objCount, uchar*data, const int w, const int h, const float thrsh, const int use_means){ - if (!yolo) return NULL; const cIMAGE img{data, w, h, 3}; - cObjInfo *info = NULL; - int ret = yolo->yolo_detect(handle, &img, thrsh, use_means, (void**)&info, objCount); - if (ret <= 0) return NULL; - return info; + return yolo_detect(handle, objCount, &img, thrsh, use_means); } const char* c_api_yolo_obj_name(const int typ){ - if (!yolo) return NULL; - - return yolo->yolo_obj_name_by_type(typ); + return yolo_obj_name_by_type(typ); } \ No newline at end of file diff --git a/csdk.h b/csdk.h index a7f67ec..6a0e5d9 100644 --- a/csdk.h +++ b/csdk.h @@ -32,6 +32,8 @@ 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); /// yolo api diff --git a/csrc/all.hpp b/csrc/all.hpp index 58b32ca..6c90c4b 100644 --- a/csrc/all.hpp +++ b/csrc/all.hpp @@ -1,7 +1,11 @@ #ifndef _c_wrapper_face_detector_all_hpp_ #define _c_wrapper_face_detector_all_hpp_ -#include "buz/face/face.cpp" -#include "buz/yolo/yolo.cpp" +#include "buz/face/detector.cpp" +#include "buz/face/extractor.cpp" +#include "buz/face/property.cpp" +#include "buz/face/tracker.cpp" + +#include "buz/yolo/detector.cpp" #endif \ No newline at end of file diff --git a/csrc/buz/face/detector.cpp b/csrc/buz/face/detector.cpp new file mode 100644 index 0000000..e191ea8 --- /dev/null +++ b/csrc/buz/face/detector.cpp @@ -0,0 +1,60 @@ +#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 new file mode 100644 index 0000000..8a4497d --- /dev/null +++ b/csrc/buz/face/detector.h @@ -0,0 +1,18 @@ +#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 new file mode 100644 index 0000000..594eb1f --- /dev/null +++ b/csrc/buz/face/extractor.cpp @@ -0,0 +1,54 @@ +#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 new file mode 100644 index 0000000..31bb712 --- /dev/null +++ b/csrc/buz/face/extractor.h @@ -0,0 +1,14 @@ +#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/face.cpp b/csrc/buz/face/face.cpp deleted file mode 100644 index aa101a0..0000000 --- a/csrc/buz/face/face.cpp +++ /dev/null @@ -1,219 +0,0 @@ -#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 diff --git a/csrc/buz/face/face.h b/csrc/buz/face/face.h deleted file mode 100644 index bd10636..0000000 --- a/csrc/buz/face/face.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _sdk_face_h_ -#define _sdk_face_h_ - -#include "../base.hpp" - -struct _cFacePos; -struct _cIMAGE; -struct THFT_Param; -struct _cFaceInfo; - -namespace csdk_wrap{ - class sdkface{ - public: - sdkface(); - ~sdkface(); - public: - int init_face_detector(const int tm, const int gi, const int minFaces, const int rollAngle); - int face_detect(const cIMAGE *img, const int chan, void **fpos, int *fcnt); - - int init_face_extractor(const int tm, const int gi); - int face_extract_feature(const cFacePos &pos, const cIMAGE *img, const int chan, void **feat, int *featLen); - float face_compare(unsigned char *feat1, unsigned char *feat2); - - int init_face_property(const int tm); - cThftResult face_property(const cFacePos &pos, const cIMAGE *img, const int chan); - - 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); - int face_track(const cIMAGE *img, const int chan, void **fInfo, int *fcnt); - int face_track_resize(const int chan, const int w, const int h); - private: - VecFunc dtors_; - // face detect - cFacePos *fpos_; - // face extract - int featLen_; - unsigned char *feat_; - // face track - cFaceInfo *finfo_; - }; -} - -#endif \ No newline at end of file diff --git a/csrc/buz/face/property.cpp b/csrc/buz/face/property.cpp new file mode 100644 index 0000000..74d4774 --- /dev/null +++ b/csrc/buz/face/property.cpp @@ -0,0 +1,34 @@ +#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 new file mode 100644 index 0000000..39d3976 --- /dev/null +++ b/csrc/buz/face/property.h @@ -0,0 +1,14 @@ +#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 new file mode 100644 index 0000000..73aa7ef --- /dev/null +++ b/csrc/buz/face/tracker.cpp @@ -0,0 +1,89 @@ +#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 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 diff --git a/csrc/buz/face/tracker.h b/csrc/buz/face/tracker.h new file mode 100644 index 0000000..6498bc9 --- /dev/null +++ b/csrc/buz/face/tracker.h @@ -0,0 +1,20 @@ +#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/buz/yolo/detector.cpp b/csrc/buz/yolo/detector.cpp new file mode 100644 index 0000000..1ca2bfe --- /dev/null +++ b/csrc/buz/yolo/detector.cpp @@ -0,0 +1,139 @@ +#include "detector.h" + +#include <stdlib.h> +#include <fstream> + +#include <sys/time.h> + +#include "csdk_struct.h" + +#include "yolo.hpp" + +namespace csdk_wrap{ + + static std::vector<std::string> names; + + static void objects_names_from_file(std::string filename) { + std::ifstream file(filename); + + if (!file.is_open()){ + printf("open %s file error\n", filename.c_str()); + return; + } + for(std::string line; getline(file, line);) names.push_back(line); + + printf("names count %d\n", names.size()); + } + + void* init_yolo_detector(const char *cfg, const char *weights, const char *name, + const int gpu_index, VecFunc &vec){ + + if(!cfg || !weights || !name){ + printf("init Detector error\n"); + return NULL; + } + + if(names.empty()) + objects_names_from_file(name); + + auto det = new Detector(cfg, weights, gpu_index); + vec.emplace_back([det]{delete det;}); + + return det; + } + + image_t* buffer_to_image(const unsigned char *data, const int w, const int h, const int color_channel){ + int size = w*h; + int size2 = size*2; + + int c = color_channel; + image_t *img = new image_t; + img->h = h; + img->w = w; + img->c = color_channel; + img->data = (float*)calloc(h*w*c, sizeof(float)); + // image im = make_image(w, h, c); + const unsigned char *srcData = data; + + int count = 0; + switch(c){ + case 1:{ + for (; count < size; ){ + img->data[count] = + img->data[w*h + count] = + img->data[w*h*2 + count] = + (float)(srcData[count])/255.0; + + ++count; + } + break; + } + case 3:{ + float* desData = img->data; + + for(int i = 0;i<size;i++){ + *(desData) = *(srcData + 2) /255.0f; + *(desData+size) = *(srcData + 1) /255.0f; + *(desData+size2) = *(srcData) /255.0f; + + desData++; + srcData+=3; + } + break; + } + + default: + printf("Channel number not supported.\n"); + break; + } + + return img; + } + + cObjInfo* yolo_detect(void *handle,int *objCount, const cIMAGE *img, const float thrsh, const bool use_mean){ + Detector *det = (Detector*)handle; + + const int color_channel = img->channel; + image_t* im = buffer_to_image(img->data, img->width, img->height, color_channel); + + // struct timeval b,e; + // gettimeofday(&b, NULL); + + std::vector<bbox_t> result_vec = det->detect(*im, thrsh, use_mean); + det->free_image(*im); + delete im; + + // gettimeofday(&e,NULL); + // double t = e.tv_sec*1000.0 + e.tv_usec/1000.0 - b.tv_sec*1000.0-b.tv_usec/1000.0; + // printf("lib yolo detect use time %f ms\n", t); + + cObjInfo *infos = NULL; + if(!result_vec.empty()){ + infos = (cObjInfo*)malloc(result_vec.size() * sizeof(cObjInfo)); + } + + int count = 0; + for(auto &i : result_vec){ + + cObjInfo info; + info.typ = i.obj_id; + info.prob = i.prob; + info.rcObj.left = i.x; + info.rcObj.top = i.y; + info.rcObj.right = i.x+i.w; + info.rcObj.bottom = i.y+i.h; + + infos[count++] = info; + } + + *objCount = count; + + return infos; + } + + const char* yolo_obj_name_by_type(const int typ){ + if(names.empty() || typ < 0 || typ >= names.size()) return NULL; + return names.at(typ).c_str(); + } +} + diff --git a/csrc/buz/yolo/detector.h b/csrc/buz/yolo/detector.h new file mode 100644 index 0000000..1f263b8 --- /dev/null +++ b/csrc/buz/yolo/detector.h @@ -0,0 +1,21 @@ +#ifndef _c_wrapper_yolo_detector_h_ +#define _c_wrapper_yolo_detector_h_ + +#include "../base.hpp" + +struct _cObjInfo; +struct _cIMAGE; + +struct image_t; + + +namespace csdk_wrap{ + void* init_yolo_detector(const char *cfg, const char *weights, const char *name, + const int gpu_index, VecFunc &vec); + image_t* buffer_to_image(const unsigned char *data, const int w, const int h, const int color_channel); + cObjInfo* yolo_detect(void *handle,int *objCount, const cIMAGE *img, const float thrsh, const bool use_mean); + + const char* yolo_obj_name_by_type(const int typ); +} + +#endif \ No newline at end of file diff --git a/csrc/buz/yolo/yolo.cpp b/csrc/buz/yolo/yolo.cpp deleted file mode 100644 index fa59062..0000000 --- a/csrc/buz/yolo/yolo.cpp +++ /dev/null @@ -1,152 +0,0 @@ -#include "yolo.h" - -#include <fstream> - -#include "yolo.hpp" - -namespace csdk_wrap{ - sdkyolo::sdkyolo() - :objInfo_(NULL) - ,objCount_(0) - ,image_(NULL) - ,width_(0) - ,height_(0) - ,channel_(3) - {} - - sdkyolo::~sdkyolo(){ - for(auto i : detors_){ - delete i; - } - if (objInfo_) free(objInfo_); - if (image_){ - free(image_->data); - delete image_; - } - } - - int sdkyolo::buffer_to_image(const unsigned char *data, const int w, const int h, const int color_channel){ - int size = w*h; - int size2 = size*2; - - int c = color_channel; - if (w != width_ || h != height_ || color_channel != channel_){ - if (image_){ - free(image_->data); - delete image_; - } - image_ = new image_t; - image_->h = h; - image_->w = w; - image_->c = c; - image_->data = (float*)calloc(h*w*c, sizeof(float)); - } - - // image im = make_image(w, h, c); - const unsigned char *srcData = data; - - int count = 0; - switch(c){ - case 1:{ - for (; count < size; ){ - image_->data[count] = - image_->data[w*h + count] = - image_->data[w*h*2 + count] = - (float)(srcData[count])/255.0; - - ++count; - } - break; - } - case 3:{ - float* desData = image_->data; - - for(int i = 0;i<size;i++){ - *(desData) = *(srcData + 2) /255.0f; - *(desData+size) = *(srcData + 1) /255.0f; - *(desData+size2) = *(srcData) /255.0f; - - desData++; - srcData+=3; - } - break; - } - - default: - printf("Channel number not supported.\n"); - break; - } - - return 0; - } - - void sdkyolo::objects_names_from_file(std::string filename){ - std::ifstream file(filename); - - if (!file.is_open()){ - printf("open %s file error\n", filename.c_str()); - return; - } - for(std::string line; getline(file, line);) names_.push_back(line); - - printf("names count %d\n", names_.size()); - } - - const char* sdkyolo::yolo_obj_name_by_type(const int typ){ - if(names_.empty() || typ < 0 || typ >= names_.size()) return NULL; - return names_.at(typ).c_str(); - } - - void* sdkyolo::init_yolo(const char *cfg, const char *weights, const char *name, const int gi){ - if(!cfg || !weights || !name){ - printf("init Detector error\n"); - return NULL; - } - - if(names_.empty()) - objects_names_from_file(name); - - auto det = new Detector(cfg, weights, gi); - detors_.push_back(det); - - return det; - } - - int sdkyolo::yolo_detect(void *handle, const cIMAGE *img, const float thrsh, const bool use_mean, void **objs, int *objCount){ - Detector *det = (Detector*)handle; - - const int color_channel = img->channel; - buffer_to_image(img->data, img->width, img->height, color_channel); - - - std::vector<bbox_t> result_vec = det->detect(*image_, thrsh, use_mean); - // det->free_image(*im); - // delete im; - - if (objCount_ < result_vec.size()){ - free(objInfo_); - - objCount_ = result_vec.size(); - objInfo_ = (cObjInfo*)malloc(objCount_ * sizeof(cObjInfo)); - } - - int count = 0; - for(auto &i : result_vec){ - - cObjInfo info; - info.typ = i.obj_id; - info.prob = i.prob; - info.rcObj.left = i.x; - info.rcObj.top = i.y; - info.rcObj.right = i.x+i.w; - info.rcObj.bottom = i.y+i.h; - - objInfo_[count++] = info; - } - - *objCount = count; - *objs = objInfo_; - - return objCount_; - } -} \ No newline at end of file diff --git a/csrc/buz/yolo/yolo.h b/csrc/buz/yolo/yolo.h deleted file mode 100644 index 1a86e48..0000000 --- a/csrc/buz/yolo/yolo.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _sdk_yolo_h_ -#define _sdk_yolo_h_ - -#include <vector> -#include <string> - -struct _cObjInfo; -struct _cIMAGE; - -struct image_t; - -class Detector; - -namespace csdk_wrap{ - class sdkyolo{ - public: - sdkyolo(); - ~sdkyolo(); - public: - void* init_yolo(const char *cfg, const char *weights, const char *name, const int gi); - int yolo_detect(void *handle, const cIMAGE *img, const float thrsh, const bool use_mean, void **objs, int *objCount); - const char* yolo_obj_name_by_type(const int typ); - - private: - int buffer_to_image(const unsigned char *data, const int w, const int h, const int color_channel); - void objects_names_from_file(std::string filename); - private: - std::vector<std::string> names_; - std::vector<Detector*> detors_; - - cObjInfo *objInfo_; - int objCount_; - // image_t - image_t *image_; - int width_; - int height_; - int channel_; - }; -} - -#endif \ No newline at end of file diff --git a/gosdk.go b/gosdk.go index 42b4dcd..5d9858c 100644 --- a/gosdk.go +++ b/gosdk.go @@ -90,6 +90,7 @@ 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)) } return nil @@ -118,6 +119,7 @@ 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)) + defer C.free(unsafe.Pointer(p)) b := C.GoBytes(unsafe.Pointer(p), featLen) return b } @@ -126,6 +128,36 @@ func FaceCompare(feat1 []byte, feat2 []byte) float32 { res := C.c_api_face_compare((*C.uchar)(unsafe.Pointer(&feat1[0])), (*C.uchar)(unsafe.Pointer(&feat2[0]))) return float32(res) +} + +// FaceTrackOnly face tracker face only +func FaceTrackOnly(img SDKImage, ch int) []CRECT { + data := img.Data + w := img.Width + h := img.Height + + var fCount C.int + rect := C.c_api_face_track_only(&fCount, (*C.uchar)(unsafe.Pointer(&data[0])), C.int(w), C.int(h), C.int(ch)) + if rect != nil { + defer C.free(unsafe.Pointer(rect)) + return CRECTArrayToGoArray(unsafe.Pointer(rect), int(fCount)) + } + return nil +} + +// FaceTrackDetect face tracker face detect +func FaceTrackDetect(img SDKImage, ch int) []CFaceInfo { + data := img.Data + w := img.Width + h := img.Height + + var fCount C.int + finfo := C.c_api_face_track_only(&fCount, (*C.uchar)(unsafe.Pointer(&data[0])), C.int(w), C.int(h), C.int(ch)) + if finfo != nil { + defer C.free(unsafe.Pointer(finfo)) + return CFaceInfoArrayToGoArray(unsafe.Pointer(finfo), int(fCount)) + } + return nil } // FaceTrackingInfo face track info @@ -145,6 +177,7 @@ if cFinfo == nil { return } + defer C.free(unsafe.Pointer(cFinfo)) goFinfo := CFaceInfoArrayToGoArray(unsafe.Pointer(cFinfo), int(fCount)) // 绌猴紝娣诲姞 @@ -217,6 +250,7 @@ if cFinfo == nil { return faces } + defer C.free(unsafe.Pointer(cFinfo)) faces = CFaceInfoArrayToGoArray(unsafe.Pointer(cFinfo), int(fCount)) //if len(faces) > 0{ // fmt.Println("faces detected:", len(faces)) @@ -237,6 +271,7 @@ cobjinfo := C.c_api_yolo_detect(handle.handle, &count, (*C.uchar)(unsafe.Pointer(&data[0])), C.int(w), C.int(h), C.float(thrsh), C.int(umns)) if cobjinfo != nil { + defer C.free(unsafe.Pointer(cobjinfo)) return CYoloObjInfoArrayToGoArray(unsafe.Pointer(cobjinfo), int(count)) } return nil -- Gitblit v1.8.0