| | |
| | | |
| | | #include <fstream> |
| | | #include <vector> |
| | | #include <string> |
| | | #include <stdexcept> |
| | | |
| | | #include "struct.h" |
| | | |
| | | namespace cppyolo |
| | | { |
| | | sdkyolo::sdkyolo(const char *cfg, const char *weights, const char *name, const int gpu) |
| | | :det_(NULL) |
| | | ,infos_(NULL) |
| | | ,obj_cnt_(0) |
| | | ,image_(NULL) |
| | | ,width_(0) |
| | | ,height_(0) |
| | | ,channel_(0) |
| | | { |
| | | names_.clear(); |
| | | if (!init(cfg, weights, name, gpu)){ |
| | | throw std::runtime_error("init yolo error"); |
| | | } |
| | | } |
| | | static std::vector<std::string> names; |
| | | |
| | | sdkyolo::~sdkyolo() |
| | | { |
| | | if (det_) delete det_; |
| | | } |
| | | |
| | | static void objects_names_from_file(std::string filename, std::vector<std::string> &names){ |
| | | static void objects_names_from_file(std::string filename){ |
| | | std::ifstream file(filename); |
| | | |
| | | if (!file.is_open()){ |
| | |
| | | printf("names count %d\n", names.size()); |
| | | } |
| | | |
| | | const char* sdkyolo::obj_name_by_type(const int typ)const{ |
| | | if(names_.empty() || typ < 0 || typ >= names_.size()) return NULL; |
| | | return names_.at(typ).c_str(); |
| | | const char* obj_name_by_type(const int typ){ |
| | | if(names.empty() || typ < 0 || typ >= names.size()) return NULL; |
| | | return names.at(typ).c_str(); |
| | | } |
| | | |
| | | bool sdkyolo::init(const char *cfg, const char *weights, const char *name, const int gpu){ |
| | | if (det_) return true; |
| | | |
| | | void *init(const char *cfg, const char *weights, const char *name, const int gpu){ |
| | | if(!cfg || !weights || !name){ |
| | | printf("init Detector error\n"); |
| | | return false; |
| | | } |
| | | |
| | | if(names_.empty()) |
| | | objects_names_from_file(name, names_); |
| | | if(names.empty()) |
| | | objects_names_from_file(name); |
| | | |
| | | det_ = new Detector(cfg, weights, gpu); |
| | | return true; |
| | | return new Detector(cfg, weights, gpu); |
| | | } |
| | | |
| | | int sdkyolo::buffer_to_image(const unsigned char *data, const int w, const int h, const int color_channel){ |
| | | void release(void *handle){ |
| | | if (handle){ |
| | | Detector *d = (Detector*)handle; |
| | | delete d; |
| | | } |
| | | } |
| | | |
| | | static 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; |
| | | if (w != width_ || h != height_ || color_channel != channel_){ |
| | | if (image_){ |
| | | free(image_->data); |
| | | delete image_; |
| | | } |
| | | image_ = new image_t; |
| | | image_->h = h; |
| | | image_->w = w; |
| | | image_->c = c; |
| | | image_->data = (float*)calloc(h*w*c, sizeof(float)); |
| | | } |
| | | |
| | | image_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; |
| | | |
| | |
| | | switch(c){ |
| | | case 1:{ |
| | | for (; count < size; ){ |
| | | image_->data[count] = |
| | | image_->data[w*h + count] = |
| | | image_->data[w*h*2 + count] = |
| | | 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 = image_->data; |
| | | float* desData = img->data; |
| | | |
| | | for(int i = 0;i<size;i++){ |
| | | *(desData) = *(srcData + 2) /255.0f; |
| | |
| | | break; |
| | | } |
| | | |
| | | return 0; |
| | | return img; |
| | | } |
| | | |
| | | int sdkyolo::detect(const cIMAGE *img, const float thrsh, const bool use_mean, void **objs, int *objCount){ |
| | | if (!det_) return -1; |
| | | int detect(void *handle, const cIMAGE *img, const float thrsh, const bool use_mean, void **objs, int *objCount){ |
| | | if (!handle || !img || img->width <= 0 || img->height <= 0 || !img->data) return -1; |
| | | |
| | | Detector *d = (Detector*)handle; |
| | | |
| | | const int color_channel = img->channel; |
| | | buffer_to_image(img->data, img->width, img->height, color_channel); |
| | | |
| | | image_t *image = buffer_to_image(img->data, img->width, img->height, color_channel); |
| | | |
| | | std::vector<bbox_t> result_vec = det_->detect(*image_, thrsh, use_mean); |
| | | // det->free_image(*im); |
| | | // delete im; |
| | | std::vector<bbox_t> result_vec = d->detect(*image, thrsh, use_mean); |
| | | d->free_image(*image); |
| | | delete image; |
| | | |
| | | if (obj_cnt_ < result_vec.size()){ |
| | | free(infos_); |
| | | |
| | | obj_cnt_ = result_vec.size(); |
| | | infos_ = (cObjInfo*)malloc(obj_cnt_ * sizeof(cObjInfo)); |
| | | cObjInfo *infos = NULL; |
| | | if(!result_vec.empty()){ |
| | | infos = (cObjInfo*)malloc(result_vec.size() * sizeof(cObjInfo)); |
| | | } |
| | | |
| | | int count = 0; |
| | |
| | | info.rcObj.right = i.x+i.w; |
| | | info.rcObj.bottom = i.y+i.h; |
| | | |
| | | infos_[count++] = info; |
| | | infos[count++] = info; |
| | | } |
| | | |
| | | *objCount = count; |
| | | *objs = infos_; |
| | | *objs = infos; |
| | | |
| | | return count; |
| | | } |
| | |
| | | #ifndef _cpp_yolo_h_ |
| | | #define _cpp_yolo_h_ |
| | | |
| | | #include <vector> |
| | | #include <string> |
| | | |
| | | #include "struct.h" |
| | | |
| | | struct image_t; |
| | |
| | | |
| | | namespace cppyolo |
| | | { |
| | | class sdkyolo{ |
| | | void *init(const char *cfg, const char *weights, const char *name, const int gpu); |
| | | void release(void *handle); |
| | | |
| | | public: |
| | | sdkyolo(const char *cfg, const char *weights, const char *name, const int gpu); |
| | | ~sdkyolo(); |
| | | int detect(void *handle, const cIMAGE *img, const float thrsh, const bool use_mean, void **objs, int *objCount); |
| | | const char* obj_name_by_type(const int typ); |
| | | |
| | | public: |
| | | int detect(const cIMAGE *img, const float thrsh, const bool use_mean, void **objs, int *objCount); |
| | | const char* obj_name_by_type(const int typ)const; |
| | | private: |
| | | bool init(const char *cfg, const char *weights, const char *name, const int gpu); |
| | | int buffer_to_image(const unsigned char *data, const int w, const int h, const int color_channel); |
| | | |
| | | private: |
| | | Detector *det_; |
| | | cObjInfo *infos_; |
| | | int obj_cnt_; |
| | | std::vector<std::string> names_; |
| | | |
| | | image_t *image_; |
| | | int width_; |
| | | int height_; |
| | | int channel_; |
| | | }; |
| | | } // namespace cppyolo |
| | | |
| | | |
| | |
| | | |
| | | #include "csrc/yolo.cpp" |
| | | |
| | | using namespace cppyolo; |
| | | |
| | | void* init(const char *cfg, const char *weights, const char *name, const int gpu){ |
| | | return new sdkyolo(cfg, weights, name, gpu); |
| | | return cppyolo::init(cfg, weights, name, gpu); |
| | | } |
| | | |
| | | void release(void *handle){ |
| | | if (handle){ |
| | | sdkyolo *h = (sdkyolo*)handle; |
| | | delete h; |
| | | cppyolo::release(handle); |
| | | } |
| | | } |
| | | |
| | |
| | | const float thrsh, const int use_mean, |
| | | void **objInfos, int *objCount){ |
| | | |
| | | sdkyolo *y = (sdkyolo*)handle; |
| | | cIMAGE img{(unsigned char*)data, w, h, c}; |
| | | return y->detect(&img, thrsh, use_mean, objInfos, objCount); |
| | | return cppyolo::detect(handle, &img, thrsh, use_mean, objInfos, objCount); |
| | | } |
| | | |
| | | const char* obj_name_by_type(void *handle, const int typ){ |
| | | sdkyolo *h = (sdkyolo*)handle; |
| | | return h->obj_name_by_type(typ); |
| | | const char* obj_name_by_type(const int typ){ |
| | | |
| | | return cppyolo::obj_name_by_type(typ); |
| | | } |
| | | |
| | |
| | | const float thrsh, const int use_mean, |
| | | void **objInfos, int *objCount); |
| | | |
| | | const char* obj_name_by_type(void *handle, const int typ); |
| | | const char* obj_name_by_type(const int typ); |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | |
| | | // Free free |
| | | func Free(i interface{}) { |
| | | y := i.(*YoloHandle) |
| | | if y != nil { |
| | | if y.handle != nil { |
| | | C.release(y.handle) |
| | | } |
| | | if y != nil && y.handle != nil { |
| | | C.release(y.handle) |
| | | } |
| | | } |
| | | |
| | |
| | | &cobjinfo, &count) |
| | | |
| | | if ret == 0 { |
| | | defer C.free(cobjinfo) |
| | | return CYoloObjInfoArrayToGoArray(unsafe.Pointer(cobjinfo), int(count)) |
| | | } |
| | | return nil |
| | | } |
| | | |
| | | // YoloObjName obj name by type |
| | | func YoloObjName(i interface{}, typ int) string { |
| | | y := i.(*YoloHandle) |
| | | p := C.obj_name_by_type(y.handle, C.int(typ)) |
| | | func YoloObjName(typ int) string { |
| | | p := C.obj_name_by_type(C.int(typ)) |
| | | |
| | | return C.GoString(p) |
| | | } |