派生自 libgowrapper/yolo

zhangmeng
2019-12-11 b63c8219736016e3b3952465f41abede37a38fbd
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
#include "yolo.h"
 
#include "yolo.hpp"
 
#include <fstream>
#include <vector>
#include <string>
#include <stdexcept>
 
#include "struct.h"
 
namespace cppyolo
{
    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());
    }
 
    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();
    }
 
    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);
 
        return new Detector(cfg, weights, gpu);
    }
 
    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;
        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;
    }
 
    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;
        image_t *image = buffer_to_image(img->data, img->width, img->height, color_channel);
        
        std::vector<bbox_t> result_vec = d->detect(*image, thrsh, use_mean);
        d->free_image(*image);
        delete image;
 
        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;
        *objs = infos;
 
        return count;
    }
 
} // namespace cppyolo