Skip to content

Commit 661588c

Browse files
author
katsu560
committed
yolo : add reading labels and alphabet labels from model file
1 parent 6af7435 commit 661588c

File tree

3 files changed

+122
-7
lines changed

3 files changed

+122
-7
lines changed

examples/yolo/yolo-image.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,31 @@ bool load_image(const char *fname, yolo_image & img)
8888
return true;
8989
}
9090

91+
bool load_image_from_memory(const char *buffer, int len, yolo_image & img)
92+
{
93+
int w, h, c;
94+
uint8_t * data = stbi_load_from_memory((uint8_t *)buffer, len, &w, &h, &c, 3);
95+
if (!data) {
96+
return false;
97+
}
98+
c = 3;
99+
img.w = w;
100+
img.h = h;
101+
img.c = c;
102+
img.data.resize(w*h*c);
103+
for (int k = 0; k < c; ++k){
104+
for (int j = 0; j < h; ++j){
105+
for (int i = 0; i < w; ++i){
106+
int dst_index = i + w*j + w*h*k;
107+
int src_index = k + c*i + c*w*j;
108+
img.data[dst_index] = (float)data[src_index]/255.;
109+
}
110+
}
111+
}
112+
stbi_image_free(data);
113+
return true;
114+
}
115+
91116
static yolo_image resize_image(const yolo_image & im, int w, int h)
92117
{
93118
yolo_image resized(w, h, im.c);
@@ -207,4 +232,4 @@ void draw_label(yolo_image & im, int row, int col, const yolo_image & label, con
207232
}
208233
}
209234
}
210-
}
235+
}

examples/yolo/yolo-image.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct yolo_image {
3232
};
3333

3434
bool load_image(const char *fname, yolo_image & img);
35+
bool load_image_from_memory(const char *buffer, int len, yolo_image & img);
3536
void draw_box_width(yolo_image & a, int x1, int y1, int x2, int y2, int w, float r, float g, float b);
3637
yolo_image letterbox_image(const yolo_image & im, int w, int h);
3738
bool save_image(const yolo_image & im, const char *name, int quality);

examples/yolo/yolov3-tiny.cpp

Lines changed: 95 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct yolo_model {
3030
int height = 416;
3131
std::vector<conv2d_layer> conv2d_layers;
3232
struct ggml_context * ctx;
33+
struct gguf_context * ggufctx;
3334
};
3435

