Video Analysis底层库拆分,sdk的go封装
zhangmeng
2019-10-19 46a5aa51e6b903913a847594a1b57b0a62822b98
class them
10个文件已删除
4个文件已添加
4个文件已修改
999 ■■■■ 已修改文件
csdk.cpp 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csdk.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/all.hpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/buz/face/detector.cpp 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/buz/face/detector.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/buz/face/extractor.cpp 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/buz/face/extractor.h 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/buz/face/face.cpp 203 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/buz/face/face.h 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/buz/face/property.cpp 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/buz/face/property.h 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/buz/face/tracker.cpp 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/buz/face/tracker.h 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/buz/yolo/detector.cpp 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/buz/yolo/detector.h 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/buz/yolo/yolo.cpp 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/buz/yolo/yolo.h 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
gosdk.go 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csdk.cpp
@@ -12,88 +12,103 @@
using namespace csdk_wrap;
static VecFunc dtors_;
static sdkface *face = NULL;
static sdkyolo *yolo = NULL;
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_);
    if (!face) face = new sdkface();
    return face->init_face_detector(tm, gi, minFaces, rollAngle);
}
int c_api_face_property_init(const int tm){
    return init_face_property(tm, dtors_);
    if (!face) face = new sdkface();
    return face->init_face_property(tm);
}
int c_api_face_extractor_init(const int tm, const int gi){
    return init_face_extractor(tm, gi, dtors_);
    if (!face) face = new sdkface();
    return face->init_face_extractor(tm, 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){
   return init_face_tracker(tm, gi, wid, hei, maxFaces, detinterval, sampleSize, dtors_);
    if (!face) face = new sdkface();
    return face->init_face_tracker(tm, gi, wid, hei, maxFaces, detinterval, sampleSize);
}
YoloHandle c_api_yolo_init(
    const char *fcfg, const char *fweights, const char *fname,
    const int gpu_index){
    return init_yolo_detector(fcfg, fweights, fname, gpu_index, dtors_);
    if (!yolo) yolo = new sdkyolo;
    return yolo->init_yolo(fcfg, fweights, fname, gpu_index);
}
void c_api_release(){
    for(auto &i : dtors_){
        i();
    }
    dtors_.clear();
    if (face) delete face;
    if (yolo) delete yolo;
}
////////////////////////////////////////////////
cFacePos* c_api_face_detect(int *faceCount, uchar*data, const int w, const int h, const int channel){
    if (!face) return NULL;
    const cIMAGE img{data, w, h, 3};
    return face_detect(faceCount, &img, channel);
    cFacePos *fpos = NULL;
    int ret = face->face_detect(&img, channel, (void**)&fpos, faceCount);
    if (ret <= 0) return NULL;
    return fpos;
}
cThftResult c_api_face_property(const cFacePos* pos, uchar*data, const int w, const int h, const int channel){
    if (!face) return cThftResult{-1,-1,-1,-1,-1};
    const cIMAGE img{data, w, h, 3};
    return face_property(*pos, &img, channel);
    return face->face_property(*pos, &img, channel);
}
uchar* c_api_face_extract(int *featLen, const cFacePos* pos, uchar*data, const int w, const int h, const int channel){
    if (!face) return NULL;
    const cIMAGE img{data, w, h, 3};
    return face_extract_feature(featLen, *pos, &img, channel);
    uchar *feat = NULL;
    int ret = face->face_extract_feature(*pos, &img, channel, (void**)&feat, featLen);
    if (ret <= 0) return NULL;
    return feat;
}
float c_api_face_compare(uchar *feat1, uchar *feat2){
    return face_compare(feat1, feat2);
}
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);
}
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);
    if (!face) return NULL;
    return face->face_compare(feat1, feat2);
}
cFaceInfo* c_api_face_track(int *fCount, uchar *data, const int wid, const int hei, const int channel){
    if (!face) return NULL;
    const cIMAGE img{data, wid, hei, 3};
    return face_track(fCount, &img, channel);
    cFaceInfo *info = NULL;
    int ret = face->face_track(&img, channel, (void**)&info, fCount);
    if (ret <= 0) return NULL;
    return info;
}
/// yolo api
cObjInfo* c_api_yolo_detect(YoloHandle handle, int *objCount, uchar*data, const int w, const int h, const float thrsh, const int use_means){
    if (!yolo) return NULL;
    const cIMAGE img{data, w, h, 3};
    return yolo_detect(handle, objCount, &img, thrsh, use_means);
    cObjInfo *info = NULL;
    int ret = yolo->yolo_detect(handle, &img, thrsh, use_means, (void**)&info, objCount);
    if (ret <= 0) return NULL;
    return info;
}
const char* c_api_yolo_obj_name(const int typ){
    return yolo_obj_name_by_type(typ);
    if (!yolo) return NULL;
    return yolo->yolo_obj_name_by_type(typ);
}
csdk.h
@@ -32,8 +32,6 @@
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);
/// yolo api
csrc/all.hpp
@@ -1,11 +1,7 @@
#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"
#include "buz/yolo/detector.cpp"
#include "buz/face/face.cpp"
#include "buz/yolo/yolo.cpp"
#endif
csrc/buz/face/detector.cpp
File was deleted
csrc/buz/face/detector.h
File was deleted
csrc/buz/face/extractor.cpp
File was deleted
csrc/buz/face/extractor.h
File was deleted
csrc/buz/face/face.cpp
New file
@@ -0,0 +1,203 @@
#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)
    ,param_track_(NULL)
    ,finfo_(NULL)
    {}
    sdkface::~sdkface(){
        for(auto &i : dtors_){
            i();
        }
        if (fpos_) free(fpos_);
        if (feat_) free(feat_);
        if (param_track_) free(param_track_);
        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;
        }
        ::THFI_FacePos facesPos[maxFacePos];
        int faceNum = THFI_DetectFace(chan, (BYTE*)(img->data), 24, img->width, img->height, facesPos, 30);
        if (faceNum > 0) {
            if (fpos_ == NULL){
                fpos_ =  (cFacePos*)malloc(maxFacePos * sizeof(cFacePos));
            }
            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;
    }
