image.c 38 KB

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