New file |
| | |
| | | package gosdk |
| | | |
| | | import "image" |
| | | |
| | | // Rect convert CRECT to image Rect |
| | | func Rect(rect CRECT) image.Rectangle { |
| | | return image.Rect(int(rect.Left), int(rect.Top), int(rect.Right), int(rect.Bottom)) |
| | | } |
| | | |
| | | // Pt get CPOINT to image Pt |
| | | func Pt(pt CPOINT) image.Point { |
| | | return image.Pt(int(pt.X), int(pt.Y)) |
| | | } |
New file |
| | |
| | | package gosdk |
| | | |
| | | /* |
| | | #include <string.h> |
| | | #include "csdk_struct.h" |
| | | |
| | | int get_facepos_size(){ |
| | | return sizeof(cFacePos); |
| | | } |
| | | */ |
| | | import "C" |
| | | import ( |
| | | "unsafe" |
| | | ) |
| | | |
| | | // CFacePosArrayToGoArray convert cFacePos array to go |
| | | func CFacePosArrayToGoArray(cArray unsafe.Pointer, count int) (goArray []CFacePos) { |
| | | p := uintptr(cArray) |
| | | |
| | | for i := 0; i < count; i++ { |
| | | j := *(*CFacePos)(unsafe.Pointer(p)) |
| | | |
| | | goArray = append(goArray, j) |
| | | |
| | | p += unsafe.Sizeof(j) |
| | | } |
| | | return |
| | | } |
| | | |
| | | // CYoloObjInfoArrayToGoArray convert cObjInfo array to go |
| | | func CYoloObjInfoArrayToGoArray(cArray unsafe.Pointer, count int) (goArray []CObjInfo) { |
| | | p := uintptr(cArray) |
| | | |
| | | for i := 0; i < count; i++ { |
| | | j := *(*CObjInfo)(unsafe.Pointer(p)) |
| | | goArray = append(goArray, j) |
| | | p += unsafe.Sizeof(j) |
| | | } |
| | | return |
| | | } |
| | | |
| | | // CRECTArrayToGoArray convert cRECT array to go |
| | | func CRECTArrayToGoArray(cArray unsafe.Pointer, count int) (goArray []CRECT) { |
| | | p := uintptr(cArray) |
| | | |
| | | for i := 0; i < count; i++ { |
| | | j := *(*CRECT)(unsafe.Pointer(p)) |
| | | goArray = append(goArray, j) |
| | | p += unsafe.Sizeof(j) |
| | | } |
| | | return |
| | | } |
| | | |
| | | // CFaceInfoArrayToGoArray convert cFaceInfo array to go |
| | | func CFaceInfoArrayToGoArray(cArray unsafe.Pointer, count int) (goArray []CFaceInfo) { |
| | | p := uintptr(cArray) |
| | | |
| | | for i := 0; i < count; i++ { |
| | | j := *(*CFaceInfo)(unsafe.Pointer(p)) |
| | | goArray = append(goArray, j) |
| | | p += unsafe.Sizeof(j) |
| | | } |
| | | return |
| | | } |
New file |
| | |
| | | // +build ignore |
| | | |
| | | package gosdk |
| | | |
| | | //go:generate go tool cgo -godefs cgodefs.go |
| | | |
| | | /* |
| | | #include "csdk_struct.h" |
| | | */ |
| | | import "C" |
| | | |
| | | type CPOINT C.cPOINT |
| | | type CRECT C.cRECT |
| | | type CIMAGE C.cIMAGE |
| | | type CFaceAngle C.cFaceAngle |
| | | type CThftResult C.cThftResult |
| | | type CFacePos C.cFacePos |
| | | type CFaceInfo C.cFaceInfo |
| | | type CObjInfo C.cObjInfo |
New file |
| | |
| | | #ifdef __cplusplus |
| | | extern "C"{ |
| | | #endif |
| | | |
| | | #include "csdk.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_); |
| | | } |
| | | |
| | | 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_); |
| | | } |
| | | |
| | | 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_); |
| | | } |
| | | |
| | | void c_api_release(){ |
| | | for(auto &i : dtors_){ |
| | | i(); |
| | | } |
| | | } |
| | | |
| | | //////////////////////////////////////////////// |
| | | |
| | | 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); |
| | | } |
| | | |
| | | 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); |
| | | } |
| | | |
| | | 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); |
| | | } |
| | | |
| | | 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); |
| | | } |
| | | |
| | | 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); |
| | | } |
| | | |
| | | |
| | | /// 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){ |
| | | |
| | | const cIMAGE img{data, w, h, 3}; |
| | | return yolo_detect(handle, objCount, &img, thrsh, use_means); |
| | | } |
| | | |
| | | const char* c_api_yolo_obj_name(const int typ){ |
| | | return yolo_obj_name_by_type(typ); |
| | | } |
New file |
| | |
| | | #ifndef _c_wrapper_sdk_h_ |
| | | #define _c_wrapper_sdk_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); |
| | | |
| | | YoloHandle c_api_yolo_init( |
| | | const char *fcfg, const char *fweights, const char *fname, |
| | | const int gpu_index); |
| | | |
| | | 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); |
| | | |
| | | /// 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); |
| | | const char* c_api_yolo_obj_name(const int typ); |
| | | |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | | #endif |
| | | |
| | | |
| | | #endif |
New file |
| | |
| | | #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] |
| | | int race; //[1-white,2-yellow,3-black] |
| | | int beauty_level;//range[0-100] |
| | | int smile_level;//range[0-100] |
| | | } cThftResult; |
| | | |
| | | typedef struct _cFacePos { |
| | | cRECT rcFace; |
| | | cPOINT ptLeftEye; |
| | | cPOINT ptRightEye; |
| | | cPOINT ptMouth; |
| | | cPOINT ptNose; |
| | | cFaceAngle fAngle; |
| | | int nQuality; |
| | | |
| | | unsigned char pFacialData[512]; |
| | | } cFacePos; |
| | | |
| | | typedef struct _cFaceInfo{ |
| | | cRECT rcFace; |
| | | cPOINT ptLeftEye; |
| | | cPOINT ptRightEye; |
| | | cPOINT ptMouth; |
| | | cPOINT ptNose; |
| | | cFaceAngle fAngle; |
| | | int nQuality; |
| | | |
| | | unsigned char pFacialData[8*1024]; |
| | | long nFaceID;//face tracking id |
| | | } cFaceInfo; |
| | | |
| | | typedef struct _cObjInfo |
| | | { |
| | | cRECT rcObj; |
| | | int typ; |
| | | float prob; |
| | | } cObjInfo; |
| | | |
| | | #endif |
New file |
| | |
| | | #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" |
| | | |
| | | #endif |
New file |
| | |
| | | #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 |
New file |
| | |
| | | #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 |
New file |
| | |
| | | #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 |
New file |
| | |
| | | #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); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | #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 |
New file |
| | |
| | | #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; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | #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 |
New file |
| | |
| | | #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; |
| | | |
| | | auto nNum = THFT_Create(tm, ¶m); |
| | | if(nNum != tm){ |
| | | printf("create face detector failed!\n"); |
| | | }else{ |
| | | vec.emplace_back([]{THFI_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; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | #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); |
| | | } |
| | | #endif |
New file |
| | |
| | | #include "detector.h" |
| | | |
| | | #include <stdlib.h> |
| | | #include <fstream> |
| | | |
| | | #include <sys/time.h> |
| | | |
| | | #include "csdk_struct.h" |
| | | |
| | | #include "yolo.hpp" |
| | | |
| | | namespace csdk_wrap{ |
| | | |
| | | static std::vector<std::string> names; |
| | | |
| | | static void 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()); |
| | | } |
| | | |
| | | void* init_yolo_detector(const char *cfg, const char *weights, const char *name, |
| | | const int gpu_index, VecFunc &vec){ |
| | | |
| | | 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, gpu_index); |
| | | vec.emplace_back([det]{delete det;}); |
| | | |
| | | return det; |
| | | } |
| | | |
| | | image_t* 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; |
| | | image_t *img = new image_t; |
| | | img->h = h; |
| | | img->w = w; |
| | | img->c = color_channel; |
| | | img->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; ){ |
| | | img->data[count] = |
| | | img->data[w*h + count] = |
| | | img->data[w*h*2 + count] = |
| | | (float)(srcData[count])/255.0; |
| | | |
| | | ++count; |
| | | } |
| | | break; |
| | | } |
| | | case 3:{ |
| | | float* desData = img->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 img; |
| | | } |
| | | |
| | | cObjInfo* yolo_detect(void *handle,int *objCount, const cIMAGE *img, const float thrsh, const bool use_mean){ |
| | | Detector *det = (Detector*)handle; |
| | | |
| | | const int color_channel = img->channel; |
| | | image_t* im = buffer_to_image(img->data, img->width, img->height, color_channel); |
| | | |
| | | // struct timeval b,e; |
| | | // gettimeofday(&b, NULL); |
| | | |
| | | std::vector<bbox_t> result_vec = det->detect(*im, thrsh, use_mean); |
| | | det->free_image(*im); |
| | | delete im; |
| | | |
| | | // gettimeofday(&e,NULL); |
| | | // double t = e.tv_sec*1000.0 + e.tv_usec/1000.0 - b.tv_sec*1000.0-b.tv_usec/1000.0; |
| | | // printf("lib yolo detect use time %f ms\n", t); |
| | | |
| | | cObjInfo *infos = NULL; |
| | | if(!result_vec.empty()){ |
| | | infos = (cObjInfo*)malloc(result_vec.size() * 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; |
| | | |
| | | infos[count++] = info; |
| | | } |
| | | |
| | | *objCount = count; |
| | | |
| | | return infos; |
| | | } |
| | | |
| | | const char* yolo_obj_name_by_type(const int typ){ |
| | | if(names.empty() || typ < 0 || typ >= names.size()) return NULL; |
| | | return names.at(typ).c_str(); |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | #ifndef _c_wrapper_yolo_detector_h_ |
| | | #define _c_wrapper_yolo_detector_h_ |
| | | |
| | | #include "../base.hpp" |
| | | |
| | | struct _cObjInfo; |
| | | struct _cIMAGE; |
| | | |
| | | struct image_t; |
| | | |
| | | |
| | | namespace csdk_wrap{ |
| | | void* init_yolo_detector(const char *cfg, const char *weights, const char *name, |
| | | const int gpu_index, VecFunc &vec); |
| | | image_t* buffer_to_image(const unsigned char *data, const int w, const int h, const int color_channel); |
| | | cObjInfo* yolo_detect(void *handle,int *objCount, const cIMAGE *img, const float thrsh, const bool use_mean); |
| | | |
| | | const char* yolo_obj_name_by_type(const int typ); |
| | | } |
| | | |
| | | #endif |
New file |
| | |
| | | // Code generated by cmd/cgo -godefs; DO NOT EDIT. |
| | | // cgo -godefs cgodefs.go |
| | | |
| | | package gosdk |
| | | |
| | | type CPOINT struct { |
| | | X int32 |
| | | Y int32 |
| | | } |
| | | type CRECT struct { |
| | | Left int32 |
| | | Top int32 |
| | | Right int32 |
| | | Bottom int32 |
| | | } |
| | | type CIMAGE struct { |
| | | Data *uint8 |
| | | Width int32 |
| | | Height int32 |
| | | Channel int32 |
| | | Pad_cgo_0 [4]byte |
| | | } |
| | | type CFaceAngle struct { |
| | | Yaw int32 |
| | | Pitch int32 |
| | | Roll int32 |
| | | Confidence float32 |
| | | } |
| | | type CThftResult struct { |
| | | Gender int32 |
| | | Age int32 |
| | | Race int32 |
| | | Beauty_level int32 |
| | | Smile_level int32 |
| | | } |
| | | type CFacePos struct { |
| | | RcFace CRECT |
| | | PtLeftEye CPOINT |
| | | PtRightEye CPOINT |
| | | PtMouth CPOINT |
| | | PtNose CPOINT |
| | | FAngle CFaceAngle |
| | | NQuality int32 |
| | | PFacialData [512]uint8 |
| | | } |
| | | type CFaceInfo struct { |
| | | RcFace CRECT |
| | | PtLeftEye CPOINT |
| | | PtRightEye CPOINT |
| | | PtMouth CPOINT |
| | | PtNose CPOINT |
| | | FAngle CFaceAngle |
| | | NQuality int32 |
| | | PFacialData [8192]uint8 |
| | | NFaceID int64 |
| | | } |
| | | type CObjInfo struct { |
| | | RcObj CRECT |
| | | Typ int32 |
| | | Prob float32 |
| | | } |
New file |
| | |
| | | package gosdk |
| | | |
| | | /* |
| | | #cgo CFLAGS: -I. -I./sdk/face/include -I./sdk/darknet/include -I/usr/local/cuda/include -w -g |
| | | #cgo CXXFLAGS: -I. -I./sdk/face/include -I./sdk/darknet/include -I/usr/local/cuda/include -w -g -std=c++11 |
| | | #cgo LDFLAGS: -L/usr/local/cuda/lib64 -L${SRCDIR}/sdk/face/lib/gpu -L${SRCDIR}/sdk/darknet/lib |
| | | #cgo LDFLAGS: -Wl,-rpath,${SRCDIR}/sdk/face/lib/gpu:${SRCDIR}/sdk/darknet/lib |
| | | #cgo LDFLAGS: -ldarknet -lTHFaceImage -lTHFeature -lTHFaceProperty -lTHFaceTracking -lcudart -lcublas -lcurand -lrt -ldl -lpthread |
| | | #include <stdlib.h> |
| | | #include "csdk.h" |
| | | */ |
| | | import "C" |
| | | import ( |
| | | "unsafe" |
| | | ) |
| | | |
| | | // YoloHandle wrap C |
| | | type YoloHandle struct { |
| | | handle C.YoloHandle |
| | | } |
| | | |
| | | // SDKImage sdk image |
| | | type SDKImage struct { |
| | | Data []byte |
| | | Width int |
| | | Height int |
| | | } |
| | | |
| | | // InitYolo init yolo sdk |
| | | func InitYolo(fc, fw, fn string, gi int) *YoloHandle { |
| | | |
| | | c := C.CString(fc) |
| | | defer C.free(unsafe.Pointer(c)) |
| | | w := C.CString(fw) |
| | | defer C.free(unsafe.Pointer(w)) |
| | | n := C.CString(fn) |
| | | defer C.free(unsafe.Pointer(n)) |
| | | |
| | | g := C.int(gi) |
| | | |
| | | p := C.c_api_yolo_init(c, w, n, g) |
| | | return &YoloHandle{p} |
| | | } |
| | | |
| | | // InitFaceDetector init face detector |
| | | func InitFaceDetector(tm, gi, minFaces, rollAngle int) { |
| | | |
| | | C.c_api_face_detector_init(C.int(tm), C.int(gi), C.int(minFaces), C.int(rollAngle)) |
| | | } |
| | | |
| | | // InitFaceProperty init face property |
| | | func InitFaceProperty(tm int) { |
| | | |
| | | C.c_api_face_property_init(C.int(tm)) |
| | | } |
| | | |
| | | // InitFaceExtractor init face extractor |
| | | func InitFaceExtractor(tm, gi int) { |
| | | C.c_api_face_extractor_init(C.int(tm), C.int(gi)) |
| | | } |
| | | |
| | | // InitFaceTracker init face tracker |
| | | func InitFaceTracker(tm, gi, w, h, maxFaces, interval, sample int) { |
| | | |
| | | C.c_api_face_tracker_init(C.int(tm), C.int(gi), C.int(w), C.int(h), C.int(maxFaces), C.int(interval), C.int(sample)) |
| | | } |
| | | |
| | | // Free free sdk |
| | | func Free() { |
| | | C.c_api_release() |
| | | } |
| | | |
| | | // FaceDetect face detect |
| | | func FaceDetect(img SDKImage, ch int) []CFacePos { |
| | | |
| | | data := img.Data |
| | | w := img.Width |
| | | h := img.Height |
| | | |
| | | 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 |
| | | } |
| | | |
| | | // FaceProperty face property |
| | | func FaceProperty(fpos CFacePos, img SDKImage, ch int) CThftResult { |
| | | data := img.Data |
| | | w := img.Width |
| | | h := img.Height |
| | | |
| | | 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)) |
| | | |
| | | return *((*CThftResult)(unsafe.Pointer(&result))) |
| | | } |
| | | |
| | | // FaceExtract face extract feature |
| | | func FaceExtract(fpos CFacePos, img SDKImage, ch int) []byte { |
| | | |
| | | data := img.Data |
| | | w := img.Width |
| | | h := img.Height |
| | | |
| | | 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)) |
| | | defer C.free(unsafe.Pointer(p)) |
| | | b := C.GoBytes(unsafe.Pointer(p), featLen) |
| | | return b |
| | | } |
| | | |
| | | // FaceCompare face compare |
| | | 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 |
| | | type FaceTrackingInfo struct { |
| | | tracking bool |
| | | faces []CFaceInfo |
| | | } |
| | | |
| | | // FaceTrack face tracking info |
| | | func FaceTrack(res map[int64]FaceTrackingInfo, img SDKImage, ch int) { |
| | | data := img.Data |
| | | w := img.Width |
| | | h := img.Height |
| | | |
| | | 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)) |
| | | if cFinfo == nil { |
| | | return |
| | | } |
| | | defer C.free(unsafe.Pointer(cFinfo)) |
| | | goFinfo := CFaceInfoArrayToGoArray(unsafe.Pointer(cFinfo), int(fCount)) |
| | | |
| | | // 空,添加 |
| | | if len(res) == 0 { |
| | | for _, v := range goFinfo { |
| | | var faces []CFaceInfo |
| | | faces = append(faces, v) |
| | | tInfo := FaceTrackingInfo{true, faces} |
| | | res[v.NFaceID] = tInfo |
| | | } |
| | | // 非空 |
| | | } else { |
| | | // 默认所有faces没有tracking |
| | | for _, v := range res { |
| | | v.tracking = false |
| | | } |
| | | // 查找是否存在tracking |
| | | for _, v := range goFinfo { |
| | | // 存在已有信息 |
| | | if info, ok := res[v.NFaceID]; ok { |
| | | // tracking到face |
| | | info.tracking = true |
| | | // 如果tracking长度大于100,删除一些 |
| | | if len(info.faces) > 100 { |
| | | info.faces = info.faces[1:] |
| | | } |
| | | info.faces = append(info.faces, v) |
| | | // 不存在,新face,加入 |
| | | } else { |
| | | var faces []CFaceInfo |
| | | faces = append(faces, v) |
| | | tInfo := FaceTrackingInfo{true, faces} |
| | | res[v.NFaceID] = tInfo |
| | | } |
| | | } |
| | | // 删除不再tracking的faces |
| | | for k, v := range res { |
| | | if !v.tracking { |
| | | delete(res, k) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // YoloDetect yolo detect |
| | | func YoloDetect(handle *YoloHandle, img SDKImage, thrsh float32, umns int) []CObjInfo { |
| | | |
| | | data := img.Data |
| | | w := img.Width |
| | | h := img.Height |
| | | |
| | | var count C.int |
| | | |
| | | 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 |
| | | } |
| | | |
| | | // YoloObjName obj name by type |
| | | func YoloObjName(typ int) string { |
| | | p := C.c_api_yolo_obj_name(C.int(typ)) |
| | | |
| | | return C.GoString(p) |
| | | } |
New file |
| | |
| | | #ifndef DARKNET_API |
| | | #define DARKNET_API |
| | | #include <stdlib.h> |
| | | #include <stdio.h> |
| | | #include <string.h> |
| | | #include <pthread.h> |
| | | |
| | | #define SECRET_NUM -1234 |
| | | extern int gpu_index; |
| | | |
| | | #ifdef GPU |
| | | #define BLOCK 512 |
| | | |
| | | #include "cuda_runtime.h" |
| | | #include "curand.h" |
| | | #include "cublas_v2.h" |
| | | |
| | | #ifdef CUDNN |
| | | #include "cudnn.h" |
| | | #endif |
| | | #endif |
| | | |
| | | #ifndef __cplusplus |
| | | #ifdef OPENCV |
| | | #include "opencv2/highgui/highgui_c.h" |
| | | #include "opencv2/imgproc/imgproc_c.h" |
| | | #include "opencv2/core/version.hpp" |
| | | #if CV_MAJOR_VERSION == 3 |
| | | #include "opencv2/videoio/videoio_c.h" |
| | | #include "opencv2/imgcodecs/imgcodecs_c.h" |
| | | #endif |
| | | #endif |
| | | #endif |
| | | |
| | | typedef struct{ |
| | | int classes; |
| | | char **names; |
| | | } metadata; |
| | | |
| | | metadata get_metadata(char *file); |
| | | |
| | | typedef struct{ |
| | | int *leaf; |
| | | int n; |
| | | int *parent; |
| | | int *child; |
| | | int *group; |
| | | char **name; |
| | | |
| | | int groups; |
| | | int *group_size; |
| | | int *group_offset; |
| | | } tree; |
| | | tree *read_tree(char *filename); |
| | | |
| | | typedef enum{ |
| | | LOGISTIC, RELU, RELIE, LINEAR, RAMP, TANH, PLSE, LEAKY, ELU, LOGGY, STAIR, HARDTAN, LHTAN |
| | | } ACTIVATION; |
| | | |
| | | typedef enum{ |
| | | MULT, ADD, SUB, DIV |
| | | } BINARY_ACTIVATION; |
| | | |
| | | typedef enum { |
| | | CONVOLUTIONAL, |
| | | DECONVOLUTIONAL, |
| | | CONNECTED, |
| | | MAXPOOL, |
| | | SOFTMAX, |
| | | DETECTION, |
| | | DROPOUT, |
| | | CROP, |
| | | ROUTE, |
| | | COST, |
| | | NORMALIZATION, |
| | | AVGPOOL, |
| | | LOCAL, |
| | | SHORTCUT, |
| | | ACTIVE, |
| | | RNN, |
| | | GRU, |
| | | LSTM, |
| | | CRNN, |
| | | BATCHNORM, |
| | | NETWORK, |
| | | XNOR, |
| | | REGION, |
| | | YOLO, |
| | | REORG, |
| | | UPSAMPLE, |
| | | LOGXENT, |
| | | L2NORM, |
| | | BLANK |
| | | } LAYER_TYPE; |
| | | |
| | | typedef enum{ |
| | | SSE, MASKED, L1, SEG, SMOOTH,WGAN |
| | | } COST_TYPE; |
| | | |
| | | typedef struct{ |
| | | int batch; |
| | | float learning_rate; |
| | | float momentum; |
| | | float decay; |
| | | int adam; |
| | | float B1; |
| | | float B2; |
| | | float eps; |
| | | int t; |
| | | } update_args; |
| | | |
| | | struct network; |
| | | typedef struct network network; |
| | | |
| | | struct layer; |
| | | typedef struct layer layer; |
| | | |
| | | struct layer{ |
| | | LAYER_TYPE type; |
| | | ACTIVATION activation; |
| | | COST_TYPE cost_type; |
| | | void (*forward) (struct layer, struct network); |
| | | void (*backward) (struct layer, struct network); |
| | | void (*update) (struct layer, update_args); |
| | | void (*forward_gpu) (struct layer, struct network); |
| | | void (*backward_gpu) (struct layer, struct network); |
| | | void (*update_gpu) (struct layer, update_args); |
| | | int batch_normalize; |
| | | int shortcut; |
| | | int batch; |
| | | int forced; |
| | | int flipped; |
| | | int inputs; |
| | | int outputs; |
| | | int nweights; |
| | | int nbiases; |
| | | int extra; |
| | | int truths; |
| | | int h,w,c; |
| | | int out_h, out_w, out_c; |
| | | int n; |
| | | int max_boxes; |
| | | int groups; |
| | | int size; |
| | | int side; |
| | | int stride; |
| | | int reverse; |
| | | int flatten; |
| | | int spatial; |
| | | int pad; |
| | | int sqrt; |
| | | int flip; |
| | | int index; |
| | | int binary; |
| | | int xnor; |
| | | int steps; |
| | | int hidden; |
| | | int truth; |
| | | float smooth; |
| | | float dot; |
| | | float angle; |
| | | float jitter; |
| | | float saturation; |
| | | float exposure; |
| | | float shift; |
| | | float ratio; |
| | | float learning_rate_scale; |
| | | float clip; |
| | | int softmax; |
| | | int classes; |
| | | int coords; |
| | | int background; |
| | | int rescore; |
| | | int objectness; |
| | | int joint; |
| | | int noadjust; |
| | | int reorg; |
| | | int log; |
| | | int tanh; |
| | | int *mask; |
| | | int total; |
| | | |
| | | float alpha; |
| | | float beta; |
| | | float kappa; |
| | | |
| | | float coord_scale; |
| | | float object_scale; |
| | | float noobject_scale; |
| | | float mask_scale; |
| | | float class_scale; |
| | | int bias_match; |
| | | int random; |
| | | float ignore_thresh; |
| | | float truth_thresh; |
| | | float thresh; |
| | | float focus; |
| | | int classfix; |
| | | int absolute; |
| | | |
| | | int onlyforward; |
| | | int stopbackward; |
| | | int dontload; |
| | | int dontsave; |
| | | int dontloadscales; |
| | | |
| | | float temperature; |
| | | float probability; |
| | | float scale; |
| | | |
| | | char * cweights; |
| | | int * indexes; |
| | | int * input_layers; |
| | | int * input_sizes; |
| | | int * map; |
| | | float * rand; |
| | | float * cost; |
| | | float * state; |
| | | float * prev_state; |
| | | float * forgot_state; |
| | | float * forgot_delta; |
| | | float * state_delta; |
| | | float * combine_cpu; |
| | | float * combine_delta_cpu; |
| | | |
| | | float * concat; |
| | | float * concat_delta; |
| | | |
| | | float * binary_weights; |
| | | |
| | | float * biases; |
| | | float * bias_updates; |
| | | |
| | | float * scales; |
| | | float * scale_updates; |
| | | |
| | | float * weights; |
| | | float * weight_updates; |
| | | |
| | | float * delta; |
| | | float * output; |
| | | float * loss; |
| | | float * squared; |
| | | float * norms; |
| | | |
| | | float * spatial_mean; |
| | | float * mean; |
| | | float * variance; |
| | | |
| | | float * mean_delta; |
| | | float * variance_delta; |
| | | |
| | | float * rolling_mean; |
| | | float * rolling_variance; |
| | | |
| | | float * x; |
| | | float * x_norm; |
| | | |
| | | float * m; |
| | | float * v; |
| | | |
| | | float * bias_m; |
| | | float * bias_v; |
| | | float * scale_m; |
| | | float * scale_v; |
| | | |
| | | |
| | | float *z_cpu; |
| | | float *r_cpu; |
| | | float *h_cpu; |
| | | float * prev_state_cpu; |
| | | |
| | | float *temp_cpu; |
| | | float *temp2_cpu; |
| | | float *temp3_cpu; |
| | | |
| | | float *dh_cpu; |
| | | float *hh_cpu; |
| | | float *prev_cell_cpu; |
| | | float *cell_cpu; |
| | | float *f_cpu; |
| | | float *i_cpu; |
| | | float *g_cpu; |
| | | float *o_cpu; |
| | | float *c_cpu; |
| | | float *dc_cpu; |
| | | |
| | | float * binary_input; |
| | | |
| | | struct layer *input_layer; |
| | | struct layer *self_layer; |
| | | struct layer *output_layer; |
| | | |
| | | struct layer *reset_layer; |
| | | struct layer *update_layer; |
| | | struct layer *state_layer; |
| | | |
| | | struct layer *input_gate_layer; |
| | | struct layer *state_gate_layer; |
| | | struct layer *input_save_layer; |
| | | struct layer *state_save_layer; |
| | | struct layer *input_state_layer; |
| | | struct layer *state_state_layer; |
| | | |
| | | struct layer *input_z_layer; |
| | | struct layer *state_z_layer; |
| | | |
| | | struct layer *input_r_layer; |
| | | struct layer *state_r_layer; |
| | | |
| | | struct layer *input_h_layer; |
| | | struct layer *state_h_layer; |
| | | |
| | | struct layer *wz; |
| | | struct layer *uz; |
| | | struct layer *wr; |
| | | struct layer *ur; |
| | | struct layer *wh; |
| | | struct layer *uh; |
| | | struct layer *uo; |
| | | struct layer *wo; |
| | | struct layer *uf; |
| | | struct layer *wf; |
| | | struct layer *ui; |
| | | struct layer *wi; |
| | | struct layer *ug; |
| | | struct layer *wg; |
| | | |
| | | tree *softmax_tree; |
| | | |
| | | size_t workspace_size; |
| | | |
| | | #ifdef GPU |
| | | int *indexes_gpu; |
| | | |
| | | float *z_gpu; |
| | | float *r_gpu; |
| | | float *h_gpu; |
| | | |
| | | float *temp_gpu; |
| | | float *temp2_gpu; |
| | | float *temp3_gpu; |
| | | |
| | | float *dh_gpu; |
| | | float *hh_gpu; |
| | | float *prev_cell_gpu; |
| | | float *cell_gpu; |
| | | float *f_gpu; |
| | | float *i_gpu; |
| | | float *g_gpu; |
| | | float *o_gpu; |
| | | float *c_gpu; |
| | | float *dc_gpu; |
| | | |
| | | float *m_gpu; |
| | | float *v_gpu; |
| | | float *bias_m_gpu; |
| | | float *scale_m_gpu; |
| | | float *bias_v_gpu; |
| | | float *scale_v_gpu; |
| | | |
| | | float * combine_gpu; |
| | | float * combine_delta_gpu; |
| | | |
| | | float * prev_state_gpu; |
| | | float * forgot_state_gpu; |
| | | float * forgot_delta_gpu; |
| | | float * state_gpu; |
| | | float * state_delta_gpu; |
| | | float * gate_gpu; |
| | | float * gate_delta_gpu; |
| | | float * save_gpu; |
| | | float * save_delta_gpu; |
| | | float * concat_gpu; |
| | | float * concat_delta_gpu; |
| | | |
| | | float * binary_input_gpu; |
| | | float * binary_weights_gpu; |
| | | |
| | | float * mean_gpu; |
| | | float * variance_gpu; |
| | | |
| | | float * rolling_mean_gpu; |
| | | float * rolling_variance_gpu; |
| | | |
| | | float * variance_delta_gpu; |
| | | float * mean_delta_gpu; |
| | | |
| | | float * x_gpu; |
| | | float * x_norm_gpu; |
| | | float * weights_gpu; |
| | | float * weight_updates_gpu; |
| | | float * weight_change_gpu; |
| | | |
| | | float * biases_gpu; |
| | | float * bias_updates_gpu; |
| | | float * bias_change_gpu; |
| | | |
| | | float * scales_gpu; |
| | | float * scale_updates_gpu; |
| | | float * scale_change_gpu; |
| | | |
| | | float * output_gpu; |
| | | float * loss_gpu; |
| | | float * delta_gpu; |
| | | float * rand_gpu; |
| | | float * squared_gpu; |
| | | float * norms_gpu; |
| | | #ifdef CUDNN |
| | | cudnnTensorDescriptor_t srcTensorDesc, dstTensorDesc; |
| | | cudnnTensorDescriptor_t dsrcTensorDesc, ddstTensorDesc; |
| | | cudnnTensorDescriptor_t normTensorDesc; |
| | | cudnnFilterDescriptor_t weightDesc; |
| | | cudnnFilterDescriptor_t dweightDesc; |
| | | cudnnConvolutionDescriptor_t convDesc; |
| | | cudnnConvolutionFwdAlgo_t fw_algo; |
| | | cudnnConvolutionBwdDataAlgo_t bd_algo; |
| | | cudnnConvolutionBwdFilterAlgo_t bf_algo; |
| | | #endif |
| | | #endif |
| | | }; |
| | | |
| | | void free_layer(layer); |
| | | |
| | | typedef enum { |
| | | CONSTANT, STEP, EXP, POLY, STEPS, SIG, RANDOM |
| | | } learning_rate_policy; |
| | | |
| | | typedef struct network{ |
| | | int n; |
| | | int batch; |
| | | size_t *seen; |
| | | int *t; |
| | | float epoch; |
| | | int subdivisions; |
| | | layer *layers; |
| | | float *output; |
| | | learning_rate_policy policy; |
| | | |
| | | float learning_rate; |
| | | float momentum; |
| | | float decay; |
| | | float gamma; |
| | | float scale; |
| | | float power; |
| | | int time_steps; |
| | | int step; |
| | | int max_batches; |
| | | float *scales; |
| | | int *steps; |
| | | int num_steps; |
| | | int burn_in; |
| | | |
| | | int adam; |
| | | float B1; |
| | | float B2; |
| | | float eps; |
| | | |
| | | int inputs; |
| | | int outputs; |
| | | int truths; |
| | | int notruth; |
| | | int h, w, c; |
| | | int max_crop; |
| | | int min_crop; |
| | | float max_ratio; |
| | | float min_ratio; |
| | | int center; |
| | | float angle; |
| | | float aspect; |
| | | float exposure; |
| | | float saturation; |
| | | float hue; |
| | | int random; |
| | | |
| | | int gpu_index; |
| | | tree *hierarchy; |
| | | |
| | | float *input; |
| | | float *truth; |
| | | float *delta; |
| | | float *workspace; |
| | | int train; |
| | | int index; |
| | | float *cost; |
| | | float clip; |
| | | |
| | | #ifdef GPU |
| | | float *input_gpu; |
| | | float *truth_gpu; |
| | | float *delta_gpu; |
| | | float *output_gpu; |
| | | #endif |
| | | |
| | | } network; |
| | | |
| | | typedef struct { |
| | | int w; |
| | | int h; |
| | | float scale; |
| | | float rad; |
| | | float dx; |
| | | float dy; |
| | | float aspect; |
| | | } augment_args; |
| | | |
| | | typedef struct { |
| | | int w; |
| | | int h; |
| | | int c; |
| | | float *data; |
| | | } image; |
| | | |
| | | typedef struct{ |
| | | float x, y, w, h; |
| | | } box; |
| | | |
| | | typedef struct detection{ |
| | | box bbox; |
| | | int classes; |
| | | float *prob; |
| | | float *mask; |
| | | float objectness; |
| | | int sort_class; |
| | | } detection; |
| | | |
| | | typedef struct matrix{ |
| | | int rows, cols; |
| | | float **vals; |
| | | } matrix; |
| | | |
| | | |
| | | typedef struct{ |
| | | int w, h; |
| | | matrix X; |
| | | matrix y; |
| | | int shallow; |
| | | int *num_boxes; |
| | | box **boxes; |
| | | } data; |
| | | |
| | | typedef enum { |
| | | CLASSIFICATION_DATA, DETECTION_DATA, CAPTCHA_DATA, REGION_DATA, IMAGE_DATA, COMPARE_DATA, WRITING_DATA, SWAG_DATA, TAG_DATA, OLD_CLASSIFICATION_DATA, STUDY_DATA, DET_DATA, SUPER_DATA, LETTERBOX_DATA, REGRESSION_DATA, SEGMENTATION_DATA, INSTANCE_DATA |
| | | } data_type; |
| | | |
| | | typedef struct load_args{ |
| | | int threads; |
| | | char **paths; |
| | | char *path; |
| | | int n; |
| | | int m; |
| | | char **labels; |
| | | int h; |
| | | int w; |
| | | int out_w; |
| | | int out_h; |
| | | int nh; |
| | | int nw; |
| | | int num_boxes; |
| | | int min, max, size; |
| | | int classes; |
| | | int background; |
| | | int scale; |
| | | int center; |
| | | int coords; |
| | | float jitter; |
| | | float angle; |
| | | float aspect; |
| | | float saturation; |
| | | float exposure; |
| | | float hue; |
| | | data *d; |
| | | image *im; |
| | | image *resized; |
| | | data_type type; |
| | | tree *hierarchy; |
| | | } load_args; |
| | | |
| | | typedef struct{ |
| | | int id; |
| | | float x,y,w,h; |
| | | float left, right, top, bottom; |
| | | } box_label; |
| | | |
| | | |
| | | void free_data(data d); |
| | | |
| | | typedef struct node{ |
| | | void *val; |
| | | struct node *next; |
| | | struct node *prev; |
| | | } node; |
| | | |
| | | typedef struct list{ |
| | | int size; |
| | | node *front; |
| | | node *back; |
| | | } list; |
| | | |
| | | #ifdef __cplusplus |
| | | extern "C" { // 告诉编译器下列代码要以C链接约定的模式进行链接 |
| | | #endif |
| | | |
| | | //#todo |
| | | network *load_network(char *cfg, char *weights, int clear); |
| | | load_args get_base_args(network *net); |
| | | |
| | | pthread_t load_data(load_args args); |
| | | list *read_data_cfg(char *filename); |
| | | list *read_cfg(char *filename); |
| | | unsigned char *read_file(char *filename); |
| | | data resize_data(data orig, int w, int h); |
| | | data *tile_data(data orig, int divs, int size); |
| | | data select_data(data *orig, int *inds); |
| | | |
| | | void forward_network(network *net); |
| | | void backward_network(network *net); |
| | | void update_network(network *net); |
| | | |
| | | |
| | | float dot_cpu(int N, float *X, int INCX, float *Y, int INCY); |
| | | void axpy_cpu(int N, float ALPHA, float *X, int INCX, float *Y, int INCY); |
| | | void copy_cpu(int N, float *X, int INCX, float *Y, int INCY); |
| | | void scal_cpu(int N, float ALPHA, float *X, int INCX); |
| | | void fill_cpu(int N, float ALPHA, float * X, int INCX); |
| | | void normalize_cpu(float *x, float *mean, float *variance, int batch, int filters, int spatial); |
| | | void softmax(float *input, int n, float temp, int stride, float *output); |
| | | |
| | | int best_3d_shift_r(image a, image b, int min, int max); |
| | | |
| | | image get_label(image **characters, char *string, int size); |
| | | void draw_label(image a, int r, int c, image label, const float *rgb); |
| | | void save_image_png(image im, const char *name); |
| | | void get_next_batch(data d, int n, int offset, float *X, float *y); |
| | | void grayscale_image_3c(image im); |
| | | void normalize_image(image p); |
| | | void matrix_to_csv(matrix m); |
| | | float train_network_sgd(network *net, data d, int n); |
| | | void rgbgr_image(image im); |
| | | data copy_data(data d); |
| | | data concat_data(data d1, data d2); |
| | | data load_cifar10_data(char *filename); |
| | | float matrix_topk_accuracy(matrix truth, matrix guess, int k); |
| | | void matrix_add_matrix(matrix from, matrix to); |
| | | void scale_matrix(matrix m, float scale); |
| | | matrix csv_to_matrix(char *filename); |
| | | float *network_accuracies(network *net, data d, int n); |
| | | float train_network_datum(network *net); |
| | | image make_random_image(int w, int h, int c); |
| | | |
| | | void denormalize_connected_layer(layer l); |
| | | void denormalize_convolutional_layer(layer l); |
| | | void statistics_connected_layer(layer l); |
| | | void rescale_weights(layer l, float scale, float trans); |
| | | void rgbgr_weights(layer l); |
| | | image *get_weights(layer l); |
| | | |
| | | void demo(char *cfgfile, char *weightfile, float thresh, int cam_index, const char *filename, char **names, int classes, int frame_skip, char *prefix, int avg, float hier_thresh, int w, int h, int fps, int fullscreen); |
| | | void get_detection_detections(layer l, int w, int h, float thresh, detection *dets); |
| | | |
| | | char *option_find_str(list *l, char *key, char *def); |
| | | int option_find_int(list *l, char *key, int def); |
| | | int option_find_int_quiet(list *l, char *key, int def); |
| | | |
| | | network *parse_network_cfg(char *filename); |
| | | void save_weights(network *net, char *filename); |
| | | void load_weights(network *net, char *filename); |
| | | void save_weights_upto(network *net, char *filename, int cutoff); |
| | | void load_weights_upto(network *net, char *filename, int start, int cutoff); |
| | | |
| | | void zero_objectness(layer l); |
| | | void get_region_detections(layer l, int w, int h, int netw, int neth, float thresh, int *map, float tree_thresh, int relative, detection *dets); |
| | | int get_yolo_detections(layer l, int w, int h, int netw, int neth, float thresh, int *map, int relative, detection *dets); |
| | | void free_network(network *net); |
| | | void set_batch_network(network *net, int b); |
| | | void set_temp_network(network *net, float t); |
| | | image load_image(char *filename, int w, int h, int c); |
| | | image load_image_color(char *filename, int w, int h); |
| | | image make_image(int w, int h, int c); |
| | | image resize_image(image im, int w, int h); |
| | | void censor_image(image im, int dx, int dy, int w, int h); |
| | | image letterbox_image(image im, int w, int h); |
| | | image crop_image(image im, int dx, int dy, int w, int h); |
| | | image center_crop_image(image im, int w, int h); |
| | | image resize_min(image im, int min); |
| | | image resize_max(image im, int max); |
| | | image threshold_image(image im, float thresh); |
| | | image mask_to_rgb(image mask); |
| | | int resize_network(network *net, int w, int h); |
| | | void free_matrix(matrix m); |
| | | void test_resize(char *filename); |
| | | void save_image(image p, const char *name); |
| | | void show_image(image p, const char *name); |
| | | image copy_image(image p); |
| | | void draw_box_width(image a, int x1, int y1, int x2, int y2, int w, float r, float g, float b); |
| | | float get_current_rate(network *net); |
| | | void composite_3d(char *f1, char *f2, char *out, int delta); |
| | | data load_data_old(char **paths, int n, int m, char **labels, int k, int w, int h); |
| | | size_t get_current_batch(network *net); |
| | | void constrain_image(image im); |
| | | image get_network_image_layer(network *net, int i); |
| | | layer get_network_output_layer(network *net); |
| | | void top_predictions(network *net, int n, int *index); |
| | | void flip_image(image a); |
| | | image float_to_image(int w, int h, int c, float *data); |
| | | void ghost_image(image source, image dest, int dx, int dy); |
| | | float network_accuracy(network *net, data d); |
| | | void random_distort_image(image im, float hue, float saturation, float exposure); |
| | | void fill_image(image m, float s); |
| | | image grayscale_image(image im); |
| | | void rotate_image_cw(image im, int times); |
| | | double what_time_is_it_now(); |
| | | image rotate_image(image m, float rad); |
| | | void visualize_network(network *net); |
| | | float box_iou(box a, box b); |
| | | data load_all_cifar10(); |
| | | box_label *read_boxes(char *filename, int *n); |
| | | box float_to_box(float *f, int stride); |
| | | void draw_detections(image im, detection *dets, int num, float thresh, char **names, image **alphabet, int classes); |
| | | |
| | | matrix network_predict_data(network *net, data test); |
| | | image **load_alphabet(); |
| | | image get_network_image(network *net); |
| | | float *network_predict(network *net, float *input); |
| | | |
| | | int network_width(network *net); |
| | | int network_height(network *net); |
| | | float *network_predict_image(network *net, image im); |
| | | void network_detect(network *net, image im, float thresh, float hier_thresh, float nms, detection *dets); |
| | | detection *get_network_boxes(network *net, int w, int h, float thresh, float hier, int *map, int relative, int *num); |
| | | void free_detections(detection *dets, int n); |
| | | |
| | | void reset_network_state(network *net, int b); |
| | | |
| | | char **get_labels(char *filename); |
| | | void do_nms_obj(detection *dets, int total, int classes, float thresh); |
| | | void do_nms_sort(detection *dets, int total, int classes, float thresh); |
| | | |
| | | matrix make_matrix(int rows, int cols); |
| | | |
| | | void free_image(image m); |
| | | float train_network(network *net, data d); |
| | | pthread_t load_data_in_thread(load_args args); |
| | | void load_data_blocking(load_args args); |
| | | list *get_paths(char *filename); |
| | | void hierarchy_predictions(float *predictions, int n, tree *hier, int only_leaves, int stride); |
| | | void change_leaves(tree *t, char *leaf_list); |
| | | |
| | | int find_int_arg(int argc, char **argv, char *arg, int def); |
| | | float find_float_arg(int argc, char **argv, char *arg, float def); |
| | | int find_arg(int argc, char* argv[], char *arg); |
| | | char *find_char_arg(int argc, char **argv, char *arg, char *def); |
| | | char *basecfg(char *cfgfile); |
| | | void find_replace(char *str, char *orig, char *rep, char *output); |
| | | void free_ptrs(void **ptrs, int n); |
| | | char *fgetl(FILE *fp); |
| | | void strip(char *s); |
| | | float sec(clock_t clocks); |
| | | void **list_to_array(list *l); |
| | | void top_k(float *a, int n, int k, int *index); |
| | | int *read_map(char *filename); |
| | | void error(const char *s); |
| | | int max_index(float *a, int n); |
| | | int max_int_index(int *a, int n); |
| | | int sample_array(float *a, int n); |
| | | int *random_index_order(int min, int max); |
| | | void free_list(list *l); |
| | | float mse_array(float *a, int n); |
| | | float variance_array(float *a, int n); |
| | | float mag_array(float *a, int n); |
| | | void scale_array(float *a, int n, float s); |
| | | float mean_array(float *a, int n); |
| | | float sum_array(float *a, int n); |
| | | void normalize_array(float *a, int n); |
| | | int *read_intlist(char *s, int *n, int d); |
| | | size_t rand_size_t(); |
| | | float rand_normal(); |
| | | float rand_uniform(float min, float max); |
| | | |
| | | #ifdef GPU |
| | | void axpy_gpu(int N, float ALPHA, float * X, int INCX, float * Y, int INCY); |
| | | void fill_gpu(int N, float ALPHA, float * X, int INCX); |
| | | void scal_gpu(int N, float ALPHA, float * X, int INCX); |
| | | void copy_gpu(int N, float * X, int INCX, float * Y, int INCY); |
| | | |
| | | void cuda_set_device(int n); |
| | | void cuda_free(float *x_gpu); |
| | | float *cuda_make_array(float *x, size_t n); |
| | | void cuda_pull_array(float *x_gpu, float *x, size_t n); |
| | | float cuda_mag_array(float *x_gpu, size_t n); |
| | | void cuda_push_array(float *x_gpu, float *x, size_t n); |
| | | |
| | | void forward_network_gpu(network *net); |
| | | void backward_network_gpu(network *net); |
| | | void update_network_gpu(network *net); |
| | | |
| | | float train_networks(network **nets, int n, data d, int interval); |
| | | void sync_nets(network **nets, int n, int interval); |
| | | void harmless_update_network_gpu(network *net); |
| | | #endif |
| | | |
| | | #ifndef __cplusplus |
| | | #ifdef OPENCV |
| | | image get_image_from_stream(CvCapture *cap); |
| | | #endif |
| | | #endif |
| | | #ifdef __cplusplus |
| | | } |
| | | #endif |
| | | |
| | | |
| | | #endif |
New file |
| | |
| | | #pragma once |
| | | #ifdef YOLODLL_EXPORTS |
| | | #if defined(_MSC_VER) |
| | | #define YOLODLL_API __declspec(dllexport) |
| | | #else |
| | | #define YOLODLL_API __attribute__((visibility("default"))) |
| | | #endif |
| | | #else |
| | | #if defined(_MSC_VER) |
| | | #define YOLODLL_API __declspec(dllimport) |
| | | #else |
| | | #define YOLODLL_API |
| | | #endif |
| | | #endif |
| | | |
| | | struct bbox_t { |
| | | unsigned int x, y, w, h; // (x,y) - top-left corner, (w, h) - width & height of bounded box |
| | | float prob; // confidence - probability that the object was found correctly |
| | | unsigned int obj_id; // class of object - from range [0, classes-1] |
| | | unsigned int track_id; // tracking id for video (0 - untracked, 1 - inf - tracked object) |
| | | unsigned int frames_counter;// counter of frames on which the object was detected |
| | | }; |
| | | |
| | | struct image_t { |
| | | int h; // height |
| | | int w; // width |
| | | int c; // number of chanels (3 - for RGB) |
| | | float *data; // pointer to the image data |
| | | }; |
| | | |
| | | #ifdef __cplusplus |
| | | #include <memory> |
| | | #include <vector> |
| | | #include <deque> |
| | | #include <algorithm> |
| | | |
| | | #ifdef OPENCV |
| | | #include <opencv2/opencv.hpp> // C++ |
| | | #include "opencv2/highgui/highgui_c.h" // C |
| | | #include "opencv2/imgproc/imgproc_c.h" // C |
| | | #endif // OPENCV |
| | | |
| | | class Detector { |
| | | std::shared_ptr<void> detector_gpu_ptr; |
| | | std::deque<std::vector<bbox_t>> prev_bbox_vec_deque; |
| | | const int cur_gpu_id; |
| | | public: |
| | | float nms = .4; |
| | | bool wait_stream; |
| | | |
| | | YOLODLL_API Detector(std::string cfg_filename, std::string weight_filename, int gpu_id = 0); |
| | | YOLODLL_API ~Detector(); |
| | | |
| | | YOLODLL_API std::vector<bbox_t> detect(std::string image_filename, float thresh = 0.2, bool use_mean = false); |
| | | YOLODLL_API std::vector<bbox_t> detect(image_t img, float thresh = 0.2, bool use_mean = false); |
| | | static YOLODLL_API image_t load_image(std::string image_filename); |
| | | static YOLODLL_API void free_image(image_t m); |
| | | YOLODLL_API int get_net_width() const; |
| | | YOLODLL_API int get_net_height() const; |
| | | |
| | | YOLODLL_API std::vector<bbox_t> tracking_id(std::vector<bbox_t> cur_bbox_vec, bool const change_history = true, |
| | | int const frames_story = 10, int const max_dist = 150); |
| | | |
| | | std::vector<bbox_t> detect_resized(image_t img, int init_w, int init_h, float thresh = 0.2, bool use_mean = false) |
| | | { |
| | | if (img.data == NULL) |
| | | throw std::runtime_error("Image is empty"); |
| | | auto detection_boxes = detect(img, thresh, use_mean); |
| | | float wk = (float)init_w / img.w, hk = (float)init_h / img.h; |
| | | for (auto &i : detection_boxes) i.x *= wk, i.w *= wk, i.y *= hk, i.h *= hk; |
| | | return detection_boxes; |
| | | } |
| | | |
| | | #ifdef OPENCV |
| | | std::vector<bbox_t> detect(cv::Mat mat, float thresh = 0.2, bool use_mean = false) |
| | | { |
| | | if(mat.data == NULL) |
| | | throw std::runtime_error("Image is empty"); |
| | | auto image_ptr = mat_to_image_resize(mat); |
| | | return detect_resized(*image_ptr, mat.cols, mat.rows, thresh, use_mean); |
| | | } |
| | | |
| | | std::shared_ptr<image_t> mat_to_image_resize(cv::Mat mat) const |
| | | { |
| | | if (mat.data == NULL) return std::shared_ptr<image_t>(NULL); |
| | | cv::Mat det_mat; |
| | | cv::resize(mat, det_mat, cv::Size(get_net_width(), get_net_height())); |
| | | return mat_to_image(det_mat); |
| | | } |
| | | |
| | | static std::shared_ptr<image_t> mat_to_image(cv::Mat img_src) |
| | | { |
| | | cv::Mat img; |
| | | cv::cvtColor(img_src, img, cv::COLOR_RGB2BGR); |
| | | std::shared_ptr<image_t> image_ptr(new image_t, [](image_t *img) { free_image(*img); delete img; }); |
| | | std::shared_ptr<IplImage> ipl_small = std::make_shared<IplImage>(img); |
| | | *image_ptr = ipl_to_image(ipl_small.get()); |
| | | return image_ptr; |
| | | } |
| | | |
| | | private: |
| | | |
| | | static image_t ipl_to_image(IplImage* src) |
| | | { |
| | | unsigned char *data = (unsigned char *)src->imageData; |
| | | int h = src->height; |
| | | int w = src->width; |
| | | int c = src->nChannels; |
| | | int step = src->widthStep; |
| | | image_t out = make_image_custom(w, h, c); |
| | | int count = 0; |
| | | |
| | | for (int k = 0; k < c; ++k) { |
| | | for (int i = 0; i < h; ++i) { |
| | | int i_step = i*step; |
| | | for (int j = 0; j < w; ++j) { |
| | | out.data[count++] = data[i_step + j*c + k] / 255.; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return out; |
| | | } |
| | | |
| | | static image_t make_empty_image(int w, int h, int c) |
| | | { |
| | | image_t out; |
| | | out.data = 0; |
| | | out.h = h; |
| | | out.w = w; |
| | | out.c = c; |
| | | return out; |
| | | } |
| | | |
| | | static image_t make_image_custom(int w, int h, int c) |
| | | { |
| | | image_t out = make_empty_image(w, h, c); |
| | | out.data = (float *)calloc(h*w*c, sizeof(float)); |
| | | return out; |
| | | } |
| | | |
| | | #endif // OPENCV |
| | | |
| | | }; |
| | | |
| | | |
| | | |
| | | #if defined(TRACK_OPTFLOW) && defined(OPENCV) && defined(GPU) |
| | | |
| | | #include <opencv2/cudaoptflow.hpp> |
| | | #include <opencv2/cudaimgproc.hpp> |
| | | #include <opencv2/cudaarithm.hpp> |
| | | #include <opencv2/core/cuda.hpp> |
| | | |
| | | class Tracker_optflow { |
| | | public: |
| | | const int gpu_count; |
| | | const int gpu_id; |
| | | const int flow_error; |
| | | |
| | | |
| | | Tracker_optflow(int _gpu_id = 0, int win_size = 9, int max_level = 3, int iterations = 8000, int _flow_error = -1) : |
| | | gpu_count(cv::cuda::getCudaEnabledDeviceCount()), gpu_id(std::min(_gpu_id, gpu_count-1)), |
| | | flow_error((_flow_error > 0)? _flow_error:(win_size*4)) |
| | | { |
| | | int const old_gpu_id = cv::cuda::getDevice(); |
| | | cv::cuda::setDevice(gpu_id); |
| | | |
| | | stream = cv::cuda::Stream(); |
| | | |
| | | sync_PyrLKOpticalFlow_gpu = cv::cuda::SparsePyrLKOpticalFlow::create(); |
| | | sync_PyrLKOpticalFlow_gpu->setWinSize(cv::Size(win_size, win_size)); // 9, 15, 21, 31 |
| | | sync_PyrLKOpticalFlow_gpu->setMaxLevel(max_level); // +- 3 pt |
| | | sync_PyrLKOpticalFlow_gpu->setNumIters(iterations); // 2000, def: 30 |
| | | |
| | | cv::cuda::setDevice(old_gpu_id); |
| | | } |
| | | |
| | | // just to avoid extra allocations |
| | | cv::cuda::GpuMat src_mat_gpu; |
| | | cv::cuda::GpuMat dst_mat_gpu, dst_grey_gpu; |
| | | cv::cuda::GpuMat prev_pts_flow_gpu, cur_pts_flow_gpu; |
| | | cv::cuda::GpuMat status_gpu, err_gpu; |
| | | |
| | | cv::cuda::GpuMat src_grey_gpu; // used in both functions |
| | | cv::Ptr<cv::cuda::SparsePyrLKOpticalFlow> sync_PyrLKOpticalFlow_gpu; |
| | | cv::cuda::Stream stream; |
| | | |
| | | std::vector<bbox_t> cur_bbox_vec; |
| | | std::vector<bool> good_bbox_vec_flags; |
| | | cv::Mat prev_pts_flow_cpu; |
| | | |
| | | void update_cur_bbox_vec(std::vector<bbox_t> _cur_bbox_vec) |
| | | { |
| | | cur_bbox_vec = _cur_bbox_vec; |
| | | good_bbox_vec_flags = std::vector<bool>(cur_bbox_vec.size(), true); |
| | | cv::Mat prev_pts, cur_pts_flow_cpu; |
| | | |
| | | for (auto &i : cur_bbox_vec) { |
| | | float x_center = (i.x + i.w / 2.0F); |
| | | float y_center = (i.y + i.h / 2.0F); |
| | | prev_pts.push_back(cv::Point2f(x_center, y_center)); |
| | | } |
| | | |
| | | if (prev_pts.rows == 0) |
| | | prev_pts_flow_cpu = cv::Mat(); |
| | | else |
| | | cv::transpose(prev_pts, prev_pts_flow_cpu); |
| | | |
| | | if (prev_pts_flow_gpu.cols < prev_pts_flow_cpu.cols) { |
| | | prev_pts_flow_gpu = cv::cuda::GpuMat(prev_pts_flow_cpu.size(), prev_pts_flow_cpu.type()); |
| | | cur_pts_flow_gpu = cv::cuda::GpuMat(prev_pts_flow_cpu.size(), prev_pts_flow_cpu.type()); |
| | | |
| | | status_gpu = cv::cuda::GpuMat(prev_pts_flow_cpu.size(), CV_8UC1); |
| | | err_gpu = cv::cuda::GpuMat(prev_pts_flow_cpu.size(), CV_32FC1); |
| | | } |
| | | |
| | | prev_pts_flow_gpu.upload(cv::Mat(prev_pts_flow_cpu), stream); |
| | | } |
| | | |
| | | |
| | | void update_tracking_flow(cv::Mat src_mat, std::vector<bbox_t> _cur_bbox_vec) |
| | | { |
| | | int const old_gpu_id = cv::cuda::getDevice(); |
| | | if (old_gpu_id != gpu_id) |
| | | cv::cuda::setDevice(gpu_id); |
| | | |
| | | if (src_mat.channels() == 3) { |
| | | if (src_mat_gpu.cols == 0) { |
| | | src_mat_gpu = cv::cuda::GpuMat(src_mat.size(), src_mat.type()); |
| | | src_grey_gpu = cv::cuda::GpuMat(src_mat.size(), CV_8UC1); |
| | | } |
| | | |
| | | update_cur_bbox_vec(_cur_bbox_vec); |
| | | |
| | | //src_grey_gpu.upload(src_mat, stream); // use BGR |
| | | src_mat_gpu.upload(src_mat, stream); |
| | | cv::cuda::cvtColor(src_mat_gpu, src_grey_gpu, CV_BGR2GRAY, 1, stream); |
| | | } |
| | | if (old_gpu_id != gpu_id) |
| | | cv::cuda::setDevice(old_gpu_id); |
| | | } |
| | | |
| | | |
| | | std::vector<bbox_t> tracking_flow(cv::Mat dst_mat, bool check_error = true) |
| | | { |
| | | if (sync_PyrLKOpticalFlow_gpu.empty()) { |
| | | std::cout << "sync_PyrLKOpticalFlow_gpu isn't initialized \n"; |
| | | return cur_bbox_vec; |
| | | } |
| | | |
| | | int const old_gpu_id = cv::cuda::getDevice(); |
| | | if(old_gpu_id != gpu_id) |
| | | cv::cuda::setDevice(gpu_id); |
| | | |
| | | if (dst_mat_gpu.cols == 0) { |
| | | dst_mat_gpu = cv::cuda::GpuMat(dst_mat.size(), dst_mat.type()); |
| | | dst_grey_gpu = cv::cuda::GpuMat(dst_mat.size(), CV_8UC1); |
| | | } |
| | | |
| | | //dst_grey_gpu.upload(dst_mat, stream); // use BGR |
| | | dst_mat_gpu.upload(dst_mat, stream); |
| | | cv::cuda::cvtColor(dst_mat_gpu, dst_grey_gpu, CV_BGR2GRAY, 1, stream); |
| | | |
| | | if (src_grey_gpu.rows != dst_grey_gpu.rows || src_grey_gpu.cols != dst_grey_gpu.cols) { |
| | | stream.waitForCompletion(); |
| | | src_grey_gpu = dst_grey_gpu.clone(); |
| | | cv::cuda::setDevice(old_gpu_id); |
| | | return cur_bbox_vec; |
| | | } |
| | | |
| | | ////sync_PyrLKOpticalFlow_gpu.sparse(src_grey_gpu, dst_grey_gpu, prev_pts_flow_gpu, cur_pts_flow_gpu, status_gpu, &err_gpu); // OpenCV 2.4.x |
| | | sync_PyrLKOpticalFlow_gpu->calc(src_grey_gpu, dst_grey_gpu, prev_pts_flow_gpu, cur_pts_flow_gpu, status_gpu, err_gpu, stream); // OpenCV 3.x |
| | | |
| | | cv::Mat cur_pts_flow_cpu; |
| | | cur_pts_flow_gpu.download(cur_pts_flow_cpu, stream); |
| | | |
| | | dst_grey_gpu.copyTo(src_grey_gpu, stream); |
| | | |
| | | cv::Mat err_cpu, status_cpu; |
| | | err_gpu.download(err_cpu, stream); |
| | | status_gpu.download(status_cpu, stream); |
| | | |
| | | stream.waitForCompletion(); |
| | | |
| | | std::vector<bbox_t> result_bbox_vec; |
| | | |
| | | if (err_cpu.cols == cur_bbox_vec.size() && status_cpu.cols == cur_bbox_vec.size()) |
| | | { |
| | | for (size_t i = 0; i < cur_bbox_vec.size(); ++i) |
| | | { |
| | | cv::Point2f cur_key_pt = cur_pts_flow_cpu.at<cv::Point2f>(0, i); |
| | | cv::Point2f prev_key_pt = prev_pts_flow_cpu.at<cv::Point2f>(0, i); |
| | | |
| | | float moved_x = cur_key_pt.x - prev_key_pt.x; |
| | | float moved_y = cur_key_pt.y - prev_key_pt.y; |
| | | |
| | | if (abs(moved_x) < 100 && abs(moved_y) < 100 && good_bbox_vec_flags[i]) |
| | | if (err_cpu.at<float>(0, i) < flow_error && status_cpu.at<unsigned char>(0, i) != 0 && |
| | | ((float)cur_bbox_vec[i].x + moved_x) > 0 && ((float)cur_bbox_vec[i].y + moved_y) > 0) |
| | | { |
| | | cur_bbox_vec[i].x += moved_x + 0.5; |
| | | cur_bbox_vec[i].y += moved_y + 0.5; |
| | | result_bbox_vec.push_back(cur_bbox_vec[i]); |
| | | } |
| | | else good_bbox_vec_flags[i] = false; |
| | | else good_bbox_vec_flags[i] = false; |
| | | |
| | | //if(!check_error && !good_bbox_vec_flags[i]) result_bbox_vec.push_back(cur_bbox_vec[i]); |
| | | } |
| | | } |
| | | |
| | | cur_pts_flow_gpu.swap(prev_pts_flow_gpu); |
| | | cur_pts_flow_cpu.copyTo(prev_pts_flow_cpu); |
| | | |
| | | if (old_gpu_id != gpu_id) |
| | | cv::cuda::setDevice(old_gpu_id); |
| | | |
| | | return result_bbox_vec; |
| | | } |
| | | |
| | | }; |
| | | |
| | | #elif defined(TRACK_OPTFLOW) && defined(OPENCV) |
| | | |
| | | //#include <opencv2/optflow.hpp> |
| | | #include <opencv2/video/tracking.hpp> |
| | | |
| | | class Tracker_optflow { |
| | | public: |
| | | const int flow_error; |
| | | |
| | | |
| | | Tracker_optflow(int win_size = 9, int max_level = 3, int iterations = 8000, int _flow_error = -1) : |
| | | flow_error((_flow_error > 0)? _flow_error:(win_size*4)) |
| | | { |
| | | sync_PyrLKOpticalFlow = cv::SparsePyrLKOpticalFlow::create(); |
| | | sync_PyrLKOpticalFlow->setWinSize(cv::Size(win_size, win_size)); // 9, 15, 21, 31 |
| | | sync_PyrLKOpticalFlow->setMaxLevel(max_level); // +- 3 pt |
| | | |
| | | } |
| | | |
| | | // just to avoid extra allocations |
| | | cv::Mat dst_grey; |
| | | cv::Mat prev_pts_flow, cur_pts_flow; |
| | | cv::Mat status, err; |
| | | |
| | | cv::Mat src_grey; // used in both functions |
| | | cv::Ptr<cv::SparsePyrLKOpticalFlow> sync_PyrLKOpticalFlow; |
| | | |
| | | std::vector<bbox_t> cur_bbox_vec; |
| | | std::vector<bool> good_bbox_vec_flags; |
| | | |
| | | void update_cur_bbox_vec(std::vector<bbox_t> _cur_bbox_vec) |
| | | { |
| | | cur_bbox_vec = _cur_bbox_vec; |
| | | good_bbox_vec_flags = std::vector<bool>(cur_bbox_vec.size(), true); |
| | | cv::Mat prev_pts, cur_pts_flow; |
| | | |
| | | for (auto &i : cur_bbox_vec) { |
| | | float x_center = (i.x + i.w / 2.0F); |
| | | float y_center = (i.y + i.h / 2.0F); |
| | | prev_pts.push_back(cv::Point2f(x_center, y_center)); |
| | | } |
| | | |
| | | if (prev_pts.rows == 0) |
| | | prev_pts_flow = cv::Mat(); |
| | | else |
| | | cv::transpose(prev_pts, prev_pts_flow); |
| | | } |
| | | |
| | | |
| | | void update_tracking_flow(cv::Mat new_src_mat, std::vector<bbox_t> _cur_bbox_vec) |
| | | { |
| | | if (new_src_mat.channels() == 3) { |
| | | |
| | | update_cur_bbox_vec(_cur_bbox_vec); |
| | | |
| | | cv::cvtColor(new_src_mat, src_grey, CV_BGR2GRAY, 1); |
| | | } |
| | | } |
| | | |
| | | |
| | | std::vector<bbox_t> tracking_flow(cv::Mat new_dst_mat, bool check_error = true) |
| | | { |
| | | if (sync_PyrLKOpticalFlow.empty()) { |
| | | std::cout << "sync_PyrLKOpticalFlow isn't initialized \n"; |
| | | return cur_bbox_vec; |
| | | } |
| | | |
| | | cv::cvtColor(new_dst_mat, dst_grey, CV_BGR2GRAY, 1); |
| | | |
| | | if (src_grey.rows != dst_grey.rows || src_grey.cols != dst_grey.cols) { |
| | | src_grey = dst_grey.clone(); |
| | | return cur_bbox_vec; |
| | | } |
| | | |
| | | if (prev_pts_flow.cols < 1) { |
| | | return cur_bbox_vec; |
| | | } |
| | | |
| | | ////sync_PyrLKOpticalFlow_gpu.sparse(src_grey_gpu, dst_grey_gpu, prev_pts_flow_gpu, cur_pts_flow_gpu, status_gpu, &err_gpu); // OpenCV 2.4.x |
| | | sync_PyrLKOpticalFlow->calc(src_grey, dst_grey, prev_pts_flow, cur_pts_flow, status, err); // OpenCV 3.x |
| | | |
| | | dst_grey.copyTo(src_grey); |
| | | |
| | | std::vector<bbox_t> result_bbox_vec; |
| | | |
| | | if (err.rows == cur_bbox_vec.size() && status.rows == cur_bbox_vec.size()) |
| | | { |
| | | for (size_t i = 0; i < cur_bbox_vec.size(); ++i) |
| | | { |
| | | cv::Point2f cur_key_pt = cur_pts_flow.at<cv::Point2f>(0, i); |
| | | cv::Point2f prev_key_pt = prev_pts_flow.at<cv::Point2f>(0, i); |
| | | |
| | | float moved_x = cur_key_pt.x - prev_key_pt.x; |
| | | float moved_y = cur_key_pt.y - prev_key_pt.y; |
| | | |
| | | if (abs(moved_x) < 100 && abs(moved_y) < 100 && good_bbox_vec_flags[i]) |
| | | if (err.at<float>(0, i) < flow_error && status.at<unsigned char>(0, i) != 0 && |
| | | ((float)cur_bbox_vec[i].x + moved_x) > 0 && ((float)cur_bbox_vec[i].y + moved_y) > 0) |
| | | { |
| | | cur_bbox_vec[i].x += moved_x + 0.5; |
| | | cur_bbox_vec[i].y += moved_y + 0.5; |
| | | result_bbox_vec.push_back(cur_bbox_vec[i]); |
| | | } |
| | | else good_bbox_vec_flags[i] = false; |
| | | else good_bbox_vec_flags[i] = false; |
| | | |
| | | //if(!check_error && !good_bbox_vec_flags[i]) result_bbox_vec.push_back(cur_bbox_vec[i]); |
| | | } |
| | | } |
| | | |
| | | prev_pts_flow = cur_pts_flow.clone(); |
| | | |
| | | return result_bbox_vec; |
| | | } |
| | | |
| | | }; |
| | | #else |
| | | |
| | | class Tracker_optflow {}; |
| | | |
| | | #endif // defined(TRACK_OPTFLOW) && defined(OPENCV) |
| | | |
| | | |
| | | #ifdef OPENCV |
| | | |
| | | static cv::Scalar obj_id_to_color(int obj_id) { |
| | | int const colors[6][3] = { { 1,0,1 },{ 0,0,1 },{ 0,1,1 },{ 0,1,0 },{ 1,1,0 },{ 1,0,0 } }; |
| | | int const offset = obj_id * 123457 % 6; |
| | | int const color_scale = 150 + (obj_id * 123457) % 100; |
| | | cv::Scalar color(colors[offset][0], colors[offset][1], colors[offset][2]); |
| | | color *= color_scale; |
| | | return color; |
| | | } |
| | | |
| | | class preview_boxes_t { |
| | | enum { frames_history = 30 }; // how long to keep the history saved |
| | | |
| | | struct preview_box_track_t { |
| | | unsigned int track_id, obj_id, last_showed_frames_ago; |
| | | bool current_detection; |
| | | bbox_t bbox; |
| | | cv::Mat mat_obj, mat_resized_obj; |
| | | preview_box_track_t() : track_id(0), obj_id(0), last_showed_frames_ago(frames_history), current_detection(false) {} |
| | | }; |
| | | std::vector<preview_box_track_t> preview_box_track_id; |
| | | size_t const preview_box_size, bottom_offset; |
| | | bool const one_off_detections; |
| | | public: |
| | | preview_boxes_t(size_t _preview_box_size = 100, size_t _bottom_offset = 100, bool _one_off_detections = false) : |
| | | preview_box_size(_preview_box_size), bottom_offset(_bottom_offset), one_off_detections(_one_off_detections) |
| | | {} |
| | | |
| | | void set(cv::Mat src_mat, std::vector<bbox_t> result_vec) |
| | | { |
| | | size_t const count_preview_boxes = src_mat.cols / preview_box_size; |
| | | if (preview_box_track_id.size() != count_preview_boxes) preview_box_track_id.resize(count_preview_boxes); |
| | | |
| | | // increment frames history |
| | | for (auto &i : preview_box_track_id) |
| | | i.last_showed_frames_ago = std::min((unsigned)frames_history, i.last_showed_frames_ago + 1); |
| | | |
| | | // occupy empty boxes |
| | | for (auto &k : result_vec) { |
| | | bool found = false; |
| | | // find the same (track_id) |
| | | for (auto &i : preview_box_track_id) { |
| | | if (i.track_id == k.track_id) { |
| | | if (!one_off_detections) i.last_showed_frames_ago = 0; // for tracked objects |
| | | found = true; |
| | | break; |
| | | } |
| | | } |
| | | if (!found) { |
| | | // find empty box |
| | | for (auto &i : preview_box_track_id) { |
| | | if (i.last_showed_frames_ago == frames_history) { |
| | | if (!one_off_detections && k.frames_counter == 0) break; // don't show if obj isn't tracked yet |
| | | i.track_id = k.track_id; |
| | | i.obj_id = k.obj_id; |
| | | i.bbox = k; |
| | | i.last_showed_frames_ago = 0; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // draw preview box (from old or current frame) |
| | | for (size_t i = 0; i < preview_box_track_id.size(); ++i) |
| | | { |
| | | // get object image |
| | | cv::Mat dst = preview_box_track_id[i].mat_resized_obj; |
| | | preview_box_track_id[i].current_detection = false; |
| | | |
| | | for (auto &k : result_vec) { |
| | | if (preview_box_track_id[i].track_id == k.track_id) { |
| | | if (one_off_detections && preview_box_track_id[i].last_showed_frames_ago > 0) { |
| | | preview_box_track_id[i].last_showed_frames_ago = frames_history; break; |
| | | } |
| | | bbox_t b = k; |
| | | cv::Rect r(b.x, b.y, b.w, b.h); |
| | | cv::Rect img_rect(cv::Point2i(0, 0), src_mat.size()); |
| | | cv::Rect rect_roi = r & img_rect; |
| | | if (rect_roi.width > 1 || rect_roi.height > 1) { |
| | | cv::Mat roi = src_mat(rect_roi); |
| | | cv::resize(roi, dst, cv::Size(preview_box_size, preview_box_size), cv::INTER_NEAREST); |
| | | preview_box_track_id[i].mat_obj = roi.clone(); |
| | | preview_box_track_id[i].mat_resized_obj = dst.clone(); |
| | | preview_box_track_id[i].current_detection = true; |
| | | preview_box_track_id[i].bbox = k; |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | void draw(cv::Mat draw_mat, bool show_small_boxes = false) |
| | | { |
| | | // draw preview box (from old or current frame) |
| | | for (size_t i = 0; i < preview_box_track_id.size(); ++i) |
| | | { |
| | | auto &prev_box = preview_box_track_id[i]; |
| | | |
| | | // draw object image |
| | | cv::Mat dst = prev_box.mat_resized_obj; |
| | | if (prev_box.last_showed_frames_ago < frames_history && |
| | | dst.size() == cv::Size(preview_box_size, preview_box_size)) |
| | | { |
| | | cv::Rect dst_rect_roi(cv::Point2i(i * preview_box_size, draw_mat.rows - bottom_offset), dst.size()); |
| | | cv::Mat dst_roi = draw_mat(dst_rect_roi); |
| | | dst.copyTo(dst_roi); |
| | | |
| | | cv::Scalar color = obj_id_to_color(prev_box.obj_id); |
| | | int thickness = (prev_box.current_detection) ? 5 : 1; |
| | | cv::rectangle(draw_mat, dst_rect_roi, color, thickness); |
| | | |
| | | unsigned int const track_id = prev_box.track_id; |
| | | std::string track_id_str = (track_id > 0) ? std::to_string(track_id) : ""; |
| | | putText(draw_mat, track_id_str, dst_rect_roi.tl() - cv::Point2i(-4, 5), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.9, cv::Scalar(0, 0, 0), 2); |
| | | |
| | | std::string size_str = std::to_string(prev_box.bbox.w) + "x" + std::to_string(prev_box.bbox.h); |
| | | putText(draw_mat, size_str, dst_rect_roi.tl() + cv::Point2i(0, 12), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, cv::Scalar(0, 0, 0), 1); |
| | | |
| | | if (!one_off_detections && prev_box.current_detection) { |
| | | cv::line(draw_mat, dst_rect_roi.tl() + cv::Point2i(preview_box_size, 0), |
| | | cv::Point2i(prev_box.bbox.x, prev_box.bbox.y + prev_box.bbox.h), |
| | | color); |
| | | } |
| | | |
| | | if (one_off_detections && show_small_boxes) { |
| | | cv::Rect src_rect_roi(cv::Point2i(prev_box.bbox.x, prev_box.bbox.y), |
| | | cv::Size(prev_box.bbox.w, prev_box.bbox.h)); |
| | | unsigned int const color_history = (255 * prev_box.last_showed_frames_ago) / frames_history; |
| | | color = cv::Scalar(255 - 3 * color_history, 255 - 2 * color_history, 255 - 1 * color_history); |
| | | if (prev_box.mat_obj.size() == src_rect_roi.size()) { |
| | | prev_box.mat_obj.copyTo(draw_mat(src_rect_roi)); |
| | | } |
| | | cv::rectangle(draw_mat, src_rect_roi, color, thickness); |
| | | putText(draw_mat, track_id_str, src_rect_roi.tl() - cv::Point2i(0, 10), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, cv::Scalar(0, 0, 0), 1); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | #endif // OPENCV |
| | | |
| | | //extern "C" { |
| | | #endif // __cplusplus |
| | | |
| | | /* |
| | | // C - wrappers |
| | | YOLODLL_API void create_detector(char const* cfg_filename, char const* weight_filename, int gpu_id); |
| | | YOLODLL_API void delete_detector(); |
| | | YOLODLL_API bbox_t* detect_custom(image_t img, float thresh, bool use_mean, int *result_size); |
| | | YOLODLL_API bbox_t* detect_resized(image_t img, int init_w, int init_h, float thresh, bool use_mean, int *result_size); |
| | | YOLODLL_API bbox_t* detect(image_t img, int *result_size); |
| | | YOLODLL_API image_t load_img(char *image_filename); |
| | | YOLODLL_API void free_img(image_t m); |
| | | |
| | | #ifdef __cplusplus |
| | | } // extern "C" |
| | | |
| | | static std::shared_ptr<void> c_detector_ptr; |
| | | static std::vector<bbox_t> c_result_vec; |
| | | |
| | | void create_detector(char const* cfg_filename, char const* weight_filename, int gpu_id) { |
| | | c_detector_ptr = std::make_shared<YOLODLL_API Detector>(cfg_filename, weight_filename, gpu_id); |
| | | } |
| | | |
| | | void delete_detector() { c_detector_ptr.reset(); } |
| | | |
| | | bbox_t* detect_custom(image_t img, float thresh, bool use_mean, int *result_size) { |
| | | c_result_vec = static_cast<Detector*>(c_detector_ptr.get())->detect(img, thresh, use_mean); |
| | | *result_size = c_result_vec.size(); |
| | | return c_result_vec.data(); |
| | | } |
| | | |
| | | bbox_t* detect_resized(image_t img, int init_w, int init_h, float thresh, bool use_mean, int *result_size) { |
| | | c_result_vec = static_cast<Detector*>(c_detector_ptr.get())->detect_resized(img, init_w, init_h, thresh, use_mean); |
| | | *result_size = c_result_vec.size(); |
| | | return c_result_vec.data(); |
| | | } |
| | | |
| | | bbox_t* detect(image_t img, int *result_size) { |
| | | return detect_custom(img, 0.24, true, result_size); |
| | | } |
| | | |
| | | image_t load_img(char *image_filename) { |
| | | return static_cast<Detector*>(c_detector_ptr.get())->load_image(image_filename); |
| | | } |
| | | void free_img(image_t m) { |
| | | static_cast<Detector*>(c_detector_ptr.get())->free_image(m); |
| | | } |
| | | |
| | | #endif // __cplusplus |
| | | */ |
New file |
| | |
| | | #ifndef _FI_STD_DEF_EX_H_ |
| | | #define _FI_STD_DEF_EX_H_ |
| | | |
| | | #ifndef WIN32 |
| | | |
| | | typedef struct tagPOINT |
| | | { |
| | | int x, y; |
| | | }POINT; |
| | | |
| | | typedef struct tagSIZE |
| | | { |
| | | int cx, cy; |
| | | }SIZE; |
| | | |
| | | typedef struct tagRECT |
| | | { |
| | | int left, top, right, bottom; |
| | | }RECT; |
| | | |
| | | typedef unsigned char BYTE; |
| | | typedef unsigned short WORD; |
| | | typedef unsigned int DWORD; |
| | | |
| | | #endif |
| | | |
| | | /* |
| | | typedef struct tagPointF { |
| | | float x; |
| | | float y; |
| | | } TPointF; |
| | | */ |
| | | #endif // _FI_STD_DEF_EX_H_ |
New file |
| | |
| | | #ifndef THFACEIMAGE_I_H |
| | | #define THFACEIMAGE_I_H |
| | | |
| | | #include "FiStdDefEx.h" |
| | | |
| | | /* |
| | | * ============================================================================ |
| | | * Name : THFaceImage_i.h |
| | | * Part of : Face Recognition (THFaceImage) SDK |
| | | * Created : 9.1.2016 by XXX |
| | | * Description: |
| | | * THFaceImage_i.h - Face Recognition (THFaceImage) SDK header file |
| | | * Version : 4.0.0 |
| | | * Copyright: All Rights Reserved by XXXX |
| | | * Revision: |
| | | * ============================================================================ |
| | | */ |
| | | |
| | | #define THFACEIMAGE_API extern "C" |
| | | |
| | | //////Struct define////// |
| | | |
| | | struct FaceAngle |
| | | { |
| | | int yaw;//angle of yaw,from -90 to +90,left is negative,right is postive |
| | | int pitch;//angle of pitch,from -90 to +90,up is negative,down is postive |
| | | int roll;//angle of roll,from -90 to +90,left is negative,right is postive |
| | | float confidence;//confidence of face pose(from 0 to 1,0.6 is suggested threshold) |
| | | }; |
| | | |
| | | struct THFI_FacePos |
| | | { |
| | | RECT rcFace;//coordinate of face |
| | | POINT ptLeftEye;//coordinate of left eye |
| | | POINT ptRightEye;//coordinate of right eye |
| | | POINT ptMouth;//coordinate of mouth |
| | | POINT ptNose;//coordinate of nose |
| | | FaceAngle fAngle;//value of face angle |
| | | int nQuality;//quality of face(from 0 to 100) |
| | | BYTE pFacialData[512];//facial data |
| | | THFI_FacePos() |
| | | { |
| | | memset(&rcFace,0,sizeof(RECT)); |
| | | memset(&ptLeftEye,0,sizeof(POINT)); |
| | | memset(&ptRightEye,0,sizeof(POINT)); |
| | | memset(&ptMouth,0,sizeof(POINT)); |
| | | memset(&ptNose,0,sizeof(POINT)); |
| | | memset(&fAngle,0,sizeof(FaceAngle)); |
| | | nQuality=0; |
| | | memset(pFacialData, 0, 512); |
| | | } |
| | | }; |
| | | |
| | | typedef long long DWORD_PTR; |
| | | struct THFI_Param |
| | | { |
| | | int nMinFaceSize;//min face width size can be detected,default is 50 pixels |
| | | int nRollAngle;//max face roll angle,default is 30(degree) |
| | | bool bOnlyDetect;//ingored |
| | | DWORD_PTR dwReserved;//reserved value,must be NULL |
| | | THFI_Param() |
| | | { |
| | | nMinFaceSize=50; |
| | | nRollAngle=30; |
| | | bOnlyDetect=false; |
| | | dwReserved=NULL; |
| | | } |
| | | }; |
| | | |
| | | struct THFI_Param_Ex |
| | | { |
| | | THFI_Param tp; |
| | | int nDeviceID;//device id for GPU device.eg:0,1,2,3..... |
| | | THFI_Param_Ex() |
| | | { |
| | | nDeviceID = 0; |
| | | } |
| | | }; |
| | | |
| | | //////API define////// |
| | | |
| | | THFACEIMAGE_API int THFI_Create(short nChannelNum,THFI_Param* pParam); |
| | | /* |
| | | The THFI_Create function will initialize the algorithm engine module |
| | | |
| | | Parameters: |
| | | nChannelNum[intput],algorithm channel num,for multi-thread mode,one thread uses one channel |
| | | pParam[input],algorithm engine parameter. |
| | | Return Values: |
| | | If the function succeeds, the return value is valid channel number. |
| | | If the function fails, the return value is zero or negative; |
| | | error code: |
| | | -99,invalid license. |
| | | Remarks: |
| | | This function only can be called one time at program initialization. |
| | | */ |
| | | |
| | | THFACEIMAGE_API int THFI_DetectFace(short nChannelID, BYTE* pImage, int bpp, int nWidth, int nHeight, THFI_FacePos* pfps, int nMaxFaceNums, int nSampleSize=640); |
| | | /* |
| | | The THFI_DetectFace function execute face detection only. |
| | | |
| | | Parameters: |
| | | nChannelID[input],channel ID(from 0 to nChannelNum-1) |
| | | pImage[input],image data buffer,RGB24 format. |
| | | bpp[input],bits per pixel(24-RGB24 image),must be 24 |
| | | nWidth[input],image width. |
| | | nHeight[input],image height. |
| | | pfps[output],the facial position information. |
| | | nMaxFaceNums[input],max face nums that you want |
| | | nSampleSize[input],down sample size(image down sample) for detect image,if it is 0,will detect by original image. |
| | | Return Values: |
| | | If the function succeeds, the return value is face number. |
| | | If the function fails, the return value is negative. |
| | | error code: |
| | | -99,invalid license. |
| | | -1,nChannelID is invalid or SDK is not initialized |
| | | -2,image data is invalid,please check function parameter:pImage,bpp,nWidth,nHeight |
| | | -3,pfps or nMaxFaceNums is invalid. |
| | | Remarks: |
| | | 1.image data buffer(pImage) size must be nWidth*(bpp/8)*nHeight. |
| | | 2.pfps must be allocated by caller,the memory size is nMaxFaceNums*sizeof(THFI_FacePos). |
| | | 3.if image has face(s),face number less than or equal to nMaxFaceNums |
| | | */ |
| | | |
| | | THFACEIMAGE_API int THFI_DetectFaceByEye(short nChannelID, BYTE* pImage, int nWidth, int nHeight, POINT ptLeft, POINT ptRight, THFI_FacePos* pfps); |
| | | /* |
| | | The THFI_DetectFaceByEye function detect facial data by eye position |
| | | |
| | | Parameters: |
| | | pImage[input],image data buffer,rgb24 format,pImage data size must be nWidth*nHeight*3 bytes |
| | | nWidth[input],image width. |
| | | nHeight[input],image height. |
| | | ptLeft[input],left eye position |
| | | ptRight[input],right eye position |
| | | pfps[output],the facial position information. |
| | | Return Values: |
| | | If the function succeeds, the return value is 1. |
| | | If the function fails, the return value is negative. |
| | | error code: |
| | | -99,invalid license. |
| | | -1,nChannelID is invalid or SDK is not initialize |
| | | -2,image data is invalid,please check function parameter:pImage,bpp,nWidth,nHeight |
| | | -3,pfps or nMaxFaceNums is invalid. |
| | | */ |
| | | |
| | | THFACEIMAGE_API void THFI_Release(); |
| | | /* |
| | | The THFI_Release function will release the algorithm engine module |
| | | |
| | | Parameters: |
| | | No parameter. |
| | | Return Values: |
| | | No return value. |
| | | Remarks: |
| | | This function only can be called one time at program exit. |
| | | */ |
| | | |
| | | THFACEIMAGE_API int THFI_Create_Ex(short nChannelNum, THFI_Param_Ex* pParam); |
| | | /* |
| | | The THFI_Create_Ex function will initialize the algorithm engine module,,only for GPU version |
| | | |
| | | Parameters: |
| | | nChannelNum[intput],algorithm channel num,for multi-thread mode,one thread uses one channel |
| | | pParam[input],algorithm engine parameter. |
| | | Return Values: |
| | | If the function succeeds, the return value is valid channel number. |
| | | If the function fails, the return value is zero or negative; |
| | | error code: |
| | | -99,invalid license. |
| | | Remarks: |
| | | This function only can be called one time at program initialization. |
| | | */ |
| | | |
| | | #endif |
New file |
| | |
| | | #ifndef THFACELIVE_I_H |
| | | #define THFACELIVE_I_H |
| | | |
| | | /* |
| | | * ============================================================================ |
| | | * Name : THFaceLive_i.h |
| | | * Part of : Face Liveness Detect (THFaceLive) SDK |
| | | * Created : 9.1.2017 by XXX |
| | | * Description: |
| | | * THFaceLive_i.h - Face Liveness Detect (THFaceLive) SDK header file |
| | | * Version : 2.0.0 |
| | | * Copyright: All Rights Reserved by XXXX |
| | | * Revision: |
| | | * ============================================================================ |
| | | */ |
| | | #include "THFaceImage_i.h" |
| | | |
| | | #define THFACELIVE_API extern "C" |
| | | |
| | | THFACELIVE_API int THFL_Create(); |
| | | /* |
| | | The THFL_Create function will initialize the algorithm engine module |
| | | |
| | | Parameters: |
| | | No parameter. |
| | | Return Values: |
| | | If the function succeeds, the return value is 1. |
| | | If the function fails, the return value is negative; |
| | | Remarks: |
| | | This function only can be called one time at program initialization. |
| | | */ |
| | | |
| | | THFACELIVE_API int THFL_Detect(unsigned char* pBuf_color, unsigned char* pBuf_bw, int nWidth, int nHeight, THFI_FacePos* ptfp_color, THFI_FacePos* ptfp_bw, int nThreshold=30); |
| | | /* |
| | | The THFL_Detect function execute face liveness detection |
| | | |
| | | Parameters: |
| | | pBuf_color[input],color camera image data buffer,bgr format. |
| | | pBuf_bw[input],black-white camera image data buffer,bgr format. |
| | | nWidth[input],image width. |
| | | nHeight[input],image height. |
| | | ptfp_color[input],face data of color camera image.(THFI_FacePos format,return by THFI_DetectFace of THFaceImage SDK) |
| | | ptfp_bw[input],face data of black-white camera image.(THFI_FacePos format,return by THFI_DetectFace of THFaceImage SDK) |
| | | nThreshold[input],score threshold(sugguest value is 30) |
| | | Return Values: |
| | | If the function succeeds, the return value is 0 or 1.(0->fake face,1->live face) |
| | | If the function fails, the return value is negative. |
| | | Remarks: |
| | | */ |
| | | THFACELIVE_API void THFL_Release(); |
| | | /* |
| | | The THFL_Release function will release the algorithm engine module |
| | | |
| | | Parameters: |
| | | No parameter. |
| | | Return Values: |
| | | No return value. |
| | | Remarks: |
| | | This function only can be called one time at program exit. |
| | | */ |
| | | |
| | | #endif |
New file |
| | |
| | | #ifndef THFACEPROP_I_H |
| | | #define THFACEPROP_I_H |
| | | |
| | | #include "THFaceImage_i.h" |
| | | |
| | | /* |
| | | * ============================================================================ |
| | | * Name : THFaceProperty_i.h |
| | | * Part of : Face Property (THFaceProperty) SDK |
| | | * Created : 7.8.2016 by XXX |
| | | * Description: |
| | | * THFaceProp_i.h - Face Property (THFaceProperty) SDK header file |
| | | * Version : 1.0.0 |
| | | * Copyright: All Rights Reserved by XXXX |
| | | * Revision: |
| | | * ============================================================================ |
| | | */ |
| | | |
| | | struct THFP_Result_V1 |
| | | { |
| | | int gender;//1-male,0-female |
| | | int age;//range[0-100] |
| | | int beauty_level;//range[0-100] |
| | | int smile_level;//range[0-100] |
| | | }; |
| | | |
| | | struct THFP_Result_V2 |
| | | { |
| | | int gender;//1-male,0-female |
| | | int age;//range[0-100] |
| | | int race; //[1-white,2-yellow,3-black] |
| | | int beauty_level;//range[0-100] |
| | | int smile_level;//range[0-100] |
| | | }; |
| | | |
| | | #define THFACEPROP_API extern "C" |
| | | |
| | | THFACEPROP_API int THFP_Create(short nChannelNum); |
| | | /* |
| | | The THFP_Create function will initialize the algorithm engine module |
| | | |
| | | Parameters: |
| | | nChannelNum[intput],algorithm channel num,for multi-thread mode,one thread uses one channel |
| | | Return Values: |
| | | If the function succeeds, the return value is valid channel number. |
| | | If the function fails, the return value is zero or negative; |
| | | error code: |
| | | -99,invalid license. |
| | | Remarks: |
| | | This function only can be called one time at program initialization. |
| | | */ |
| | | |
| | | THFACEPROP_API void THFP_Release(); |
| | | /* |
| | | The THFP_Release function will release the algorithm engine module |
| | | |
| | | Parameters: |
| | | No parameter. |
| | | Return Values: |
| | | No return value. |
| | | Remarks: |
| | | This function only can be called one time at program exit. |
| | | */ |
| | | |
| | | THFACEPROP_API int THFP_Execute_V1(short nChannelID, BYTE* pBGR, int nWidth, int nHeight, THFI_FacePos* ptfp, THFP_Result_V1* pResult); |
| | | /* |
| | | The THFP_Execute_V1 function execute face property analysis. |
| | | |
| | | Parameters: |
| | | nChannelID[input],channel ID(from 0 to nChannelNum-1) |
| | | pBGR[input],point to an image buffer,BGR format. |
| | | nWidth[input],the image width. |
| | | nHeight[input],the image height. |
| | | ptfp[input],the facial data of a face. |
| | | pResult[output],the face property result |
| | | Return Values: |
| | | If the function succeeds, the return value is 0. |
| | | If the function fails, the return value is nagative. |
| | | error code: |
| | | -99,invalid license. |
| | | -1,pBuf,ptfp,pFeature is NULL |
| | | -2,nChannelID is invalid or SDK is not initialized |
| | | Remarks: |
| | | No remark. |
| | | */ |
| | | THFACEPROP_API int THFP_Execute_1N_V1(short nChannelID, BYTE* pBGR, int nWidth, int nHeight, THFI_FacePos* ptfps, THFP_Result_V1* pResults,int nFaceCount); |
| | | /* |
| | | The THFP_Execute_1N_V1 function execute face property analysis. |
| | | |
| | | Parameters: |
| | | nChannelID[input],channel ID(from 0 to nChannelNum-1) |
| | | pBGR[input],point to an image buffer,BGR format. |
| | | nWidth[input],the image width. |
| | | nHeight[input],the image height. |
| | | ptfps[input],the facial data of muti-faces |
| | | pResults[output],the face property results of muti-faces |
| | | nFaceCount[input],the face number |
| | | Return Values: |
| | | If the function succeeds, the return value is 0. |
| | | If the function fails, the return value is nagative. |
| | | error code: |
| | | -99,invalid license. |
| | | -1,pBGR,ptfps,pResults is NULL,OR nFaceCount is less than 1 |
| | | -2,nChannelID is invalid or SDK is not initialized |
| | | Remarks: |
| | | No remark. |
| | | */ |
| | | THFACEPROP_API int THFP_Execute_V2(short nChannelID, BYTE* pBGR, int nWidth, int nHeight, THFI_FacePos* ptfp, THFP_Result_V2* pResult); |
| | | /* |
| | | The THFP_Execute_V2 function execute face property analysis. |
| | | |
| | | Parameters: |
| | | nChannelID[input],channel ID(from 0 to nChannelNum-1) |
| | | pBGR[input],point to an image buffer,BGR format. |
| | | nWidth[input],the image width. |
| | | nHeight[input],the image height. |
| | | ptfp[input],the facial data of a face. |
| | | pResult[output],the face property result |
| | | Return Values: |
| | | If the function succeeds, the return value is 0. |
| | | If the function fails, the return value is nagative. |
| | | error code: |
| | | -99,invalid license. |
| | | -1,pBGR,ptfp,pResult is NULL |
| | | -2,nChannelID is invalid or SDK is not initialized |
| | | Remarks: |
| | | No remark. |
| | | */ |
| | | |
| | | THFACEPROP_API int THFP_Execute_1N_V2(short nChannelID, BYTE* pBGR, int nWidth, int nHeight, THFI_FacePos* ptfps, THFP_Result_V2* pResults, int nFaceCount); |
| | | /* |
| | | The THFP_Execute_1N_V2 function execute face property analysis. |
| | | |
| | | Parameters: |
| | | nChannelID[input],channel ID(from 0 to nChannelNum-1) |
| | | pBGR[input],point to an image buffer,BGR format. |
| | | nWidth[input],the image width. |
| | | nHeight[input],the image height. |
| | | ptfps[input],the facial data of muti-faces |
| | | pResults[output],the face property results of muti-faces |
| | | nFaceCount[input],the face number |
| | | Return Values: |
| | | If the function succeeds, the return value is 0. |
| | | If the function fails, the return value is nagative. |
| | | error code: |
| | | -99,invalid license. |
| | | -1,pBGR,ptfps,pResults is NULL,OR nFaceCount is less than 1 |
| | | -2,nChannelID is invalid or SDK is not initialized |
| | | Remarks: |
| | | No remark. |
| | | */ |
| | | |
| | | #endif |
New file |
| | |
| | | #ifndef THFACETRACKING_I_H |
| | | #define THFACETRACKING_I_H |
| | | |
| | | #include "FiStdDefEx.h" |
| | | |
| | | /* |
| | | * ============================================================================ |
| | | * Name : THFaceTracking_i.h |
| | | * Part of : Face Tracking (THFaceTracking) SDK |
| | | * Created : 11.22.2017 by XXX |
| | | * Description: |
| | | * THFaceTracking_i.h - Face Tracking (THFaceTracking) SDK header file |
| | | * Version : 1.0.0 |
| | | * Copyright: All Rights Reserved by XXXX |
| | | * Revision: |
| | | * ============================================================================ |
| | | */ |
| | | |
| | | struct FacePose |
| | | { |
| | | int yaw;//angle of yaw,from -90 to +90,left is negative,right is postive |
| | | int pitch;//angle of pitch,from -90 to +90,up is negative,down is postive |
| | | int roll;//angle of roll,from -90 to +90,left is negative,right is postive |
| | | float confidence;//confidence of face pose(from 0 to 1,0.6 is suggested threshold) |
| | | }; |
| | | |
| | | struct THFT_FaceInfo |
| | | { |
| | | RECT rcFace;//coordinate of face |
| | | POINT ptLeftEye;//coordinate of left eye |
| | | POINT ptRightEye;//coordinate of right eye |
| | | POINT ptMouth;//coordinate of mouth |
| | | POINT ptNose;//coordinate of nose |
| | | FacePose fAngle;//value of face angle |
| | | int nQuality;//quality of face(from 0 to 100) |
| | | BYTE pFacialData[8*1024];//facial data |
| | | |
| | | long nFaceID;//face tracking id |
| | | |
| | | THFT_FaceInfo() |
| | | { |
| | | memset(&rcFace, 0, sizeof(RECT)); |
| | | memset(&ptLeftEye, 0, sizeof(POINT)); |
| | | memset(&ptRightEye, 0, sizeof(POINT)); |
| | | memset(&ptMouth, 0, sizeof(POINT)); |
| | | memset(&ptNose, 0, sizeof(POINT)); |
| | | memset(&fAngle, 0, sizeof(FacePose)); |
| | | nQuality = 0; |
| | | memset(pFacialData, 0, 8 * 1024); |
| | | |
| | | nFaceID = -1; |
| | | } |
| | | }; |
| | | |
| | | struct THFT_Param |
| | | { |
| | | int nDeviceID;//device id for GPU device.eg:0,1,2,3..... |
| | | |
| | | int nImageWidth;//image width of video |
| | | int nImageHeight;//image height of video |
| | | int nMaxFaceNum;//max face number for tracking |
| | | int nSampleSize;//down sample size for face detection |
| | | int nDetectionIntervalFrame;//interval frame number of face detection for face tracking |
| | | |
| | | THFT_Param() |
| | | { |
| | | nMaxFaceNum = 100; |
| | | nSampleSize = 640; |
| | | nDeviceID = 0; |
| | | nDetectionIntervalFrame = 5; |
| | | } |
| | | }; |
| | | |
| | | #define THFACETRACKING_API extern "C" |
| | | |
| | | |
| | | THFACETRACKING_API int THFT_Create(short nChannelNum,THFT_Param* pParam); |
| | | /* |
| | | The THFT_Create function will initialize the algorithm engine module |
| | | |
| | | Parameters: |
| | | nChannelNum[intput],algorithm channel num,for multi-thread mode,one thread uses one channel |
| | | pParam[input],algorithm engine parameter. |
| | | Return Values: |
| | | If the function succeeds, the return value is valid channel number. |
| | | If the function fails, the return value is zero or negative; |
| | | error code: |
| | | -99,invalid license. |
| | | Remarks: |
| | | This function only can be called one time at program initialization. |
| | | */ |
| | | |
| | | THFACETRACKING_API void THFT_Release(); |
| | | /* |
| | | The THFT_Release function will release the algorithm engine module |
| | | |
| | | Parameters: |
| | | No parameter. |
| | | Return Values: |
| | | No return value. |
| | | Remarks: |
| | | This function only can be called one time at program exit. |
| | | */ |
| | | |
| | | THFACETRACKING_API int THFT_FaceTracking(short nChannelID, unsigned char* pBGR,THFT_FaceInfo* pFaceInfos); |
| | | /* |
| | | The THFT_FaceTracking function execute face detection and face tracking |
| | | |
| | | Parameters: |
| | | nChannelID[input],channel ID(from 0 to nChannelNum-1) |
| | | pBGR[input],image data buffer,BGR format. |
| | | pFaceInfos[output],the facial position information. |
| | | Return Values: |
| | | If the function succeeds, the return value is face number. |
| | | If the function fails, the return value is negative. |
| | | error code: |
| | | -99,invalid license. |
| | | -1,nChannelID is invalid or SDK is not initialized |
| | | -2,image data is invalid,please check function parameter:pBGR |
| | | -3,pFaceInfos is invalid. |
| | | Remarks: |
| | | 1.image data buffer(pBGR) size must be (THFT_Param::nImageWidth * THFT_Param::nImageHeight * 3) |
| | | 2.pFaceInfos must be allocated by caller,the memory size is THFT_Param::nMaxFaceNum*sizeof(THFT_FaceInfo). |
| | | 3.if image has face(s),face number less than or equal to THFT_Param::nMaxFaceNums |
| | | */ |
| | | |
| | | THFACETRACKING_API int THFT_FaceDetect(short nChannelID, BYTE* pBGR, int nWidth, int nHeight, THFT_FaceInfo* pFaceInfos, int nMaxFaceNums, int nSampleSize); |
| | | /* |
| | | The THFT_FaceDetect function execute facial detection for an image |
| | | |
| | | Parameters: |
| | | nChannelID[input],channel ID(from 0 to nChannelNum-1) |
| | | pBGR[input],image data buffer,BGR format. |
| | | nWidth[input],image width. |
| | | nHeight[input],image height. |
| | | pFaceInfos[output],the facial position information. |
| | | nMaxFaceNums[input],max face nums that you want |
| | | nSampleSize[input],down sample size(image down sample) for detect image,if it is 0,will detect by original image. |
| | | Return Values: |
| | | If the function succeeds, the return value is face number. |
| | | If the function fails, the return value is negative. |
| | | error code: |
| | | -99,invalid license. |
| | | -1,nChannelID is invalid or SDK is not initialized |
| | | -2,image data is invalid,please check function parameter:pBGR,nWidth,nHeight |
| | | -3,pFaceInfos or nMaxFaceNums is invalid. |
| | | Remarks: |
| | | 1.image data buffer(pBGR) size must be nWidth*nHeight*3. |
| | | 2.pFaceInfos must be allocated by caller,the memory size is nMaxFaceNums*sizeof(THFT_FaceInfo). |
| | | 3.if image has face(s),face number less than or equal to nMaxFaceNums |
| | | */ |
| | | |
| | | THFACETRACKING_API int THFT_FaceOnly(short nChannelID, BYTE* pBGR, int nWidth, int nHeight, RECT* pFaces, int nMaxFaceNums, int nSampleSize); |
| | | /* |
| | | The THFT_FaceOnly function execute face rectangle detection only |
| | | |
| | | Parameters: |
| | | nChannelID[input],channel ID(from 0 to nChannelNum-1) |
| | | pBGR[input],image data buffer,BGR format. |
| | | nWidth[input],image width. |
| | | nHeight[input],image height. |
| | | pFaces[output],the face rectangle |
| | | nMaxFaceNums[input],max face nums that you want |
| | | nSampleSize[input],down sample size(image down sample) for detect image,if it is 0,will detect by original image. |
| | | Return Values: |
| | | If the function succeeds, the return value is face number. |
| | | If the function fails, the return value is negative. |
| | | error code: |
| | | -99,invalid license. |
| | | -1,nChannelID is invalid or SDK is not initialized |
| | | -2,image data is invalid,please check function parameter:pBGR,nWidth,nHeight |
| | | -3,pFaces or nMaxFaceNums is invalid. |
| | | Remarks: |
| | | 1.image data buffer(pBGR) size must be nWidth*nHeight*3. |
| | | 2.pFaces must be allocated by caller,the memory size is nMaxFaceNums*sizeof(RECT). |
| | | 3.if image has face(s),face number less than or equal to nMaxFaceNums |
| | | */ |
| | | |
| | | |
| | | #endif |
New file |
| | |
| | | #ifndef THFEATURE_I_H |
| | | #define THFEATURE_I_H |
| | | |
| | | #include "THFaceImage_i.h" |
| | | |
| | | /* |
| | | * ============================================================================ |
| | | * Name : THFeature_i.h |
| | | * Part of : Face Feature (THFeature) SDK |
| | | * Created : 10.18.2016 by xxx |
| | | * Description: |
| | | * THFeature_i.h - Face Feature(THFeature) SDK header file |
| | | * Version : 5.0.0 |
| | | * Copyright: All Rights Reserved by XXX |
| | | * Revision: |
| | | * ============================================================================ |
| | | */ |
| | | |
| | | #define THFEATURE_API extern "C" |
| | | |
| | | struct TH_Image_Data |
| | | { |
| | | BYTE* bgr;//MUST BE bgr format buffer,the size is width*height*3 bytes |
| | | int width;//image width |
| | | int height;//image height |
| | | }; |
| | | |
| | | struct EF_Param |
| | | { |
| | | int nDeviceID;//device id for GPU device.eg:0,1,2,3..... |
| | | EF_Param() |
| | | { |
| | | nDeviceID = 0; |
| | | } |
| | | }; |
| | | //////API define////// |
| | | |
| | | THFEATURE_API short EF_Init(int nChannelNum); |
| | | /* |
| | | The EF_Init function will initialize the Face Feature(THFeature) algorithm module |
| | | |
| | | Parameters: |
| | | nChannelNum,the channel number,support for muti-thread,one channel stand for one thread.max value is 32. |
| | | Return Values: |
| | | If the function succeeds, the return value is valid channel number. |
| | | If the function fails, the return value is 0 or nagative; |
| | | error code: |
| | | -99,invalid license. |
| | | -1,open file "feadb.db*" error |
| | | -2,check file "feadb.db*" error |
| | | -3,read file "feadb.db*" error |
| | | Remarks: |
| | | This function can be called one time at program initialization. |
| | | */ |
| | | |
| | | THFEATURE_API int EF_Size(); |
| | | /* |
| | | The EF_Size function will return face feature size. |
| | | |
| | | Parameters: |
| | | No parameter. |
| | | Return Values: |
| | | If the function succeeds, the return value is face feature size. |
| | | If the function fails, the return value is 0 or nagative; |
| | | error code: |
| | | -99,invalid license. |
| | | Remarks: |
| | | No remark. |
| | | */ |
| | | |
| | | THFEATURE_API int EF_Extract(short nChannelID, BYTE* pBuf, int nWidth, int nHeight, int nChannel, THFI_FacePos* ptfp, BYTE* pFeature); |
| | | /* |
| | | The EF_Extract function execute face feature extraction from one photo |
| | | |
| | | Parameters: |
| | | nChannelID[input],channel ID(from 0 to nChannelNum-1) |
| | | pBuf[input],point to an image buffer,BGR format. |
| | | nWidth[input],the image width. |
| | | nHeight[input],the image height. |
| | | nChannel[input],image buffer channel,must be 3 |
| | | ptfp[input],the facial data of a face. |
| | | pFeature[output],the face feature buffer |
| | | Return Values: |
| | | If the function succeeds, the return value is 1. |
| | | If the function fails, the return value is nagative. |
| | | error code: |
| | | -99,invalid license. |
| | | -1,pBuf,ptfp,pFeature is NULL |
| | | -2,nChannelID is invalid or SDK is not initialized |
| | | Remarks: |
| | | No remark. |
| | | */ |
| | | |
| | | THFEATURE_API int EF_Extract_M(short nChannelID, BYTE* pBuf, int nWidth, int nHeight, int nChannel, THFI_FacePos* ptfps, BYTE* pFeatures, int nFaceNum); |
| | | /* |
| | | The EF_Extract_M function execute face feature extraction for muti-faces from one photo |
| | | |
| | | Parameters: |
| | | nChannelID[input],channel ID(from 0 to nChannelNum-1) |
| | | pBuf[input],point to an image buffer,BGR format. |
| | | nWidth[input],the image width. |
| | | nHeight[input],the image height. |
| | | nChannel[input],image buffer channel,must be 3 |
| | | ptfps[input],the facial data of muti-faces |
| | | pFeatures[output],the face feature buffer for muti-faces |
| | | nFaceNum[input],the face number |
| | | Return Values: |
| | | If the function succeeds, the return value is 1. |
| | | If the function fails, the return value is 0 or nagative. |
| | | error code: |
| | | -99,invalid license. |
| | | -1,pBuf,ptfps,pFeatures is NULL |
| | | -2,nChannelID is invalid or SDK is not initialized |
| | | Remarks: |
| | | No remark. |
| | | */ |
| | | |
| | | THFEATURE_API int EF_Extracts(short nChannelID, TH_Image_Data* ptids, THFI_FacePos* ptfps, BYTE* pFeatures, int nNum); |
| | | /* |
| | | The EF_Extracts function execute face feature extraction for muti-faces from muti-photos |
| | | |
| | | Parameters: |
| | | nChannelID[input],channel ID(from 0 to nChannelNum-1) |
| | | ptids[input],the image data list of muti-photos |
| | | ptfps[input],the facial data list of muti-photos(one image data-one facial data) |
| | | pFeatures[output],the face feature buffer for muti-faces |
| | | nNum[input],the image data number |
| | | Return Values: |
| | | If the function succeeds, the return value is 1. |
| | | If the function fails, the return value is 0 or nagative. |
| | | error code: |
| | | -99,invalid license. |
| | | -1,ptids,ptfp,pFeature is NULL |
| | | -2,nChannelID is invalid or SDK is not initialized |
| | | Remarks: |
| | | No remark. |
| | | */ |
| | | |
| | | THFEATURE_API float EF_Compare(BYTE* pFeature1, BYTE* pFeature2); |
| | | /* |
| | | The EF_Compare function execute two face features compare. |
| | | |
| | | Parameters: |
| | | pFeature1[input],point to one face feature buffer. |
| | | pFeature2[input],point to another face feature buffer. |
| | | Return Values: |
| | | the return value is the two face features's similarity. |
| | | Remarks: |
| | | No remark. |
| | | */ |
| | | |
| | | THFEATURE_API void EF_Release(); |
| | | /* |
| | | The EF_Release function will release the Face Feature (THFeature) algorithm module |
| | | |
| | | Parameters: |
| | | No parameter. |
| | | Return Values: |
| | | No return value. |
| | | Remarks: |
| | | This function can be called one time at program Un-Initialization. |
| | | */ |
| | | |
| | | THFEATURE_API short EF_Init_Ex(int nChannelNum, EF_Param* pParam = NULL); |
| | | /* |
| | | The EF_Init_Ex function will initialize the Face Feature(THFeature) algorithm module,only for GPU version |
| | | |
| | | Parameters: |
| | | nChannelNum,the channel number,support for muti-thread,one channel stand for one thread.max value is 32. |
| | | pParam,initialize parameter |
| | | Return Values: |
| | | If the function succeeds, the return value is valid channel number. |
| | | If the function fails, the return value is 0 or nagative; |
| | | error code: |
| | | -99,invalid license. |
| | | -1,open file "feadb.db*" error |
| | | -2,check file "feadb.db*" error |
| | | -3,read file "feadb.db*" error |
| | | Remarks: |
| | | This function can be called one time at program initialization. |
| | | */ |
| | | |
| | | #endif |
New file |
| | |
| | | Face-SDK-CUDA-Linux64V7.0.3 和 FaceTracking-SDK-CUDA-Linux64 V1.0.0-timeout2018 的合并 |
New file |
| | |
| | | package gosdk |
| | | |
| | | import ( |
| | | "C" |
| | | ) |
| | | |
| | | // func (s *Goapi) NewAPIFaceFeature(thread_max, gpu_index int) { |
| | | // detectMinFaces := 20 |
| | | // detectRollAngle := 60 |
| | | // s.NewAPIFaceDetector(thread_max, gpu_index, detectMinFaces, detectRollAngle) |
| | | |
| | | // s.NewAPIFaceProperty(thread_max) |
| | | |
| | | // s.NewAPIFaceExtractor(thread_max, gpu_index) |
| | | // } |
| | | |
| | | // func (s *Goapi) FaceFeature(d []byte, w, h, channel int) []interface{} { |
| | | // cres := s.APIFaceDetect(d, w, h, channel) |
| | | // if cres == nil { |
| | | // return nil |
| | | // } |
| | | // gores := (*CResult)(unsafe.Pointer(cres)) |
| | | |
| | | // count := gores.Count |
| | | // // count := getResultCount(det) |
| | | |
| | | // faces := (*CFacePos)(unsafe.Pointer(gores.Data)) |
| | | // fmt.Printf("det count %d", count) |
| | | // // result := make([]FaceDetectResult, count) |
| | | |
| | | // // for i := 0; i < count; i++ { |
| | | // // ext := s.APIFaceExtract(det, i, d, w, h, channel) |
| | | // // if ext == nil { |
| | | // // continue |
| | | // // } |
| | | |
| | | // // res := FaceDetectResult{} |
| | | // // } |
| | | |
| | | // return nil |
| | | // } |