/////////////////////////////////////////////////////
    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){
        if (param_track_) return -1;
        param_track_ = (THFT_Param*)malloc(sizeof(THFT_Param));
        param_track_->nDeviceID = gi;
        param_track_->nImageWidth = w;
        param_track_->nImageHeight = h;
        param_track_->nMaxFaceNum = maxFaces;
        param_track_->nSampleSize = sampleSize > 0 ? sampleSize : w/2;
        param_track_->nDetectionIntervalFrame = detinterval;
        auto nNum = THFT_Create(tm, param_track_);
        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 (!param_track_) return -1;
        if (!finfo_){
            finfo_ = (cFaceInfo*)malloc(param_track_->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;
    }
}
csrc/buz/face/face.h
New file
@@ -0,0 +1,43 @@
#ifndef _sdk_face_h_
#define _sdk_face_h_
#include "../base.hpp"
struct _cFacePos;
struct _cIMAGE;
struct THFT_Param;
struct _cFaceInfo;
namespace csdk_wrap{
    class sdkface{
    public:
        sdkface();
        ~sdkface();
    public:
        int init_face_detector(const int tm, const int gi, const int minFaces, const int rollAngle);
        int face_detect(const cIMAGE *img, const int chan, void **fpos, int *fcnt);
        int init_face_extractor(const int tm, const int gi);
        int face_extract_feature(const cFacePos &pos, const cIMAGE *img, const int chan, void **feat, int *featLen);
        float face_compare(unsigned char *feat1, unsigned char *feat2);
        int init_face_property(const int tm);
        cThftResult face_property(const cFacePos &pos, const cIMAGE *img, const int chan);
        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);
        int face_track(const cIMAGE *img, const int chan, void **fInfo, int *fcnt);
    private:
        VecFunc dtors_;
        // face detect
        cFacePos *fpos_;
        // face extract
        int featLen_;
        unsigned char *feat_;
        // face track
        THFT_Param *param_track_;
        cFaceInfo *finfo_;
    };
}
#endif
csrc/buz/face/property.cpp
File was deleted
csrc/buz/face/property.h
File was deleted
csrc/buz/face/tracker.cpp
File was deleted
csrc/buz/face/tracker.h
File was deleted
csrc/buz/yolo/detector.cpp
File was deleted
csrc/buz/yolo/detector.h
File was deleted
csrc/buz/yolo/yolo.cpp
New file
@@ -0,0 +1,148 @@
#include "yolo.h"
#include <fstream>
#include "yolo.hpp"
namespace csdk_wrap{
    sdkyolo::sdkyolo()
    :objInfo_(NULL)
    ,objCount_(0)
    ,image_(NULL)
    ,width_(0)
    ,height_(0)
    ,channel_(3)
    {}
    sdkyolo::~sdkyolo(){
        for(auto i : detors_){
            delete i;
        }
        if (objInfo_) free(objInfo_);
    }
    int sdkyolo::buffer_to_image(const unsigned char *data, const int w, const int h, const int color_channel){
        int size = w*h;
        int size2 = size*2;
        int c = color_channel;
        if (w != width_ || h != height_ || color_channel != channel_){
            if (image_){
                free(image_->data);
                delete image_;
            }
            image_ = new image_t;
            image_->h = h;
            image_->w = w;
            image_->c = c;
            image_->data = (float*)calloc(h*w*c, sizeof(float));
        }
        // image im = make_image(w, h, c);
        const unsigned char *srcData = data;
        int count = 0;
        switch(c){
            case 1:{
                for (; count < size; ){
                    image_->data[count] =
                    image_->data[w*h + count] =
                    image_->data[w*h*2 + count] =
                    (float)(srcData[count])/255.0;
                    ++count;
                }
                break;
            }
            case 3:{
                float* desData = image_->data;
                for(int i = 0;i<size;i++){
                    *(desData) = *(srcData + 2) /255.0f;
                    *(desData+size) = *(srcData + 1) /255.0f;
                    *(desData+size2) = *(srcData) /255.0f;
                    desData++;
                    srcData+=3;
                }
                break;
            }
            default:
                printf("Channel number not supported.\n");
                break;
        }
        return 0;
    }
    void sdkyolo::objects_names_from_file(std::string filename){
        std::ifstream file(filename);
        if (!file.is_open()){
            printf("open %s file error\n", filename.c_str());
            return;
        }
        for(std::string line; getline(file, line);) names_.push_back(line);
        printf("names count %d\n", names_.size());
    }
    const char* sdkyolo::yolo_obj_name_by_type(const int typ){
        if(names_.empty() || typ < 0 || typ >= names_.size()) return NULL;
        return names_.at(typ).c_str();
    }
    void* sdkyolo::init_yolo(const char *cfg, const char *weights, const char *name, const int gi){
        if(!cfg || !weights || !name){
            printf("init Detector error\n");
            return NULL;
        }
        if(names_.empty())
            objects_names_from_file(name);
        auto det = new Detector(cfg, weights, gi);
        detors_.push_back(det);
        return det;
    }
    int sdkyolo::yolo_detect(void *handle, const cIMAGE *img, const float thrsh, const bool use_mean, void **objs, int *objCount){
        Detector *det = (Detector*)handle;
        const int color_channel = img->channel;
        buffer_to_image(img->data, img->width, img->height, color_channel);
        std::vector<bbox_t> result_vec = det->detect(*image_, thrsh, use_mean);
        // det->free_image(*im);
        // delete im;
        if (objCount_ < result_vec.size()){
            free(objInfo_);
            objCount_ = result_vec.size();
            objInfo_ = (cObjInfo*)malloc(objCount_ * sizeof(cObjInfo));
        }
        int count = 0;
        for(auto &i : result_vec){
            cObjInfo info;
            info.typ = i.obj_id;
            info.prob = i.prob;
            info.rcObj.left = i.x;
            info.rcObj.top = i.y;
            info.rcObj.right = i.x+i.w;
            info.rcObj.bottom = i.y+i.h;
            objInfo_[count++] = info;
        }
        *objCount = objCount_;
        *objs = objInfo_;
        return objCount_;
    }
}
csrc/buz/yolo/yolo.h
New file
@@ -0,0 +1,41 @@
#ifndef _sdk_yolo_h_
#define _sdk_yolo_h_
#include <vector>
#include <string>
struct _cObjInfo;
struct _cIMAGE;
struct image_t;
class Detector;
namespace csdk_wrap{
    class sdkyolo{
    public:
        sdkyolo();
        ~sdkyolo();
    public:
        void* init_yolo(const char *cfg, const char *weights, const char *name, const int gi);
        int yolo_detect(void *handle, const cIMAGE *img, const float thrsh, const bool use_mean, void **objs, int *objCount);
        const char* yolo_obj_name_by_type(const int typ);
    private:
        int buffer_to_image(const unsigned char *data, const int w, const int h, const int color_channel);
        void objects_names_from_file(std::string filename);
    private:
        std::vector<std::string> names_;
        std::vector<Detector*> detors_;
        cObjInfo *objInfo_;
        int objCount_;
        // image_t
        image_t *image_;
        int width_;
        int height_;
        int channel_;
    };
}
#endif
gosdk.go
@@ -84,7 +84,6 @@
    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))
    }
    return nil