3536
struct yolo_layer {
@@ -71,6 +72,7 @@ static bool load_model(const std::string & fname, yolo_model & model) {
7172
fprintf(stderr, "%s: gguf_init_from_file() failed\n", __func__);
7273
return false;
7374
}
75+
model.ggufctx = ctx;
7476
model.width = 416;
7577
model.height = 416;
7678
model.conv2d_layers.resize(13);
@@ -100,6 +102,47 @@ static bool load_model(const std::string & fname, yolo_model & model) {
100102
return true;
101103
}
102104

105+
// istream from memory
106+
#include <streambuf>
107+
#include <istream>
108+
109+
struct membuf : std::streambuf {
110+
membuf(const char * begin, const char * end) {
111+
char * b(const_cast<char *>(begin));
112+
char * e(const_cast<char *>(end));
113+
this->begin = b;
114+
this->end = e;
115+
this->setg(b, b, e);
116+
}
117+
118+
membuf(const char * base, size_t size) {
119+
char * b(const_cast<char *>(begin));
120+
this->begin = b;
121+
this->end = b + size;
122+
this->setg(b, b, end);
123+
}
124+
125+
virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which = std::ios_base::in) override {
126+
if(dir == std::ios_base::cur) {
127+
gbump(off);
128+
} else if(dir == std::ios_base::end) {
129+
setg(begin, end + off, end);
130+
} else if(dir == std::ios_base::beg) {
131+
setg(begin, begin + off, end);
132+
}
133+
134+
return gptr() - eback();
135+
}
136+
137+
virtual pos_type seekpos(std::streampos pos, std::ios_base::openmode mode) override {
138+
return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode);
139+
}
140+
141+
char * begin;
142+
char * end;
143+
};
144+
145+
103146
static bool load_labels(const char * filename, std::vector<std::string> & labels)
104147
{
105148
std::ifstream file_in(filename);
@@ -114,6 +157,25 @@ static bool load_labels(const char * filename, std::vector<std::string> & labels
114157
return true;
115158
}
116159

160+
static bool load_labels_kv(const struct gguf_context * ctx, const char * filename, std::vector<std::string> & labels)
161+
{
162+
struct gguf_nobj nobj = gguf_find_name_nobj(ctx, filename);
163+
if (nobj.n == 0) {
164+
return false;
165+
}
166+
membuf buf(nobj.data, nobj.data + nobj.n);
167+
std::istream file_in(&buf);
168+
if (!file_in) {
169+
return false;
170+
}
171+
std::string line;
172+
while (std::getline(file_in, line)) {
173+
labels.push_back(line);
174+
}
175+
GGML_ASSERT(labels.size() == 80);
176+
return true;
177+
}
178+
117179
static bool load_alphabet(std::vector<yolo_image> & alphabet)
118180
{
119181
alphabet.resize(8 * 128);
@@ -130,6 +192,27 @@ static bool load_alphabet(std::vector<yolo_image> & alphabet)
130192
return true;
131193
}
132194

195+
static bool load_alphabet_kv(const struct gguf_context * ctx, std::vector<yolo_image> & alphabet)
196+
{
197+
alphabet.resize(8 * 128);
198+
for (int j = 0; j < 8; j++) {
199+
for (int i = 32; i < 127; i++) {
200+
char fname[256];
201+
sprintf(fname, "data/labels/%d_%d.png", i, j);
202+
struct gguf_nobj nobj = gguf_find_name_nobj(ctx, fname);
203+
if (nobj.n == 0) {
204+
fprintf(stderr, "Cannot find '%s'\n", fname);
205+
return false;
206+
}
207+
if (!load_image_from_memory(nobj.data, nobj.n, alphabet[j*128 + i])) {
208+
fprintf(stderr, "Cannot load '%s'\n", fname);
209+
return false;
210+
}
211+
}
212+
}
213+
return true;
214+
}
215+
133216
static ggml_tensor * apply_conv2d(ggml_context * ctx, ggml_tensor * input, const conv2d_layer & layer)
134217
{
135218
struct ggml_tensor * result = ggml_conv_2d(ctx, layer.weights, input, 1, 1, layer.padding, layer.padding, 1, 1);
@@ -503,14 +586,20 @@ int main(int argc, char *argv[])
503586
return 1;
504587
}
505588
std::vector<std::string> labels;
506-
if (!load_labels("data/coco.names", labels)) {
507-
fprintf(stderr, "%s: failed to load labels from 'data/coco.names'\n", __func__);
508-
return 1;
589+
if (!load_labels_kv(model.ggufctx, "data/coco.names", labels)) {
590+
fprintf(stderr, "%s: failed to load labels from 'data/coco.names' in model\n", __func__);
591+
if (!load_labels("data/coco.names", labels)) {
592+
fprintf(stderr, "%s: failed to load labels from 'data/coco.names'\n", __func__);
593+
return 1;
594+
}
509595
}
510596
std::vector<yolo_image> alphabet;
511-
if (!load_alphabet(alphabet)) {
512-
fprintf(stderr, "%s: failed to load alphabet\n", __func__);
513-
return 1;
597+
if (!load_alphabet_kv(model.ggufctx, alphabet)) {
598+
fprintf(stderr, "%s: failed to load alphabet from model\n", __func__);
599+
if (!load_alphabet(alphabet)) {
600+
fprintf(stderr, "%s: failed to load alphabet\n", __func__);
601+
return 1;
602+
}
514603
}
515604
const int64_t t_start_ms = ggml_time_ms();
516605
detect(img, model, params.thresh, labels, alphabet);

0 commit comments

Comments
 (0)