From b7340a34ff68f018a4aa0e7aada3b7feaabd2fe1 Mon Sep 17 00:00:00 2001
From: chenshijun <csj_sky@126.com>
Date: 星期二, 22 十月 2019 14:52:49 +0800
Subject: [PATCH] 增加人脸跟踪检测的通道分辨率调整接口face_track_resize

---
 csrc/buz/face/face.cpp |  219 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 219 insertions(+), 0 deletions(-)

diff --git a/csrc/buz/face/face.cpp b/csrc/buz/face/face.cpp
new file mode 100644
index 0000000..aa101a0
--- /dev/null
+++ b/csrc/buz/face/face.cpp
@@ -0,0 +1,219 @@
+#include "face.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "THFaceImage_i.h"
+#include "THFeature_i.h"
+#include "THFaceProperty_i.h"
+#include "THFaceTracking_i.h"
+
+#include "csdk_struct.h"
+
+namespace csdk_wrap{
+    sdkface::sdkface()
+    :fpos_(NULL)
+    ,featLen_(0)
+    ,feat_(NULL)
+    ,finfo_(NULL)
+    {}
+
+    sdkface::~sdkface(){
+        for(auto &i : dtors_){
+            i();
+        }
+
+        if (fpos_) free(fpos_);
+        if (feat_) free(feat_);
+        if (finfo_) free(finfo_);
+    }
+
+    int sdkface::init_face_detector(const int tm, const int gi, const int minFaces, const int rollAngle){
+        int ret = 0;
+          if (gi < 0) {
+              THFI_Param *param = new THFI_Param[tm];
+              ret = THFI_Create(tm, param);
+              delete[] param;
+          } else {
+              THFI_Param_Ex *param = new THFI_Param_Ex[tm];
+              THFI_Param detParam;
+              detParam.nMinFaceSize = minFaces;
+              detParam.nRollAngle = rollAngle;
+              for (int i = 0; i < tm; i++) {
+                  param[i].tp = detParam;
+                  param[i].nDeviceID = gi;
+              }
+              ret = THFI_Create_Ex(tm, param);
+              delete[] param;
+          }
+          if(ret != tm){
+              printf("create face detector failed!\n");
+          }else{
+              dtors_.emplace_back([]{THFI_Release();});
+          }
+          
+          return ret;
+    }
+
+static const int maxFacePos = 30;
+
+    int sdkface::face_detect(const cIMAGE *img, const int chan, void **fpos, int *fcnt){
+        if(chan < 0 || !img || !img->data || img->width <= 0 || img->height <= 0){
+            return -1;
+        }
+
+        if (fpos_ == NULL){
+            fpos_ =  (cFacePos*)malloc(maxFacePos * sizeof(cFacePos));
+        }
+
+        // ::THFI_FacePos facesPos[maxFacePos];
+        int faceNum = THFI_DetectFace(chan, (BYTE*)(img->data), 24, img->width, img->height, 
+                                      (::THFI_FacePos*)fpos_, maxFacePos);
+
+        if (faceNum > 0) {
+            // memcpy(fpos_, facesPos, sizeof(THFI_FacePos) * faceNum);
+            *fcnt = faceNum;
+            *fpos = fpos_;
+        }
+        return faceNum;
+    }
+///////////////////////////////////////////////////
+    int sdkface::init_face_extractor(const int tm, const int gi){
+        int ret = 0;
+        if (gi < 0) {
+            ret = EF_Init(tm);
+        } else {
+            EF_Param *param = new EF_Param[tm];
+            for (int i = 0; i < tm; i++) {
+                param[i].nDeviceID = gi;
+            }
+            ret = EF_Init_Ex(tm, param);
+            delete[] param;
+        }
+        if(ret != tm){
+            printf("create face extractor failed!\n");;
+        }else{
+            dtors_.emplace_back([]{EF_Release();});
+        }
+        return ret;
+    }
+
+    int sdkface::face_extract_feature(const cFacePos &pos, const cIMAGE *img, const int chan, 
+                                        void **feat, int *featLen){
+        if(chan < 0 || !img || !img->data || img->width <= 0 || img->height <= 0){
+            printf("face extract error, image or pos null\n");
+            return -1;
+        }
+        *featLen = EF_Size();
+        if (featLen_ < *featLen){
+            free(feat_);
+            feat_ = (unsigned char*)malloc(*featLen);
+            featLen_ = *featLen;
+        }
+
+        auto ret = EF_Extract(chan, (BYTE*)(img->data), img->width, img->height, 3, 
+                                (THFI_FacePos*)(&pos), feat_);
+        
+        if(ret != 1){
+            printf("face extract error %d\n", ret);
+            return ret;
+        }
+        
+        *feat = feat_;
+
+        return *featLen;
+    }
+
+    float sdkface::face_compare(unsigned char *feat1, unsigned char *feat2){
+        if (!feat1 || !feat2){
+            return 0.0f;
+        }
+
+        return EF_Compare(feat1, feat2);
+    }
+
+////////////////////////////////////////////
+    int sdkface::init_face_property(const int tm){
+        auto ret = THFP_Create(tm);
+        if(ret != tm){
+            printf("create face property error\n");
+        }else{
+            dtors_.emplace_back([]{THFP_Release();});
+        }
+        return ret;
+    }
+
+    cThftResult sdkface::face_property(const cFacePos &pos, const cIMAGE *img, const int chan){
+        cThftResult result;
+        result.gender = result.age = result.race = -1;
+
+        auto ret = THFP_Execute_V2(chan, (BYTE*)(img->data), img->width, img->height,
+            (THFI_FacePos*)(&pos), (THFP_Result_V2*)(&result));
+        if(ret == 0){
+            // printf("property face gender %s, age %d, race %s, beauty level %d, smile_level %d\n", 
+            // result.gender ?"male":"female",
+            // result.age,
+            // result.race==2?"yello":"other",
+            // result.beauty_level, result.smile_level);
+        }
+        return result;
+    }
+/////////////////////////////////////////////////////
+static THFT_Param param;
+    int sdkface::init_face_tracker(const int tm, const int gi,const int w, const int h,
+                    const int maxFaces, const int detinterval,  const int sampleSize){
+        param.nDeviceID = gi;
+        param.nImageWidth = w;
+        param.nImageHeight = h;
+        param.nMaxFaceNum = maxFaces;
+        param.nSampleSize = sampleSize > 0 ? sampleSize : w/2;
+        param.nDetectionIntervalFrame = detinterval;
+        
+        printf("threads %d gi: %d size: %dx%d maxface: %d, sample: %d, interval: %d\n",
+            tm, gi, w, h, maxFaces, sampleSize, detinterval);
+        
+        auto nNum = THFT_Create(tm, &param);
+        if(nNum != tm){
+            printf("create face detector failed!\n");
+        }else{
+            dtors_.emplace_back([]{THFT_Release();});
+        }
+        return nNum;
+    }
+
+    int sdkface::face_track(const cIMAGE *img, const int chan, void **fInfo, int *fcnt){
+
+        if (!finfo_){
+            finfo_ = (cFaceInfo*)malloc(param.nMaxFaceNum * sizeof(cFaceInfo));
+        }
+
+        *fcnt = 0;
+
+        auto nNum = THFT_FaceTracking(chan, img->data, (THFT_FaceInfo*)finfo_);
+        if (nNum > 0){
+            *fcnt = nNum;
+            *fInfo = finfo_;
+        }else{
+            *fInfo = NULL;
+        }
+        return nNum;
+    }
+
+    //THFACETRACKING_API int	THFT_Reset(short nChannelID, THFT_Param* pParam);
+    int sdkface::face_track_resize(const int chan, const int w, const int h){
+        THFT_Param tmpParam;
+        tmpParam.nDeviceID = param.nDeviceID;
+        tmpParam.nImageWidth = w;
+        tmpParam.nImageHeight = h;
+        tmpParam.nMaxFaceNum = param.nMaxFaceNum;
+        tmpParam.nSampleSize = param.nSampleSize;
+        tmpParam.nDetectionIntervalFrame = param.nDetectionIntervalFrame;
+
+        printf("chan %d size: %dx%d", chan, w, h);
+
+        auto flag = THFT_Reset(chan, &tmpParam);
+
+        return flag;
+    }
+}
\ No newline at end of file

--
Gitblit v1.8.0