@@ -113,7 +112,6 @@
    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))
    defer C.free(unsafe.Pointer(p))
    b := C.GoBytes(unsafe.Pointer(p), featLen)
    return b
}
@@ -122,36 +120,6 @@
func FaceCompare(feat1 []byte, feat2 []byte) float32 {
    res := C.c_api_face_compare((*C.uchar)(unsafe.Pointer(&feat1[0])), (*C.uchar)(unsafe.Pointer(&feat2[0])))
    return float32(res)
}
// FaceTrackOnly face tracker face only
func FaceTrackOnly(img SDKImage, ch int) []CRECT {
    data := img.Data
    w := img.Width
    h := img.Height
    var fCount C.int
    rect := C.c_api_face_track_only(&fCount, (*C.uchar)(unsafe.Pointer(&data[0])), C.int(w), C.int(h), C.int(ch))
    if rect != nil {
        defer C.free(unsafe.Pointer(rect))
        return CRECTArrayToGoArray(unsafe.Pointer(rect), int(fCount))
    }
    return nil
}
// FaceTrackDetect face tracker face detect
func FaceTrackDetect(img SDKImage, ch int) []CFaceInfo {
    data := img.Data
    w := img.Width
    h := img.Height
    var fCount C.int
    finfo := C.c_api_face_track_only(&fCount, (*C.uchar)(unsafe.Pointer(&data[0])), C.int(w), C.int(h), C.int(ch))
    if finfo != nil {
        defer C.free(unsafe.Pointer(finfo))
        return CFaceInfoArrayToGoArray(unsafe.Pointer(finfo), int(fCount))
    }
    return nil
}
// FaceTrackingInfo face track info
@@ -171,7 +139,6 @@
    if cFinfo == nil {
        return
    }
    defer C.free(unsafe.Pointer(cFinfo))
    goFinfo := CFaceInfoArrayToGoArray(unsafe.Pointer(cFinfo), int(fCount))
    // 空,添加
@@ -244,7 +211,6 @@
    if cFinfo == nil {
        return faces
    }
    defer C.free(unsafe.Pointer(cFinfo))
    faces = CFaceInfoArrayToGoArray(unsafe.Pointer(cFinfo), int(fCount))
    //if len(faces) > 0{
    // fmt.Println("faces detected:", len(faces))
@@ -265,7 +231,6 @@
    cobjinfo := C.c_api_yolo_detect(handle.handle, &count, (*C.uchar)(unsafe.Pointer(&data[0])), C.int(w), C.int(h), C.float(thrsh), C.int(umns))
    if cobjinfo != nil {
        defer C.free(unsafe.Pointer(cobjinfo))
        return CYoloObjInfoArrayToGoArray(unsafe.Pointer(cobjinfo), int(count))
    }
    return nil