派生自 libgowrapper/yolo

zhangmeng
2019-12-10 eb19ddaebdf451cee76dc31082a3194a5f9b50ac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "yolo.h"
 
#include "yolo.hpp"
 
#include <fstream>
#include <vector>
#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");
        }
    }
 
    sdkyolo::~sdkyolo()
    {
        if (det_) delete det_;
    }
 
    static void objects_names_from_file(std::string filename, std::vector<std::string> &names){
        std::ifstream file(filename);
 
        if (!file.is_open()){
            printf("open %s file error\n", filename.c_str());
            return;
        }
        for(std::string line; getline(file, line);) names.push_back(line);
 
        printf("names count %d\n", names.size());
    }
 
    const char* sdkyolo::obj_name_by_type(const int typ)const{
        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;
 
        if(!cfg || !weights || !name){
            printf("init Detector error\n");
            return false;
        }
    
        if(names_.empty())
            objects_names_from_file(name, names_);
 
        det_ = new Detector(cfg, weights, gpu);
        return true;
    }
 
    int sdkyolo::buffer_to_image(const unsigned char *data, const int w, const int h, const int color_channel){
        
        int size = w*h;
        int size2 = size*2;
    
        int c = color_channel;
        if (w != width_ || h != height_ || color_channel != channel_){
            if (image_){
                free(image_->data);
                delete image_;
            }
            image_ = new image_t;
            image_->h = h;
            image_->w = w;
            image_->c = c;
            image_->data = (float*)calloc(h*w*c, sizeof(float));
        }
 
        // image im = make_image(w, h, c);
        const unsigned char *srcData = data;
    
        int count = 0;
        switch(c){
            case 1:{
                for (; count < size; ){
                    image_->data[count] = 
                    image_->data[w*h + count] = 
                    image_->data[w*h*2 + count] = 
                    (float)(srcData[count])/255.0;
    
                    ++count;
                }
                break;
            }
            case 3:{
                float* desData = image_->data;
    
                for(int i = 0;i<size;i++){
                    *(desData) = *(srcData + 2) /255.0f;
                    *(desData+size) = *(srcData + 1) /255.0f;
                    *(desData+size2) = *(srcData) /255.0f;
    
                    desData++;
                    srcData+=3;
                }
                break;
            }
    
            default:
                printf("Channel number not supported.\n");
                break;
        }
 
        return 0;
    }
 
    int sdkyolo::detect(const cIMAGE *img, const float thrsh, const bool use_mean, void **objs, int *objCount){
        if (!det_) return -1;
 
        const int color_channel = img->channel;
        buffer_to_image(img->data, img->width, img->height, color_channel);
 
        
        std::vector<bbox_t> result_vec = det_->detect(*image_, thrsh, use_mean);
        // det->free_image(*im);
        // delete im;
 
        if (obj_cnt_ < result_vec.size()){
            free(infos_);
 
            obj_cnt_ = result_vec.size();
            infos_ = (cObjInfo*)malloc(obj_cnt_ * 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;
        *objs = infos_;
 
        return count;
    }
 
} // namespace cppyolo