darknet  v3
image.c
Go to the documentation of this file.
1 #include "image.h"
2 #include "utils.h"
3 #include "blas.h"
4 #include "cuda.h"
5 #include <stdio.h>
6 #include <math.h>
7 
8 #define STB_IMAGE_IMPLEMENTATION
9 #include "stb_image.h"
10 #define STB_IMAGE_WRITE_IMPLEMENTATION
11 #include "stb_image_write.h"
12 
13 int windows = 0;
14 
15 float colors[6][3] = { {1,0,1}, {0,0,1},{0,1,1},{0,1,0},{1,1,0},{1,0,0} };
16 
17 float get_color(int c, int x, int max)
18 {
19  float ratio = ((float)x/max)*5;
20  int i = floor(ratio);
21  int j = ceil(ratio);
22  ratio -= i;
23  float r = (1-ratio) * colors[i][c] + ratio*colors[j][c];
24  //printf("%f\n", r);
25  return r;
26 }
27 
29 {
30  int n = mask.c;
31  image im = make_image(mask.w, mask.h, 3);
32  int i, j;
33  for(j = 0; j < n; ++j){
34  int offset = j*123457 % n;
35  float red = get_color(2,offset,n);
36  float green = get_color(1,offset,n);
37  float blue = get_color(0,offset,n);
38  for(i = 0; i < im.w*im.h; ++i){
39  im.data[i + 0*im.w*im.h] += mask.data[j*im.h*im.w + i]*red;
40  im.data[i + 1*im.w*im.h] += mask.data[j*im.h*im.w + i]*green;
41  im.data[i + 2*im.w*im.h] += mask.data[j*im.h*im.w + i]*blue;
42  }
43  }
44  return im;
45 }
46 
47 static float get_pixel(image m, int x, int y, int c)
48 {
49  assert(x < m.w && y < m.h && c < m.c);
50  return m.data[c*m.h*m.w + y*m.w + x];
51 }
52 static float get_pixel_extend(image m, int x, int y, int c)
53 {
54  if(x < 0 || x >= m.w || y < 0 || y >= m.h) return 0;
55  /*
56  if(x < 0) x = 0;
57  if(x >= m.w) x = m.w-1;
58  if(y < 0) y = 0;
59  if(y >= m.h) y = m.h-1;
60  */
61  if(c < 0 || c >= m.c) return 0;
62  return get_pixel(m, x, y, c);
63 }
64 static void set_pixel(image m, int x, int y, int c, float val)
65 {
66  if (x < 0 || y < 0 || c < 0 || x >= m.w || y >= m.h || c >= m.c) return;
67  assert(x < m.w && y < m.h && c < m.c);
68  m.data[c*m.h*m.w + y*m.w + x] = val;
69 }
70 static void add_pixel(image m, int x, int y, int c, float val)
71 {
72  assert(x < m.w && y < m.h && c < m.c);
73  m.data[c*m.h*m.w + y*m.w + x] += val;
74 }
75 
76 static float bilinear_interpolate(image im, float x, float y, int c)
77 {
78  int ix = (int) floorf(x);
79  int iy = (int) floorf(y);
80 
81  float dx = x - ix;
82  float dy = y - iy;
83 
84  float val = (1-dy) * (1-dx) * get_pixel_extend(im, ix, iy, c) +
85  dy * (1-dx) * get_pixel_extend(im, ix, iy+1, c) +
86  (1-dy) * dx * get_pixel_extend(im, ix+1, iy, c) +
87  dy * dx * get_pixel_extend(im, ix+1, iy+1, c);
88  return val;
89 }
90 
91 
92 void composite_image(image source, image dest, int dx, int dy)
93 {
94  int x,y,k;
95  for(k = 0; k < source.c; ++k){
96  for(y = 0; y < source.h; ++y){
97  for(x = 0; x < source.w; ++x){
98  float val = get_pixel(source, x, y, k);
99  float val2 = get_pixel_extend(dest, dx+x, dy+y, k);
100  set_pixel(dest, dx+x, dy+y, k, val * val2);
101  }
102  }
103  }
104 }
105 
106 image border_image(image a, int border)
107 {
108  image b = make_image(a.w + 2*border, a.h + 2*border, a.c);
109  int x,y,k;
110  for(k = 0; k < b.c; ++k){
111  for(y = 0; y < b.h; ++y){
112  for(x = 0; x < b.w; ++x){
113  float val = get_pixel_extend(a, x - border, y - border, k);
114  if(x - border < 0 || x - border >= a.w || y - border < 0 || y - border >= a.h) val = 1;
115  set_pixel(b, x, y, k, val);
116  }
117  }
118  }
119  return b;
120 }
121 
123 {
124  if(a.w == 0) return copy_image(b);
125  image c = make_image(a.w + b.w + dx, (a.h > b.h) ? a.h : b.h, (a.c > b.c) ? a.c : b.c);
126  fill_cpu(c.w*c.h*c.c, 1, c.data, 1);
127  embed_image(a, c, 0, 0);
128  composite_image(b, c, a.w + dx, 0);
129  return c;
130 }
131 
132 image get_label(image **characters, char *string, int size)
133 {
134  size = size/10;
135  if(size > 7) size = 7;
136  image label = make_empty_image(0,0,0);
137  while(*string){
138  image l = characters[size][(int)*string];
139  image n = tile_images(label, l, -size - 1 + (size+1)/2);
140  free_image(label);
141  label = n;
142  ++string;
143  }
144  image b = border_image(label, label.h*.25);
145  free_image(label);
146  return b;
147 }
148 
149 void draw_label(image a, int r, int c, image label, const float *rgb)
150 {
151  int w = label.w;
152  int h = label.h;
153  if (r - h >= 0) r = r - h;
154 
155  int i, j, k;
156  for(j = 0; j < h && j + r < a.h; ++j){
157  for(i = 0; i < w && i + c < a.w; ++i){
158  for(k = 0; k < label.c; ++k){
159  float val = get_pixel(label, i, j, k);
160  set_pixel(a, i+c, j+r, k, rgb[k] * val);
161  }
162  }
163  }
164 }
165 
166 void draw_box(image a, int x1, int y1, int x2, int y2, float r, float g, float b)
167 {
168  //normalize_image(a);
169  int i;
170  if(x1 < 0) x1 = 0;
171  if(x1 >= a.w) x1 = a.w-1;
172  if(x2 < 0) x2 = 0;
173  if(x2 >= a.w) x2 = a.w-1;
174 
175  if(y1 < 0) y1 = 0;
176  if(y1 >= a.h) y1 = a.h-1;
177  if(y2 < 0) y2 = 0;
178  if(y2 >= a.h) y2 = a.h-1;
179 
180  for(i = x1; i <= x2; ++i){
181  a.data[i + y1*a.w + 0*a.w*a.h] = r;
182  a.data[i + y2*a.w + 0*a.w*a.h] = r;
183 
184  a.data[i + y1*a.w + 1*a.w*a.h] = g;
185  a.data[i + y2*a.w + 1*a.w*a.h] = g;
186 
187  a.data[i + y1*a.w + 2*a.w*a.h] = b;
188  a.data[i + y2*a.w + 2*a.w*a.h] = b;
189  }
190  for(i = y1; i <= y2; ++i){
191  a.data[x1 + i*a.w + 0*a.w*a.h] = r;
192  a.data[x2 + i*a.w + 0*a.w*a.h] = r;
193 
194  a.data[x1 + i*a.w + 1*a.w*a.h] = g;
195  a.data[x2 + i*a.w + 1*a.w*a.h] = g;
196 
197  a.data[x1 + i*a.w + 2*a.w*a.h] = b;
198  a.data[x2 + i*a.w + 2*a.w*a.h] = b;
199  }
200 }
201 
202 void draw_box_width(image a, int x1, int y1, int x2, int y2, int w, float r, float g, float b)
203 {
204  int i;
205  for(i = 0; i < w; ++i){
206  draw_box(a, x1+i, y1+i, x2-i, y2-i, r, g, b);
207  }
208 }
209 
210 void draw_bbox(image a, box bbox, int w, float r, float g, float b)
211 {
212  int left = (bbox.x-bbox.w/2)*a.w;
213  int right = (bbox.x+bbox.w/2)*a.w;
214  int top = (bbox.y-bbox.h/2)*a.h;
215  int bot = (bbox.y+bbox.h/2)*a.h;
216 
217  int i;
218  for(i = 0; i < w; ++i){
219  draw_box(a, left+i, top+i, right-i, bot-i, r, g, b);
220  }
221 }
222 
224 {
225  int i, j;
226  const int nsize = 8;
227  image **alphabets = calloc(nsize, sizeof(image));
228  for(j = 0; j < nsize; ++j){
229  alphabets[j] = calloc(128, sizeof(image));
230  for(i = 32; i < 127; ++i){
231  char buff[256];
232  sprintf(buff, "data/labels/%d_%d.png", i, j);
233  alphabets[j][i] = load_image_color(buff, 0, 0);
234  }
235  }
236  return alphabets;
237 }
238 
239 void draw_detections(image im, detection *dets, int num, float thresh, char **names, image **alphabet, int classes)
240 {
241  int i,j;
242 
243  for(i = 0; i < num; ++i){
244  char labelstr[4096] = {0};
245  int class = -1;
246  for(j = 0; j < classes; ++j){
247  if (dets[i].prob[j] > thresh){
248  if (class < 0) {
249  strcat(labelstr, names[j]);
250  class = j;
251  } else {
252  strcat(labelstr, ", ");
253  strcat(labelstr, names[j]);
254  }
255  printf("%s: %.0f%%\n", names[j], dets[i].prob[j]*100);
256  }
257  }
258  if(class >= 0){
259  int width = im.h * .006;
260 
261  /*
262  if(0){
263  width = pow(prob, 1./2.)*10+1;
264  alphabet = 0;
265  }
266  */
267 
268  //printf("%d %s: %.0f%%\n", i, names[class], prob*100);
269  int offset = class*123457 % classes;
270  float red = get_color(2,offset,classes);
271  float green = get_color(1,offset,classes);
272  float blue = get_color(0,offset,classes);
273  float rgb[3];
274 
275  //width = prob*20+2;
276 
277  rgb[0] = red;
278  rgb[1] = green;
279  rgb[2] = blue;
280  box b = dets[i].bbox;
281  //printf("%f %f %f %f\n", b.x, b.y, b.w, b.h);
282 
283  int left = (b.x-b.w/2.)*im.w;
284  int right = (b.x+b.w/2.)*im.w;
285  int top = (b.y-b.h/2.)*im.h;
286  int bot = (b.y+b.h/2.)*im.h;
287 
288  if(left < 0) left = 0;
289  if(right > im.w-1) right = im.w-1;
290  if(top < 0) top = 0;
291  if(bot > im.h-1) bot = im.h-1;
292 
293  draw_box_width(im, left, top, right, bot, width, red, green, blue);
294  if (alphabet) {
295  image label = get_label(alphabet, labelstr, (im.h*.03));
296  draw_label(im, top + width, left, label, rgb);
297  free_image(label);
298  }
299  if (dets[i].mask){
300  image mask = float_to_image(14, 14, 1, dets[i].mask);
301  image resized_mask = resize_image(mask, b.w*im.w, b.h*im.h);
302  image tmask = threshold_image(resized_mask, .5);
303  embed_image(tmask, im, left, top);
304  free_image(mask);
305  free_image(resized_mask);
306  free_image(tmask);
307  }
308  }
309  }
310 }
311 
313 {
314  assert(im.w == im.h);
315  int n, m;
316  int c;
317  for(c = 0; c < im.c; ++c){
318  for(n = 0; n < im.w-1; ++n){
319  for(m = n + 1; m < im.w; ++m){
320  float swap = im.data[m + im.w*(n + im.h*c)];
321  im.data[m + im.w*(n + im.h*c)] = im.data[n + im.w*(m + im.h*c)];
322  im.data[n + im.w*(m + im.h*c)] = swap;
323  }
324  }
325  }
326 }
327 
328 void rotate_image_cw(image im, int times)
329 {
330  assert(im.w == im.h);
331  times = (times + 400) % 4;
332  int i, x, y, c;
333  int n = im.w;
334  for(i = 0; i < times; ++i){
335  for(c = 0; c < im.c; ++c){
336  for(x = 0; x < n/2; ++x){
337  for(y = 0; y < (n-1)/2 + 1; ++y){
338  float temp = im.data[y + im.w*(x + im.h*c)];
339  im.data[y + im.w*(x + im.h*c)] = im.data[n-1-x + im.w*(y + im.h*c)];
340  im.data[n-1-x + im.w*(y + im.h*c)] = im.data[n-1-y + im.w*(n-1-x + im.h*c)];
341  im.data[n-1-y + im.w*(n-1-x + im.h*c)] = im.data[x + im.w*(n-1-y + im.h*c)];
342  im.data[x + im.w*(n-1-y + im.h*c)] = temp;
343  }
344  }
345  }
346  }
347 }
348 
350 {
351  int i,j,k;
352  for(k = 0; k < a.c; ++k){
353  for(i = 0; i < a.h; ++i){
354  for(j = 0; j < a.w/2; ++j){
355  int index = j + a.w*(i + a.h*(k));
356  int flip = (a.w - j - 1) + a.w*(i + a.h*(k));
357  float swap = a.data[flip];
358  a.data[flip] = a.data[index];
359  a.data[index] = swap;
360  }
361  }
362  }
363 }
364 
366 {
367  int i,j;
368  image dist = make_image(a.w, a.h, 1);
369  for(i = 0; i < a.c; ++i){
370  for(j = 0; j < a.h*a.w; ++j){
371  dist.data[j] += pow(a.data[i*a.h*a.w+j]-b.data[i*a.h*a.w+j],2);
372  }
373  }
374  for(j = 0; j < a.h*a.w; ++j){
375  dist.data[j] = sqrt(dist.data[j]);
376  }
377  return dist;
378 }
379 
380 void ghost_image(image source, image dest, int dx, int dy)
381 {
382  int x,y,k;
383  float max_dist = sqrt((-source.w/2. + .5)*(-source.w/2. + .5));
384  for(k = 0; k < source.c; ++k){
385  for(y = 0; y < source.h; ++y){
386  for(x = 0; x < source.w; ++x){
387  float dist = sqrt((x - source.w/2. + .5)*(x - source.w/2. + .5) + (y - source.h/2. + .5)*(y - source.h/2. + .5));
388  float alpha = (1 - dist/max_dist);
389  if(alpha < 0) alpha = 0;
390  float v1 = get_pixel(source, x,y,k);
391  float v2 = get_pixel(dest, dx+x,dy+y,k);
392  float val = alpha*v1 + (1-alpha)*v2;
393  set_pixel(dest, dx+x, dy+y, k, val);
394  }
395  }
396  }
397 }
398 
399 void blocky_image(image im, int s)
400 {
401  int i,j,k;
402  for(k = 0; k < im.c; ++k){
403  for(j = 0; j < im.h; ++j){
404  for(i = 0; i < im.w; ++i){
405  im.data[i + im.w*(j + im.h*k)] = im.data[i/s*s + im.w*(j/s*s + im.h*k)];
406  }
407  }
408  }
409 }
410 
411 void censor_image(image im, int dx, int dy, int w, int h)
412 {
413  int i,j,k;
414  int s = 32;
415  if(dx < 0) dx = 0;
416  if(dy < 0) dy = 0;
417 
418  for(k = 0; k < im.c; ++k){
419  for(j = dy; j < dy + h && j < im.h; ++j){
420  for(i = dx; i < dx + w && i < im.w; ++i){
421  im.data[i + im.w*(j + im.h*k)] = im.data[i/s*s + im.w*(j/s*s + im.h*k)];
422  //im.data[i + j*im.w + k*im.w*im.h] = 0;
423  }
424  }
425  }
426 }
427 
428 void embed_image(image source, image dest, int dx, int dy)
429 {
430  int x,y,k;
431  for(k = 0; k < source.c; ++k){
432  for(y = 0; y < source.h; ++y){
433  for(x = 0; x < source.w; ++x){
434  float val = get_pixel(source, x,y,k);
435  set_pixel(dest, dx+x, dy+y, k, val);
436  }
437  }
438  }
439 }
440 
441 image collapse_image_layers(image source, int border)
442 {
443  int h = source.h;
444  h = (h+border)*source.c - border;
445  image dest = make_image(source.w, h, 1);
446  int i;
447  for(i = 0; i < source.c; ++i){
448  image layer = get_image_layer(source, i);
449  int h_offset = i*(source.h+border);
450  embed_image(layer, dest, 0, h_offset);
451  free_image(layer);
452  }
453  return dest;
454 }
455 
457 {
458  int i;
459  for(i = 0; i < im.w*im.h*im.c; ++i){
460  if(im.data[i] < 0) im.data[i] = 0;
461  if(im.data[i] > 1) im.data[i] = 1;
462  }
463 }
464 
466 {
467  int i;
468  float min = 9999999;
469  float max = -999999;
470 
471  for(i = 0; i < p.h*p.w*p.c; ++i){
472  float v = p.data[i];
473  if(v < min) min = v;
474  if(v > max) max = v;
475  }
476  if(max - min < .000000001){
477  min = 0;
478  max = 1;
479  }
480  for(i = 0; i < p.c*p.w*p.h; ++i){
481  p.data[i] = (p.data[i] - min)/(max-min);
482  }
483 }
484 
486 {
487  float *min = calloc(p.c, sizeof(float));
488  float *max = calloc(p.c, sizeof(float));
489  int i,j;
490  for(i = 0; i < p.c; ++i) min[i] = max[i] = p.data[i*p.h*p.w];
491 
492  for(j = 0; j < p.c; ++j){
493  for(i = 0; i < p.h*p.w; ++i){
494  float v = p.data[i+j*p.h*p.w];
495  if(v < min[j]) min[j] = v;
496  if(v > max[j]) max[j] = v;
497  }
498  }
499  for(i = 0; i < p.c; ++i){
500  if(max[i] - min[i] < .000000001){
501  min[i] = 0;
502  max[i] = 1;
503  }
504  }
505  for(j = 0; j < p.c; ++j){
506  for(i = 0; i < p.w*p.h; ++i){
507  p.data[i+j*p.h*p.w] = (p.data[i+j*p.h*p.w] - min[j])/(max[j]-min[j]);
508  }
509  }
510  free(min);
511  free(max);
512 }
513 
514 void copy_image_into(image src, image dest)
515 {
516  memcpy(dest.data, src.data, src.h*src.w*src.c*sizeof(float));
517 }
518 
520 {
521  image copy = p;
522  copy.data = calloc(p.h*p.w*p.c, sizeof(float));
523  memcpy(copy.data, p.data, p.h*p.w*p.c*sizeof(float));
524  return copy;
525 }
526 
528 {
529  int i;
530  for(i = 0; i < im.w*im.h; ++i){
531  float swap = im.data[i];
532  im.data[i] = im.data[i+im.w*im.h*2];
533  im.data[i+im.w*im.h*2] = swap;
534  }
535 }
536 
537 #ifdef OPENCV
538 void show_image_cv(image p, const char *name, IplImage *disp)
539 {
540  int x,y,k;
541  if(p.c == 3) rgbgr_image(p);
542  //normalize_image(copy);
543 
544  char buff[256];
545  //sprintf(buff, "%s (%d)", name, windows);
546  sprintf(buff, "%s", name);
547 
548  int step = disp->widthStep;
549  cvNamedWindow(buff, CV_WINDOW_NORMAL);
550  //cvMoveWindow(buff, 100*(windows%10) + 200*(windows/10), 100*(windows%10));
551  ++windows;
552  for(y = 0; y < p.h; ++y){
553  for(x = 0; x < p.w; ++x){
554  for(k= 0; k < p.c; ++k){
555  disp->imageData[y*step + x*p.c + k] = (unsigned char)(get_pixel(p,x,y,k)*255);
556  }
557  }
558  }
559  if(0){
560  int w = 448;
561  int h = w*p.h/p.w;
562  if(h > 1000){
563  h = 1000;
564  w = h*p.w/p.h;
565  }
566  IplImage *buffer = disp;
567  disp = cvCreateImage(cvSize(w, h), buffer->depth, buffer->nChannels);
568  cvResize(buffer, disp, CV_INTER_LINEAR);
569  cvReleaseImage(&buffer);
570  }
571  cvShowImage(buff, disp);
572 }
573 #endif
574 
575 int show_image(image p, const char *name, int ms)
576 {
577 #ifdef OPENCV
578  IplImage *disp = cvCreateImage(cvSize(p.w,p.h), IPL_DEPTH_8U, p.c);
579  image copy = copy_image(p);
580  constrain_image(copy);
581  show_image_cv(copy, name, disp);
582  free_image(copy);
583  cvReleaseImage(&disp);
584  int c = cvWaitKey(ms);
585  if (c != -1) c = c%256;
586  return c;
587 #else
588  fprintf(stderr, "Not compiled with OpenCV, saving to %s.png instead\n", name);
589  save_image(p, name);
590  return 0;
591 #endif
592 }
593 
594 #ifdef OPENCV
595 
596 void ipl_into_image(IplImage* src, image im)
597 {
598  unsigned char *data = (unsigned char *)src->imageData;
599  int h = src->height;
600  int w = src->width;
601  int c = src->nChannels;
602  int step = src->widthStep;
603  int i, j, k;
604 
605  for(i = 0; i < h; ++i){
606  for(k= 0; k < c; ++k){
607  for(j = 0; j < w; ++j){
608  im.data[k*w*h + i*w + j] = data[i*step + j*c + k]/255.;
609  }
610  }
611  }
612 }
613 
614 image ipl_to_image(IplImage* src)
615 {
616  int h = src->height;
617  int w = src->width;
618  int c = src->nChannels;
619  image out = make_image(w, h, c);
620  ipl_into_image(src, out);
621  return out;
622 }
623 
624 image load_image_cv(char *filename, int channels)
625 {
626  IplImage* src = 0;
627  int flag = -1;
628  if (channels == 0) flag = -1;
629  else if (channels == 1) flag = 0;
630  else if (channels == 3) flag = 1;
631  else {
632  fprintf(stderr, "OpenCV can't force load with %d channels\n", channels);
633  }
634 
635  if( (src = cvLoadImage(filename, flag)) == 0 )
636  {
637  fprintf(stderr, "Cannot load image \"%s\"\n", filename);
638  char buff[256];
639  sprintf(buff, "echo %s >> bad.list", filename);
640  system(buff);
641  return make_image(10,10,3);
642  //exit(0);
643  }
644  image out = ipl_to_image(src);
645  cvReleaseImage(&src);
646  rgbgr_image(out);
647  return out;
648 }
649 
650 void flush_stream_buffer(CvCapture *cap, int n)
651 {
652  int i;
653  for(i = 0; i < n; ++i) {
654  cvQueryFrame(cap);
655  }
656 }
657 
658 image get_image_from_stream(CvCapture *cap)
659 {
660  IplImage* src = cvQueryFrame(cap);
661  if (!src) return make_empty_image(0,0,0);
662  image im = ipl_to_image(src);
663  rgbgr_image(im);
664  return im;
665 }
666 
667 int fill_image_from_stream(CvCapture *cap, image im)
668 {
669  IplImage* src = cvQueryFrame(cap);
670  if (!src) return 0;
671  ipl_into_image(src, im);
672  rgbgr_image(im);
673  return 1;
674 }
675 
676 void save_image_jpg(image p, const char *name)
677 {
678  image copy = copy_image(p);
679  if(p.c == 3) rgbgr_image(copy);
680  int x,y,k;
681 
682  char buff[256];
683  sprintf(buff, "%s.jpg", name);
684 
685  IplImage *disp = cvCreateImage(cvSize(p.w,p.h), IPL_DEPTH_8U, p.c);
686  int step = disp->widthStep;
687  for(y = 0; y < p.h; ++y){
688  for(x = 0; x < p.w; ++x){
689  for(k= 0; k < p.c; ++k){
690  disp->imageData[y*step + x*p.c + k] = (unsigned char)(get_pixel(copy,x,y,k)*255);
691  }
692  }
693  }
694  cvSaveImage(buff, disp,0);
695  cvReleaseImage(&disp);
696  free_image(copy);
697 }
698 #endif
699 
700 void save_image_png(image im, const char *name)
701 {
702  char buff[256];
703  //sprintf(buff, "%s (%d)", name, windows);
704  sprintf(buff, "%s.png", name);
705  unsigned char *data = calloc(im.w*im.h*im.c, sizeof(char));
706  int i,k;
707  for(k = 0; k < im.c; ++k){
708  for(i = 0; i < im.w*im.h; ++i){
709  data[i*im.c+k] = (unsigned char) (255*im.data[i + k*im.w*im.h]);
710  }
711  }
712  int success = stbi_write_png(buff, im.w, im.h, im.c, data, im.w*im.c);
713  free(data);
714  if(!success) fprintf(stderr, "Failed to write image %s\n", buff);
715 }
716 
717 void save_image(image im, const char *name)
718 {
719 #ifdef OPENCV
720  save_image_jpg(im, name);
721 #else
722  save_image_png(im, name);
723 #endif
724 }
725 
726 
727 void show_image_layers(image p, char *name)
728 {
729  int i;
730  char buff[256];
731  for(i = 0; i < p.c; ++i){
732  sprintf(buff, "%s - Layer %d", name, i);
733  image layer = get_image_layer(p, i);
734  show_image(layer, buff, 1);
735  free_image(layer);
736  }
737 }
738 
739 void show_image_collapsed(image p, char *name)
740 {
741  image c = collapse_image_layers(p, 1);
742  show_image(c, name, 1);
743  free_image(c);
744 }
745 
746 image make_empty_image(int w, int h, int c)
747 {
748  image out;
749  out.data = 0;
750  out.h = h;
751  out.w = w;
752  out.c = c;
753  return out;
754 }
755 
756 image make_image(int w, int h, int c)
757 {
758  image out = make_empty_image(w,h,c);
759  out.data = calloc(h*w*c, sizeof(float));
760  return out;
761 }
762 
763 image make_random_image(int w, int h, int c)
764 {
765  image out = make_empty_image(w,h,c);
766  out.data = calloc(h*w*c, sizeof(float));
767  int i;
768  for(i = 0; i < w*h*c; ++i){
769  out.data[i] = (rand_normal() * .25) + .5;
770  }
771  return out;
772 }
773 
774 image float_to_image(int w, int h, int c, float *data)
775 {
776  image out = make_empty_image(w,h,c);
777  out.data = data;
778  return out;
779 }
780 
781 void place_image(image im, int w, int h, int dx, int dy, image canvas)
782 {
783  int x, y, c;
784  for(c = 0; c < im.c; ++c){
785  for(y = 0; y < h; ++y){
786  for(x = 0; x < w; ++x){
787  float rx = ((float)x / w) * im.w;
788  float ry = ((float)y / h) * im.h;
789  float val = bilinear_interpolate(im, rx, ry, c);
790  set_pixel(canvas, x + dx, y + dy, c, val);
791  }
792  }
793  }
794 }
795 
796 image center_crop_image(image im, int w, int h)
797 {
798  int m = (im.w < im.h) ? im.w : im.h;
799  image c = crop_image(im, (im.w - m) / 2, (im.h - m)/2, m, m);
800  image r = resize_image(c, w, h);
801  free_image(c);
802  return r;
803 }
804 
805 image rotate_crop_image(image im, float rad, float s, int w, int h, float dx, float dy, float aspect)
806 {
807  int x, y, c;
808  float cx = im.w/2.;
809  float cy = im.h/2.;
810  image rot = make_image(w, h, im.c);
811  for(c = 0; c < im.c; ++c){
812  for(y = 0; y < h; ++y){
813  for(x = 0; x < w; ++x){
814  float rx = cos(rad)*((x - w/2.)/s*aspect + dx/s*aspect) - sin(rad)*((y - h/2.)/s + dy/s) + cx;
815  float ry = sin(rad)*((x - w/2.)/s*aspect + dx/s*aspect) + cos(rad)*((y - h/2.)/s + dy/s) + cy;
816  float val = bilinear_interpolate(im, rx, ry, c);
817  set_pixel(rot, x, y, c, val);
818  }
819  }
820  }
821  return rot;
822 }
823 
824 image rotate_image(image im, float rad)
825 {
826  int x, y, c;
827  float cx = im.w/2.;
828  float cy = im.h/2.;
829  image rot = make_image(im.w, im.h, im.c);
830  for(c = 0; c < im.c; ++c){
831  for(y = 0; y < im.h; ++y){
832  for(x = 0; x < im.w; ++x){
833  float rx = cos(rad)*(x-cx) - sin(rad)*(y-cy) + cx;
834  float ry = sin(rad)*(x-cx) + cos(rad)*(y-cy) + cy;
835  float val = bilinear_interpolate(im, rx, ry, c);
836  set_pixel(rot, x, y, c, val);
837  }
838  }
839  }
840  return rot;
841 }
842 
843 void fill_image(image m, float s)
844 {
845  int i;
846  for(i = 0; i < m.h*m.w*m.c; ++i) m.data[i] = s;
847 }
848 
849 void translate_image(image m, float s)
850 {
851  int i;
852  for(i = 0; i < m.h*m.w*m.c; ++i) m.data[i] += s;
853 }
854 
855 void scale_image(image m, float s)
856 {
857  int i;
858  for(i = 0; i < m.h*m.w*m.c; ++i) m.data[i] *= s;
859 }
860 
861 image crop_image(image im, int dx, int dy, int w, int h)
862 {
863  image cropped = make_image(w, h, im.c);
864  int i, j, k;
865  for(k = 0; k < im.c; ++k){
866  for(j = 0; j < h; ++j){
867  for(i = 0; i < w; ++i){
868  int r = j + dy;
869  int c = i + dx;
870  float val = 0;
871  r = constrain_int(r, 0, im.h-1);
872  c = constrain_int(c, 0, im.w-1);
873  val = get_pixel(im, c, r, k);
874  set_pixel(cropped, i, j, k, val);
875  }
876  }
877  }
878  return cropped;
879 }
880 
881 int best_3d_shift_r(image a, image b, int min, int max)
882 {
883  if(min == max) return min;
884  int mid = floor((min + max) / 2.);
885  image c1 = crop_image(b, 0, mid, b.w, b.h);
886  image c2 = crop_image(b, 0, mid+1, b.w, b.h);
887  float d1 = dist_array(c1.data, a.data, a.w*a.h*a.c, 10);
888  float d2 = dist_array(c2.data, a.data, a.w*a.h*a.c, 10);
889  free_image(c1);
890  free_image(c2);
891  if(d1 < d2) return best_3d_shift_r(a, b, min, mid);
892  else return best_3d_shift_r(a, b, mid+1, max);
893 }
894 
895 int best_3d_shift(image a, image b, int min, int max)
896 {
897  int i;
898  int best = 0;
899  float best_distance = FLT_MAX;
900  for(i = min; i <= max; i += 2){
901  image c = crop_image(b, 0, i, b.w, b.h);
902  float d = dist_array(c.data, a.data, a.w*a.h*a.c, 100);
903  if(d < best_distance){
904  best_distance = d;
905  best = i;
906  }
907  printf("%d %f\n", i, d);
908  free_image(c);
909  }
910  return best;
911 }
912 
913 void composite_3d(char *f1, char *f2, char *out, int delta)
914 {
915  if(!out) out = "out";
916  image a = load_image(f1, 0,0,0);
917  image b = load_image(f2, 0,0,0);
918  int shift = best_3d_shift_r(a, b, -a.h/100, a.h/100);
919 
920  image c1 = crop_image(b, 10, shift, b.w, b.h);
921  float d1 = dist_array(c1.data, a.data, a.w*a.h*a.c, 100);
922  image c2 = crop_image(b, -10, shift, b.w, b.h);
923  float d2 = dist_array(c2.data, a.data, a.w*a.h*a.c, 100);
924 
925  if(d2 < d1 && 0){
926  image swap = a;
927  a = b;
928  b = swap;
929  shift = -shift;
930  printf("swapped, %d\n", shift);
931  }
932  else{
933  printf("%d\n", shift);
934  }
935 
936  image c = crop_image(b, delta, shift, a.w, a.h);
937  int i;
938  for(i = 0; i < c.w*c.h; ++i){
939  c.data[i] = a.data[i];
940  }
941 #ifdef OPENCV
942  save_image_jpg(c, out);
943 #else
944  save_image(c, out);
945 #endif
946 }
947 
948 void letterbox_image_into(image im, int w, int h, image boxed)
949 {
950  int new_w = im.w;
951  int new_h = im.h;
952  if (((float)w/im.w) < ((float)h/im.h)) {
953  new_w = w;
954  new_h = (im.h * w)/im.w;
955  } else {
956  new_h = h;
957  new_w = (im.w * h)/im.h;
958  }
959  image resized = resize_image(im, new_w, new_h);
960  embed_image(resized, boxed, (w-new_w)/2, (h-new_h)/2);
961  free_image(resized);
962 }
963 
964 image letterbox_image(image im, int w, int h)
965 {
966  int new_w = im.w;
967  int new_h = im.h;
968  if (((float)w/im.w) < ((float)h/im.h)) {
969  new_w = w;
970  new_h = (im.h * w)/im.w;
971  } else {
972  new_h = h;
973  new_w = (im.w * h)/im.h;
974  }
975  image resized = resize_image(im, new_w, new_h);
976  image boxed = make_image(w, h, im.c);
977  fill_image(boxed, .5);
978  //int i;
979  //for(i = 0; i < boxed.w*boxed.h*boxed.c; ++i) boxed.data[i] = 0;
980  embed_image(resized, boxed, (w-new_w)/2, (h-new_h)/2);
981  free_image(resized);
982  return boxed;
983 }
984 
985 image resize_max(image im, int max)
986 {
987  int w = im.w;
988  int h = im.h;
989  if(w > h){
990  h = (h * max) / w;
991  w = max;
992  } else {
993  w = (w * max) / h;
994  h = max;
995  }
996  if(w == im.w && h == im.h) return im;
997  image resized = resize_image(im, w, h);
998  return resized;
999 }
1000 
1001 image resize_min(image im, int min)
1002 {
1003  int w = im.w;
1004  int h = im.h;
1005  if(w < h){
1006  h = (h * min) / w;
1007  w = min;
1008  } else {
1009  w = (w * min) / h;
1010  h = min;
1011  }
1012  if(w == im.w && h == im.h) return im;
1013  image resized = resize_image(im, w, h);
1014  return resized;
1015 }
1016 
1017 image random_crop_image(image im, int w, int h)
1018 {
1019  int dx = rand_int(0, im.w - w);
1020  int dy = rand_int(0, im.h - h);
1021  image crop = crop_image(im, dx, dy, w, h);
1022  return crop;
1023 }
1024 
1025 augment_args random_augment_args(image im, float angle, float aspect, int low, int high, int w, int h)
1026 {
1027  augment_args a = {0};
1028  aspect = rand_scale(aspect);
1029  int r = rand_int(low, high);
1030  int min = (im.h < im.w*aspect) ? im.h : im.w*aspect;
1031  float scale = (float)r / min;
1032 
1033  float rad = rand_uniform(-angle, angle) * TWO_PI / 360.;
1034 
1035  float dx = (im.w*scale/aspect - w) / 2.;
1036  float dy = (im.h*scale - w) / 2.;
1037  //if(dx < 0) dx = 0;
1038  //if(dy < 0) dy = 0;
1039  dx = rand_uniform(-dx, dx);
1040  dy = rand_uniform(-dy, dy);
1041 
1042  a.rad = rad;
1043  a.scale = scale;
1044  a.w = w;
1045  a.h = h;
1046  a.dx = dx;
1047  a.dy = dy;
1048  a.aspect = aspect;
1049  return a;
1050 }
1051 
1052 image random_augment_image(image im, float angle, float aspect, int low, int high, int w, int h)
1053 {
1054  augment_args a = random_augment_args(im, angle, aspect, low, high, w, h);
1055  image crop = rotate_crop_image(im, a.rad, a.scale, a.w, a.h, a.dx, a.dy, a.aspect);
1056  return crop;
1057 }
1058 
1059 float three_way_max(float a, float b, float c)
1060 {
1061  return (a > b) ? ( (a > c) ? a : c) : ( (b > c) ? b : c) ;
1062 }
1063 
1064 float three_way_min(float a, float b, float c)
1065 {
1066  return (a < b) ? ( (a < c) ? a : c) : ( (b < c) ? b : c) ;
1067 }
1068 
1070 {
1071  assert(im.c == 3);
1072  int i, j;
1073  float r, g, b;
1074  float y, u, v;
1075  for(j = 0; j < im.h; ++j){
1076  for(i = 0; i < im.w; ++i){
1077  y = get_pixel(im, i , j, 0);
1078  u = get_pixel(im, i , j, 1);
1079  v = get_pixel(im, i , j, 2);
1080 
1081  r = y + 1.13983*v;
1082  g = y + -.39465*u + -.58060*v;
1083  b = y + 2.03211*u;
1084 
1085  set_pixel(im, i, j, 0, r);
1086  set_pixel(im, i, j, 1, g);
1087  set_pixel(im, i, j, 2, b);
1088  }
1089  }
1090 }
1091 
1093 {
1094  assert(im.c == 3);
1095  int i, j;
1096  float r, g, b;
1097  float y, u, v;
1098  for(j = 0; j < im.h; ++j){
1099  for(i = 0; i < im.w; ++i){
1100  r = get_pixel(im, i , j, 0);
1101  g = get_pixel(im, i , j, 1);
1102  b = get_pixel(im, i , j, 2);
1103 
1104  y = .299*r + .587*g + .114*b;
1105  u = -.14713*r + -.28886*g + .436*b;
1106  v = .615*r + -.51499*g + -.10001*b;
1107 
1108  set_pixel(im, i, j, 0, y);
1109  set_pixel(im, i, j, 1, u);
1110  set_pixel(im, i, j, 2, v);
1111  }
1112  }
1113 }
1114 
1115 // http://www.cs.rit.edu/~ncs/color/t_convert.html
1117 {
1118  assert(im.c == 3);
1119  int i, j;
1120  float r, g, b;
1121  float h, s, v;
1122  for(j = 0; j < im.h; ++j){
1123  for(i = 0; i < im.w; ++i){
1124  r = get_pixel(im, i , j, 0);
1125  g = get_pixel(im, i , j, 1);
1126  b = get_pixel(im, i , j, 2);
1127  float max = three_way_max(r,g,b);
1128  float min = three_way_min(r,g,b);
1129  float delta = max - min;
1130  v = max;
1131  if(max == 0){
1132  s = 0;
1133  h = 0;
1134  }else{
1135  s = delta/max;
1136  if(r == max){
1137  h = (g - b) / delta;
1138  } else if (g == max) {
1139  h = 2 + (b - r) / delta;
1140  } else {
1141  h = 4 + (r - g) / delta;
1142  }
1143  if (h < 0) h += 6;
1144  h = h/6.;
1145  }
1146  set_pixel(im, i, j, 0, h);
1147  set_pixel(im, i, j, 1, s);
1148  set_pixel(im, i, j, 2, v);
1149  }
1150  }
1151 }
1152 
1154 {
1155  assert(im.c == 3);
1156  int i, j;
1157  float r, g, b;
1158  float h, s, v;
1159  float f, p, q, t;
1160  for(j = 0; j < im.h; ++j){
1161  for(i = 0; i < im.w; ++i){
1162  h = 6 * get_pixel(im, i , j, 0);
1163  s = get_pixel(im, i , j, 1);
1164  v = get_pixel(im, i , j, 2);
1165  if (s == 0) {
1166  r = g = b = v;
1167  } else {
1168  int index = floor(h);
1169  f = h - index;
1170  p = v*(1-s);
1171  q = v*(1-s*f);
1172  t = v*(1-s*(1-f));
1173  if(index == 0){
1174  r = v; g = t; b = p;
1175  } else if(index == 1){
1176  r = q; g = v; b = p;
1177  } else if(index == 2){
1178  r = p; g = v; b = t;
1179  } else if(index == 3){
1180  r = p; g = q; b = v;
1181  } else if(index == 4){
1182  r = t; g = p; b = v;
1183  } else {
1184  r = v; g = p; b = q;
1185  }
1186  }
1187  set_pixel(im, i, j, 0, r);
1188  set_pixel(im, i, j, 1, g);
1189  set_pixel(im, i, j, 2, b);
1190  }
1191  }
1192 }
1193 
1195 {
1196  assert(im.c == 3);
1197  int i, j, k;
1198  float scale[] = {0.299, 0.587, 0.114};
1199  for(j = 0; j < im.h; ++j){
1200  for(i = 0; i < im.w; ++i){
1201  float val = 0;
1202  for(k = 0; k < 3; ++k){
1203  val += scale[k]*get_pixel(im, i, j, k);
1204  }
1205  im.data[0*im.h*im.w + im.w*j + i] = val;
1206  im.data[1*im.h*im.w + im.w*j + i] = val;
1207  im.data[2*im.h*im.w + im.w*j + i] = val;
1208  }
1209  }
1210 }
1211 
1213 {
1214  assert(im.c == 3);
1215  int i, j, k;
1216  image gray = make_image(im.w, im.h, 1);
1217  float scale[] = {0.299, 0.587, 0.114};
1218  for(k = 0; k < im.c; ++k){
1219  for(j = 0; j < im.h; ++j){
1220  for(i = 0; i < im.w; ++i){
1221  gray.data[i+im.w*j] += scale[k]*get_pixel(im, i, j, k);
1222  }
1223  }
1224  }
1225  return gray;
1226 }
1227 
1228 image threshold_image(image im, float thresh)
1229 {
1230  int i;
1231  image t = make_image(im.w, im.h, im.c);
1232  for(i = 0; i < im.w*im.h*im.c; ++i){
1233  t.data[i] = im.data[i]>thresh ? 1 : 0;
1234  }
1235  return t;
1236 }
1237 
1238 image blend_image(image fore, image back, float alpha)
1239 {
1240  assert(fore.w == back.w && fore.h == back.h && fore.c == back.c);
1241  image blend = make_image(fore.w, fore.h, fore.c);
1242  int i, j, k;
1243  for(k = 0; k < fore.c; ++k){
1244  for(j = 0; j < fore.h; ++j){
1245  for(i = 0; i < fore.w; ++i){
1246  float val = alpha * get_pixel(fore, i, j, k) +
1247  (1 - alpha)* get_pixel(back, i, j, k);
1248  set_pixel(blend, i, j, k, val);
1249  }
1250  }
1251  }
1252  return blend;
1253 }
1254 
1255 void scale_image_channel(image im, int c, float v)
1256 {
1257  int i, j;
1258  for(j = 0; j < im.h; ++j){
1259  for(i = 0; i < im.w; ++i){
1260  float pix = get_pixel(im, i, j, c);
1261  pix = pix*v;
1262  set_pixel(im, i, j, c, pix);
1263  }
1264  }
1265 }
1266 
1267 void translate_image_channel(image im, int c, float v)
1268 {
1269  int i, j;
1270  for(j = 0; j < im.h; ++j){
1271  for(i = 0; i < im.w; ++i){
1272  float pix = get_pixel(im, i, j, c);
1273  pix = pix+v;
1274  set_pixel(im, i, j, c, pix);
1275  }
1276  }
1277 }
1278 
1280 {
1281  image c = copy_image(im);
1282  int i;
1283  for(i = 0; i < im.w * im.h * im.c; ++i){
1284  if(c.data[i] > .5) c.data[i] = 1;
1285  else c.data[i] = 0;
1286  }
1287  return c;
1288 }
1289 
1290 void saturate_image(image im, float sat)
1291 {
1292  rgb_to_hsv(im);
1293  scale_image_channel(im, 1, sat);
1294  hsv_to_rgb(im);
1295  constrain_image(im);
1296 }
1297 
1298 void hue_image(image im, float hue)
1299 {
1300  rgb_to_hsv(im);
1301  int i;
1302  for(i = 0; i < im.w*im.h; ++i){
1303  im.data[i] = im.data[i] + hue;
1304  if (im.data[i] > 1) im.data[i] -= 1;
1305  if (im.data[i] < 0) im.data[i] += 1;
1306  }
1307  hsv_to_rgb(im);
1308  constrain_image(im);
1309 }
1310 
1311 void exposure_image(image im, float sat)
1312 {
1313  rgb_to_hsv(im);
1314  scale_image_channel(im, 2, sat);
1315  hsv_to_rgb(im);
1316  constrain_image(im);
1317 }
1318 
1319 void distort_image(image im, float hue, float sat, float val)
1320 {
1321  rgb_to_hsv(im);
1322  scale_image_channel(im, 1, sat);
1323  scale_image_channel(im, 2, val);
1324  int i;
1325  for(i = 0; i < im.w*im.h; ++i){
1326  im.data[i] = im.data[i] + hue;
1327  if (im.data[i] > 1) im.data[i] -= 1;
1328  if (im.data[i] < 0) im.data[i] += 1;
1329  }
1330  hsv_to_rgb(im);
1331  constrain_image(im);
1332 }
1333 
1334 void random_distort_image(image im, float hue, float saturation, float exposure)
1335 {
1336  float dhue = rand_uniform(-hue, hue);
1337  float dsat = rand_scale(saturation);
1338  float dexp = rand_scale(exposure);
1339  distort_image(im, dhue, dsat, dexp);
1340 }
1341 
1342 void saturate_exposure_image(image im, float sat, float exposure)
1343 {
1344  rgb_to_hsv(im);
1345  scale_image_channel(im, 1, sat);
1346  scale_image_channel(im, 2, exposure);
1347  hsv_to_rgb(im);
1348  constrain_image(im);
1349 }
1350 
1351 image resize_image(image im, int w, int h)
1352 {
1353  image resized = make_image(w, h, im.c);
1354  image part = make_image(w, im.h, im.c);
1355  int r, c, k;
1356  float w_scale = (float)(im.w - 1) / (w - 1);
1357  float h_scale = (float)(im.h - 1) / (h - 1);
1358  for(k = 0; k < im.c; ++k){
1359  for(r = 0; r < im.h; ++r){
1360  for(c = 0; c < w; ++c){
1361  float val = 0;
1362  if(c == w-1 || im.w == 1){
1363  val = get_pixel(im, im.w-1, r, k);
1364  } else {
1365  float sx = c*w_scale;
1366  int ix = (int) sx;
1367  float dx = sx - ix;
1368  val = (1 - dx) * get_pixel(im, ix, r, k) + dx * get_pixel(im, ix+1, r, k);
1369  }
1370  set_pixel(part, c, r, k, val);
1371  }
1372  }
1373  }
1374  for(k = 0; k < im.c; ++k){
1375  for(r = 0; r < h; ++r){
1376  float sy = r*h_scale;
1377  int iy = (int) sy;
1378  float dy = sy - iy;
1379  for(c = 0; c < w; ++c){
1380  float val = (1-dy) * get_pixel(part, c, iy, k);
1381  set_pixel(resized, c, r, k, val);
1382  }
1383  if(r == h-1 || im.h == 1) continue;
1384  for(c = 0; c < w; ++c){
1385  float val = dy * get_pixel(part, c, iy+1, k);
1386  add_pixel(resized, c, r, k, val);
1387  }
1388  }
1389  }
1390 
1391  free_image(part);
1392  return resized;
1393 }
1394 
1395 
1396 void test_resize(char *filename)
1397 {
1398  image im = load_image(filename, 0,0, 3);
1399  float mag = mag_array(im.data, im.w*im.h*im.c);
1400  printf("L2 Norm: %f\n", mag);
1401  image gray = grayscale_image(im);
1402 
1403  image c1 = copy_image(im);
1404  image c2 = copy_image(im);
1405  image c3 = copy_image(im);
1406  image c4 = copy_image(im);
1407  distort_image(c1, .1, 1.5, 1.5);
1408  distort_image(c2, -.1, .66666, .66666);
1409  distort_image(c3, .1, 1.5, .66666);
1410  distort_image(c4, .1, .66666, 1.5);
1411 
1412 
1413  show_image(im, "Original", 1);
1414  show_image(gray, "Gray", 1);
1415  show_image(c1, "C1", 1);
1416  show_image(c2, "C2", 1);
1417  show_image(c3, "C3", 1);
1418  show_image(c4, "C4", 1);
1419 #ifdef OPENCV
1420  while(1){
1421  image aug = random_augment_image(im, 0, .75, 320, 448, 320, 320);
1422  show_image(aug, "aug", 1);
1423  free_image(aug);
1424 
1425 
1426  float exposure = 1.15;
1427  float saturation = 1.15;
1428  float hue = .05;
1429 
1430  image c = copy_image(im);
1431 
1432  float dexp = rand_scale(exposure);
1433  float dsat = rand_scale(saturation);
1434  float dhue = rand_uniform(-hue, hue);
1435 
1436  distort_image(c, dhue, dsat, dexp);
1437  show_image(c, "rand", 1);
1438  printf("%f %f %f\n", dhue, dsat, dexp);
1439  free_image(c);
1440  cvWaitKey(0);
1441  }
1442 #endif
1443 }
1444 
1445 
1446 image load_image_stb(char *filename, int channels)
1447 {
1448  int w, h, c;
1449  unsigned char *data = stbi_load(filename, &w, &h, &c, channels);
1450  if (!data) {
1451  fprintf(stderr, "Cannot load image \"%s\"\nSTB Reason: %s\n", filename, stbi_failure_reason());
1452  exit(0);
1453  }
1454  if(channels) c = channels;
1455  int i,j,k;
1456  image im = make_image(w, h, c);
1457  for(k = 0; k < c; ++k){
1458  for(j = 0; j < h; ++j){
1459  for(i = 0; i < w; ++i){
1460  int dst_index = i + w*j + w*h*k;
1461  int src_index = k + c*i + c*w*j;
1462  im.data[dst_index] = (float)data[src_index]/255.;
1463  }
1464  }
1465  }
1466  free(data);
1467  return im;
1468 }
1469 
1470 image load_image(char *filename, int w, int h, int c)
1471 {
1472 #ifdef OPENCV
1473  image out = load_image_cv(filename, c);
1474 #else
1475  image out = load_image_stb(filename, c);
1476 #endif
1477 
1478  if((h && w) && (h != out.h || w != out.w)){
1479  image resized = resize_image(out, w, h);
1480  free_image(out);
1481  out = resized;
1482  }
1483  return out;
1484 }
1485 
1486 image load_image_color(char *filename, int w, int h)
1487 {
1488  return load_image(filename, w, h, 3);
1489 }
1490 
1492 {
1493  image out = make_image(m.w, m.h, 1);
1494  int i;
1495  for(i = 0; i < m.h*m.w; ++i){
1496  out.data[i] = m.data[i+l*m.h*m.w];
1497  }
1498  return out;
1499 }
1501 {
1502  int i, j, k;
1503  for(i =0 ; i < m.c; ++i){
1504  for(j =0 ; j < m.h; ++j){
1505  for(k = 0; k < m.w; ++k){
1506  printf("%.2lf, ", m.data[i*m.h*m.w + j*m.w + k]);
1507  if(k > 30) break;
1508  }
1509  printf("\n");
1510  if(j > 30) break;
1511  }
1512  printf("\n");
1513  }
1514  printf("\n");
1515 }
1516 
1518 {
1519  int color = 1;
1520  int border = 1;
1521  int h,w,c;
1522  w = ims[0].w;
1523  h = (ims[0].h + border) * n - border;
1524  c = ims[0].c;
1525  if(c != 3 || !color){
1526  w = (w+border)*c - border;
1527  c = 1;
1528  }
1529 
1530  image filters = make_image(w, h, c);
1531  int i,j;
1532  for(i = 0; i < n; ++i){
1533  int h_offset = i*(ims[0].h+border);
1534  image copy = copy_image(ims[i]);
1535  //normalize_image(copy);
1536  if(c == 3 && color){
1537  embed_image(copy, filters, 0, h_offset);
1538  }
1539  else{
1540  for(j = 0; j < copy.c; ++j){
1541  int w_offset = j*(ims[0].w+border);
1542  image layer = get_image_layer(copy, j);
1543  embed_image(layer, filters, w_offset, h_offset);
1544  free_image(layer);
1545  }
1546  }
1547  free_image(copy);
1548  }
1549  return filters;
1550 }
1551 
1553 {
1554  int color = 1;
1555  int border = 1;
1556  int h,w,c;
1557  int size = ims[0].h;
1558  h = size;
1559  w = (ims[0].w + border) * n - border;
1560  c = ims[0].c;
1561  if(c != 3 || !color){
1562  h = (h+border)*c - border;
1563  c = 1;
1564  }
1565 
1566  image filters = make_image(w, h, c);
1567  int i,j;
1568  for(i = 0; i < n; ++i){
1569  int w_offset = i*(size+border);
1570  image copy = copy_image(ims[i]);
1571  //normalize_image(copy);
1572  if(c == 3 && color){
1573  embed_image(copy, filters, w_offset, 0);
1574  }
1575  else{
1576  for(j = 0; j < copy.c; ++j){
1577  int h_offset = j*(size+border);
1578  image layer = get_image_layer(copy, j);
1579  embed_image(layer, filters, w_offset, h_offset);
1580  free_image(layer);
1581  }
1582  }
1583  free_image(copy);
1584  }
1585  return filters;
1586 }
1587 
1588 void show_image_normalized(image im, const char *name)
1589 {
1590  image c = copy_image(im);
1591  normalize_image(c);
1592  show_image(c, name, 1);
1593  free_image(c);
1594 }
1595 
1596 void show_images(image *ims, int n, char *window)
1597 {
1598  image m = collapse_images_vert(ims, n);
1599  /*
1600  int w = 448;
1601  int h = ((float)m.h/m.w) * 448;
1602  if(h > 896){
1603  h = 896;
1604  w = ((float)m.w/m.h) * 896;
1605  }
1606  image sized = resize_image(m, w, h);
1607  */
1608  normalize_image(m);
1609  save_image(m, window);
1610  show_image(m, window, 1);
1611  free_image(m);
1612 }
1613 
1615 {
1616  if(m.data){
1617  free(m.data);
1618  }
1619 }
void saturate_exposure_image(image im, float sat, float exposure)
Definition: image.c:1342
void random_distort_image(image im, float hue, float saturation, float exposure)
Definition: image.c:1334
void saturate_image(image im, float sat)
Definition: image.c:1290
void rgb_to_yuv(image im)
Definition: image.c:1092
void transpose_image(image im)
Definition: image.c:312
image resize_min(image im, int min)
Definition: image.c:1001
image letterbox_image(image im, int w, int h)
Definition: image.c:964
void composite_image(image source, image dest, int dx, int dy)
Definition: image.c:92
float rand_scale(float s)
Definition: utils.c:708
void constrain_image(image im)
Definition: image.c:456
STBIDEF const char * stbi_failure_reason(void)
image blend_image(image fore, image back, float alpha)
Definition: image.c:1238
void normalize_image(image p)
Definition: image.c:465
image collapse_images_vert(image *ims, int n)
Definition: image.c:1517
void print_image(image m)
Definition: image.c:1500
float rad
Definition: darknet.h:506
float h
Definition: darknet.h:520
#define TWO_PI
Definition: utils.h:15
int windows
Definition: image.c:13
float get_color(int c, int x, int max)
Definition: image.c:17
image get_image_layer(image m, int l)
Definition: image.c:1491
image load_image(char *filename, int w, int h, int c)
Definition: image.c:1470
image make_random_image(int w, int h, int c)
Definition: image.c:763
void draw_label(image a, int r, int c, image label, const float *rgb)
Definition: image.c:149
void rotate_image_cw(image im, int times)
Definition: image.c:328
void yuv_to_rgb(image im)
Definition: image.c:1069
float colors[6][3]
Definition: image.c:15
Definition: darknet.h:512
image ** load_alphabet()
Definition: image.c:223
image mask_to_rgb(image mask)
Definition: image.c:28
void copy_image_into(image src, image dest)
Definition: image.c:514
void save_image_png(image im, const char *name)
Definition: image.c:700
image border_image(image a, int border)
Definition: image.c:106
image center_crop_image(image im, int w, int h)
Definition: image.c:796
image rotate_image(image im, float rad)
Definition: image.c:824
image tile_images(image a, image b, int dx)
Definition: image.c:122
image binarize_image(image im)
Definition: image.c:1279
void show_images(image *ims, int n, char *window)
Definition: image.c:1596
float w
Definition: darknet.h:520
int h
Definition: darknet.h:514
void ghost_image(image source, image dest, int dx, int dy)
Definition: image.c:380
void draw_bbox(image a, box bbox, int w, float r, float g, float b)
Definition: image.c:210
image random_crop_image(image im, int w, int h)
Definition: image.c:1017
int constrain_int(int a, int min, int max)
Definition: utils.c:524
void distort_image(image im, float hue, float sat, float val)
Definition: image.c:1319
float x
Definition: darknet.h:520
void fill_cpu(int N, float ALPHA, float *X, int INCX)
Definition: blas.c:190
image grayscale_image(image im)
Definition: image.c:1212
void flip_image(image a)
Definition: image.c:349
void test_resize(char *filename)
Definition: image.c:1396
void normalize_image2(image p)
Definition: image.c:485
void rgb_to_hsv(image im)
Definition: image.c:1116
image copy_image(image p)
Definition: image.c:519
image make_image(int w, int h, int c)
Definition: image.c:756
image rotate_crop_image(image im, float rad, float s, int w, int h, float dx, float dy, float aspect)
Definition: image.c:805
int best_3d_shift_r(image a, image b, int min, int max)
Definition: image.c:881
image get_label(image **characters, char *string, int size)
Definition: image.c:132
void fill_image(image m, float s)
Definition: image.c:843
void free_image(image m)
Definition: image.c:1614
float three_way_max(float a, float b, float c)
Definition: image.c:1059
image image_distance(image a, image b)
Definition: image.c:365
void censor_image(image im, int dx, int dy, int w, int h)
Definition: image.c:411
void exposure_image(image im, float sat)
Definition: image.c:1311
void hsv_to_rgb(image im)
Definition: image.c:1153
image threshold_image(image im, float thresh)
Definition: image.c:1228
void draw_box(image a, int x1, int y1, int x2, int y2, float r, float g, float b)
Definition: image.c:166
void draw_box_width(image a, int x1, int y1, int x2, int y2, int w, float r, float g, float b)
Definition: image.c:202
image collapse_images_horz(image *ims, int n)
Definition: image.c:1552
float dist_array(float *a, float *b, int n, int sub)
Definition: utils.c:538
int show_image(image p, const char *name, int ms)
Definition: image.c:575
void translate_image(image m, float s)
Definition: image.c:849
void hue_image(image im, float hue)
Definition: image.c:1298
box bbox
Definition: darknet.h:524
float dx
Definition: darknet.h:507
STBIDEF stbi_uc * stbi_load(char const *filename, int *x, int *y, int *channels_in_file, int desired_channels)
float rand_normal()
Definition: utils.c:654
image float_to_image(int w, int h, int c, float *data)
Definition: image.c:774
int c
Definition: darknet.h:515
int w
Definition: darknet.h:513
void composite_3d(char *f1, char *f2, char *out, int delta)
Definition: image.c:913
image load_image_color(char *filename, int w, int h)
Definition: image.c:1486
STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes)
image resize_max(image im, int max)
Definition: image.c:985
void save_image(image im, const char *name)
Definition: image.c:717
int best_3d_shift(image a, image b, int min, int max)
Definition: image.c:895
image load_image_stb(char *filename, int channels)
Definition: image.c:1446
void letterbox_image_into(image im, int w, int h, image boxed)
Definition: image.c:948
float three_way_min(float a, float b, float c)
Definition: image.c:1064
void scale_image_channel(image im, int c, float v)
Definition: image.c:1255
float scale
Definition: darknet.h:505
image resize_image(image im, int w, int h)
Definition: image.c:1351
void translate_image_channel(image im, int c, float v)
Definition: image.c:1267
float aspect
Definition: darknet.h:509
void embed_image(image source, image dest, int dx, int dy)
Definition: image.c:428
void draw_detections(image im, detection *dets, int num, float thresh, char **names, image **alphabet, int classes)
Definition: image.c:239
image collapse_image_layers(image source, int border)
Definition: image.c:441
float y
Definition: darknet.h:520
void grayscale_image_3c(image im)
Definition: image.c:1194
void show_image_layers(image p, char *name)
Definition: image.c:727
image random_augment_image(image im, float angle, float aspect, int low, int high, int w, int h)
Definition: image.c:1052
float mag_array(float *a, int n)
Definition: utils.c:574
int rand_int(int min, int max)
Definition: utils.c:642
float rand_uniform(float min, float max)
Definition: utils.c:698
image crop_image(image im, int dx, int dy, int w, int h)
Definition: image.c:861
void place_image(image im, int w, int h, int dx, int dy, image canvas)
Definition: image.c:781
void rgbgr_image(image im)
Definition: image.c:527
augment_args random_augment_args(image im, float angle, float aspect, int low, int high, int w, int h)
Definition: image.c:1025
list classes
Definition: voc_label.py:9
Definition: darknet.h:538
void scale_image(image m, float s)
Definition: image.c:855
void show_image_normalized(image im, const char *name)
Definition: image.c:1588
float dy
Definition: darknet.h:508
void show_image_collapsed(image p, char *name)
Definition: image.c:739
Definition: darknet.h:519
Definition: darknet.h:119
void blocky_image(image im, int s)
Definition: image.c:399
float * data
Definition: darknet.h:516
image make_empty_image(int w, int h, int c)
Definition: image.c:746