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