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, &param);
-        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, &param);
+        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