From 595a5ee8ec01e0199b3d69311151417307f3b264 Mon Sep 17 00:00:00 2001
From: zhangmeng <775834166@qq.com>
Date: 星期三, 15 一月 2020 11:30:41 +0800
Subject: [PATCH] copy from bgr-2-analysis
---
csrc/buz/face/property.h | 14 +
cface.h | 64 ++--
csrc/buz/base.hpp | 9
csrc/buz/face/property.cpp | 34 ++
csrc/buz/face/detector.h | 18 +
csrc/buz/face/detector.cpp | 60 +++++
csrc/buz/face/tracker.h | 20 +
csrc/all.hpp | 9
/dev/null | 51 ----
cface.cpp | 137 +++++-----
csrc/buz/face/extractor.h | 14 +
csrc/buz/face/extractor.cpp | 54 ++++
csrc/buz/face/tracker.cpp | 89 +++++++
csdk_struct.h | 23 +
goface.go | 103 +++-----
15 files changed, 478 insertions(+), 221 deletions(-)
diff --git a/cface.cpp b/cface.cpp
index 99ab41c..fc20813 100644
--- a/cface.cpp
+++ b/cface.cpp
@@ -1,86 +1,85 @@
#ifdef __cplusplus
extern "C"{
#endif
-
-#include <stdio.h>
+
#include "cface.h"
-
+
#ifdef __cplusplus
}
#endif
-
-#include "csrc/face.h"
-
-#include "csrc/struct.h"
-
-#include "csrc/face.cpp"
-
-using namespace cppface;
-
-void *create_sdkface(){
- return new sdkface();
+
+#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_);
}
-
-void release(void *handle){
- if (handle){
- sdkface *s = (sdkface*)handle;
- delete s;
+
+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();
}
+ dtors_.clear();
}
-
-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);
+
+////////////////////////////////////////////////
+
+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_extractor(void *handle, const int threads_max, const int gpu){
- sdkface *s = (sdkface*)handle;
- return s->extractor(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_propertizer(void *handle, const int threads_max){
- sdkface *s = (sdkface*)handle;
- return s->propertizer(threads_max);
+
+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_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);
+
+float c_api_face_compare(uchar *feat1, uchar *feat2){
+ return face_compare(feat1, feat2);
}
-
-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);
+
+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 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_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);
}
-
-float compare(void *handle, unsigned char *feat1, unsigned char *feat2){
- sdkface *s = (sdkface*)handle;
- return s->compare(feat1, feat2);
+
+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);
}
-
-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 e9a3234..c1d0076 100644
--- a/cface.h
+++ b/cface.h
@@ -1,36 +1,40 @@
-#ifndef _c_face_h_
-#define _c_face_h_
-
+#ifndef _c_wrapper_sdk_h_
+#define _c_wrapper_sdk_h_
+
#ifdef __cplusplus
extern "C"{
#endif
-
-#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);
-
+
+#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);
+
#ifdef __cplusplus
}
#endif
-
-#endif
+
+
+#endif
\ No newline at end of file
diff --git a/csrc/struct.h b/csdk_struct.h
similarity index 90%
rename from csrc/struct.h
rename to csdk_struct.h
index 9be7c4c..e733027 100644
--- a/csrc/struct.h
+++ b/csdk_struct.h
@@ -1,32 +1,34 @@
-#ifndef _face_struct_h_
-#define _face_struct_h_
-
+#ifndef _c_wrapper_c_structure_h_
+#define _c_wrapper_c_structure_h_
+
+#include <string.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]
@@ -34,7 +36,7 @@
int beauty_level;//range[0-100]
int smile_level;//range[0-100]
} cThftResult;
-
+
typedef struct _cFacePos {
cRECT rcFace;
cPOINT ptLeftEye;
@@ -46,7 +48,7 @@
unsigned char pFacialData[512];
} cFacePos;
-
+
typedef struct _cFaceInfo{
cRECT rcFace;
cPOINT ptLeftEye;
@@ -59,5 +61,6 @@
unsigned char pFacialData[8*1024];
long nFaceID;//face tracking id
} cFaceInfo;
-
+
+
#endif
\ No newline at end of file
diff --git a/csrc/all.hpp b/csrc/all.hpp
new file mode 100644
index 0000000..bbe31af
--- /dev/null
+++ b/csrc/all.hpp
@@ -0,0 +1,9 @@
+#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
new file mode 100644
index 0000000..c8e6763
--- /dev/null
+++ b/csrc/buz/base.hpp
@@ -0,0 +1,9 @@
+#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
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/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..cb2744a
--- /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 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/face.cpp b/csrc/face.cpp
deleted file mode 100644
index 328111a..0000000
--- a/csrc/face.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-#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
deleted file mode 100644
index d0b5233..0000000
--- a/csrc/face.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#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/goface.go b/goface.go
index 7891acf..e77e23c 100644
--- a/goface.go
+++ b/goface.go
@@ -22,7 +22,6 @@
// SDKFace sdk
type SDKFace struct {
- handle unsafe.Pointer
detector bool
extractor bool
propertizer bool
@@ -32,13 +31,8 @@
// 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,
@@ -49,9 +43,7 @@
// Free free
func (s *SDKFace) Free() {
- if s != nil && s.handle != nil {
- C.release(s.handle)
- }
+ C.c_api_release()
}
func (s *SDKFace) printLog(l ...interface{}) {
@@ -61,12 +53,14 @@
}
// Detector detector
-func (s *SDKFace) Detector(minFaces, rollAngles, threadMax, gpu int) bool {
+func (s *SDKFace) Detector(minFaces, rollAngle, threadMax, gpu int) bool {
if s.detector {
return true
}
- ret := C.init_detector(s.handle, C.int(minFaces), C.int(rollAngles), C.int(threadMax), C.int(gpu))
+
+ ret := C.c_api_face_detector_init(C.int(threadMax), C.int(gpu), C.int(minFaces), C.int(rollAngle))
+
if ret <= 0 {
s.printLog("->face--> CREATE Detector ERROR: ", ret)
return false
@@ -81,7 +75,7 @@
if s.extractor {
return true
}
- ret := C.init_extractor(s.handle, C.int(threadMax), C.int(gpu))
+ ret := C.c_api_face_extractor_init(C.int(threadMax), C.int(gpu))
if ret <= 0 {
s.printLog("->face--> CREATE Extractor ERROR: ", ret)
return false
@@ -96,7 +90,7 @@
if s.propertizer {
return true
}
- ret := C.init_propertizer(s.handle, C.int(threadMax))
+ ret := C.c_api_face_property_init(C.int(threadMax))
if ret <= 0 {
s.printLog("->face--> CREATE Propertizer ERROR: ", ret)
return false
@@ -109,10 +103,9 @@
func (s *SDKFace) Tracker(w, h, maxFaces, interval, sampleSize, threadMax, gpu int) bool {
if s.tracker {
- return s.tracker
+ return true
}
- 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))
-
+ 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))
if ret <= 0 {
s.printLog("->face--> CREATE Tracker ERROR: ", ret)
return false
@@ -141,29 +134,32 @@
return nil
}
- var cfpos unsafe.Pointer
var count C.int
- 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))
+ 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))
}
- s.printLog("->face--> Detect No One, Ret: ", ret)
+
+ s.printLog("->face--> Detect No One")
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))
- //(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)
+ 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)
}
- s.printLog("->face--> Extract Nothing, Ret: ", ret)
+ s.printLog("->face--> Extract Nothing")
return nil
}
@@ -174,27 +170,20 @@
return 0
}
- res := C.compare(s.handle, (*C.uchar)(unsafe.Pointer(&feat1[0])), (*C.uchar)(unsafe.Pointer(&feat2[0])))
+ res := C.c_api_face_compare((*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 nil
+ return sdkstruct.CThftResult{Age: 0}
}
pos := (*C.cFacePos)(unsafe.Pointer(&fpos))
-
- 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
+ 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))
}
// CFaceInfoArrayToGoArray convert cFaceInfo array to go
@@ -218,17 +207,14 @@
//img, const int chan, void **fInfo, int *fcnt);
var fCount C.int
- 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
+ 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
}
- return nil
+ defer C.free(unsafe.Pointer(cFinfo))
+ faces := CFaceInfoArrayToGoArray(unsafe.Pointer(cFinfo), int(fCount))
+ return faces
}
// FaceInfo2FacePos info -> pos
@@ -249,18 +235,13 @@
}
// TrackerResize init face tracker
-func (s *SDKFace) TrackerResize(w, h, ch int) bool {
+func (s *SDKFace) TrackerResize(w, h, ch int) int {
if !s.tracker {
s.printLog("->face--> TrackerResize Failed, No Tracker Init")
- return false
+ return -1
}
- 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
+ return int(C.c_api_face_track_resize(C.int(ch), C.int(w), C.int(h)))
}
// Run run
@@ -291,7 +272,7 @@
//杩愯sd
dec := FaceInfo2FacePos(d)
- p := s.Propertize(dec, data, w, h, c, 0)
+ p := s.Propertize(dec, data, w, h, c, dchan)
feat := s.Extract(dec, data, w, h, c, dchan)
/// filter rules
@@ -299,7 +280,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