Video Analysis底层库拆分,sdk的go封装
chenshijun
2019-10-22 b7340a34ff68f018a4aa0e7aada3b7feaabd2fe1
csrc/buz/face/face.cpp
New file
@@ -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;
    }
}