/[opencvs]/eyes/cyclone_pick.c
ViewVC logotype

Contents of /eyes/cyclone_pick.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations)
Thu Mar 6 06:43:51 2014 UTC (4 years, 4 months ago) by hib
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +2 -1 lines
File MIME type: text/plain
Got qi working and released.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <string.h>
5 #include <sys/resource.h>
6 #include <wand/MagickWand.h>
7
8
9 #include "uthash.h"
10
11 /*
12 Cycle_pick is meant to be run in a directory where there is a ri folder containing images and a
13 rk folder containing the alpha.
14
15 Then a list of files is sent in and cycle_pick prints out values trying to find the best parameters
16 where the parameters are for how much the area is enclosed
17
18
19 But if the file has | in it - then it is assumed to be other picks
20 */
21
22
23
24
25 int bits[] = {0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1};
26
27
28
29 int read_image(char *name,ssize_t *pwidth,ssize_t *pheight,
30 unsigned short **prgbbuf)
31 {
32
33
34 MagickPixelPacket input_pixel;
35 MagickWand *input_wand = NULL;
36 PixelWand *c_wand = NULL;
37 PixelWand *c2_wand = NULL;
38 MagickBooleanType status;
39 PixelIterator *input_iterator;
40 PixelWand **input_pixels;
41 register ssize_t x;
42 ssize_t y;
43
44
45 /* read the input color */
46 input_wand =NewMagickWand();
47 MagickReadImage(input_wand,name);
48 ssize_t width,height;
49 width = MagickGetImageWidth(input_wand);
50 height = MagickGetImageHeight(input_wand);
51 int number_of_points;
52 number_of_points=0;
53 unsigned short *rgbbuf;
54
55 rgbbuf= (unsigned short *)malloc(width*height*sizeof(unsigned short)*3);
56 if (!rgbbuf) {fprintf(stderr,"memory\n"); exit(-1);}
57
58 #define ThrowWandException(wand) \
59 { \
60 char \
61 *description; \
62 \
63 ExceptionType \
64 severity; \
65 \
66 description=MagickGetException(wand,&severity); \
67 (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
68 description=(char *) MagickRelinquishMemory(description); \
69 exit(-1); \
70 }
71
72
73 input_iterator=NewPixelIterator(input_wand);
74 if ((input_iterator == (PixelIterator *) NULL) )
75 ThrowWandException(input_wand);
76
77 for (y=0; y < (ssize_t) height; y++)
78 {
79 input_pixels=PixelGetNextIteratorRow(input_iterator,&width);
80 if ((input_pixels == (PixelWand **) NULL))
81 break;
82 for (x=0; x < (ssize_t) width; x++)
83 {
84 unsigned short *rl;
85 PixelGetMagickColor(input_pixels[x],&input_pixel);
86 rl=rgbbuf + ((y*width)+x)*3;
87 *(rl++) = input_pixel.red;
88 *(rl++) = input_pixel.green;
89 *(rl++) = input_pixel.blue;
90 }
91 }
92 if (y < (ssize_t) MagickGetImageHeight(input_wand))
93 ThrowWandException(input_wand);
94 input_iterator=DestroyPixelIterator(input_iterator);
95 input_wand=DestroyMagickWand(input_wand);
96
97
98
99
100
101
102 *prgbbuf = rgbbuf;
103 *pwidth = width;
104 *pheight=height;
105
106
107
108 return (0);
109 }
110
111
112
113
114
115
116 int convert_rgb(MagickWand *input_wand,ssize_t width,ssize_t height, unsigned short *rgbbuf)
117 {
118
119
120 MagickPixelPacket input_pixel;
121 PixelWand *c_wand = NULL;
122 PixelWand *c2_wand = NULL;
123 MagickBooleanType status;
124 PixelIterator *input_iterator;
125 PixelWand **input_pixels;
126 register ssize_t x;
127 ssize_t y;
128
129 int number_of_points;
130 number_of_points=0;
131
132 #define ThrowWandException(wand) \
133 { \
134 char \
135 *description; \
136 \
137 ExceptionType \
138 severity; \
139 \
140 description=MagickGetException(wand,&severity); \
141 (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
142 description=(char *) MagickRelinquishMemory(description); \
143 exit(-1); \
144 }
145
146
147 input_iterator=NewPixelIterator(input_wand);
148 if ((input_iterator == (PixelIterator *) NULL) )
149 ThrowWandException(input_wand);
150
151 for (y=0; y < (ssize_t) height; y++)
152 {
153 input_pixels=PixelGetNextIteratorRow(input_iterator,&width);
154 if ((input_pixels == (PixelWand **) NULL))
155 break;
156 for (x=0; x < (ssize_t) width; x++)
157 {
158 unsigned short *rl;
159 PixelGetMagickColor(input_pixels[x],&input_pixel);
160 rl=rgbbuf + ((y*width)+x)*3;
161 *(rl++) = input_pixel.red;
162 *(rl++) = input_pixel.green;
163 *(rl++) = input_pixel.blue;
164 }
165 }
166 if (y < (ssize_t) MagickGetImageHeight(input_wand))
167 ThrowWandException(input_wand);
168 input_iterator=DestroyPixelIterator(input_iterator);
169
170 return (0);
171 }
172
173
174
175
176
177 void make_stack_really_big() {
178 const rlim_t stacksize = 2000*1024*1024; // 2 gigabytes
179 struct rlimit rl;
180 int result;
181 result = getrlimit(RLIMIT_STACK, &rl);
182 if (result == 0)
183 {
184 if (rl.rlim_cur < stacksize)
185 {
186 rl.rlim_cur = stacksize;
187 result = setrlimit(RLIMIT_STACK, &rl);
188 if (result != 0)
189 {
190 fprintf(stderr, "setrlimit returned result = %d\n", result);
191 exit(-1);
192 }
193 }
194 }
195 else {
196 fprintf(stderr, "getrlimit returned result = %d\n", result);
197 exit(-1);
198 }
199 }
200
201
202
203
204
205
206
207
208 void make_demonstration_image(
209 unsigned short *quad_buf,
210 ssize_t quad_width,
211 ssize_t quad_height,
212 ssize_t local_width,
213 ssize_t local_height,
214 unsigned short *source_buf,
215 unsigned short *alpha_buf,
216 double average_diff,
217 double average_alpha,
218 char *file_name,
219 double xoffset,
220 double yoffset,
221 double scale,
222 double desired_r,
223 double desired_g,
224 double desired_b) {
225 ssize_t width,height;
226 int quad_xoffset;
227 int quad_yoffset;
228 width = quad_width;
229 height = quad_height;
230 double one_over_scale = 1.0 / scale;
231
232 quad_xoffset = 0;
233 quad_yoffset = 0;
234
235 /* see if we need to make the height bigger to get all of the images together */
236 int testx,testy;
237 testx = (0.0 + xoffset)*scale;
238 if (testx < quad_xoffset) {
239 quad_xoffset = testx;
240 }
241 if (testx > width) {
242 width = testx;
243 }
244 testx = ((double)(local_width-1) +xoffset)*scale;
245 if (testx < quad_xoffset) {
246 quad_xoffset = testx;
247 }
248 if (testx > width) {
249 width = testx;
250 }
251
252 testy = (0.0 +yoffset)*scale;
253 if (testy < quad_yoffset) {
254 quad_yoffset = testy;
255 }
256 if (testy > height) {
257 height = testy;
258 }
259 testy = ((double)(local_height-1) +yoffset)*scale;
260 if (testy < quad_yoffset) {
261 quad_yoffset = testx;
262 }
263 if (testy > height) {
264 height = testy;
265 }
266 /* Expand the width and height appropriately so we can fit all images in */
267 width -= quad_xoffset;
268 height -= quad_yoffset;
269 fprintf(stderr,"original w,h: %d,%d offset %d,%d wh %d,%d\n",(int)quad_width,(int)quad_height,quad_xoffset,quad_yoffset,(int)width,(int)height);
270
271 #define ThrowWandException(wand) \
272 { \
273 char \
274 *description; \
275 \
276 ExceptionType \
277 severity; \
278 \
279 description=MagickGetException(wand,&severity); \
280 (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
281 description=(char *) MagickRelinquishMemory(description); \
282 exit(-1); \
283 }
284
285 MagickWand *m_wand;
286 PixelIterator *iterator;
287 PixelWand *c_wand;
288 PixelWand **pixels;
289 MagickPixelPacket pixel;
290
291 m_wand = NewMagickWand();
292 c_wand = NewPixelWand();
293 PixelSetColor(c_wand,"black"); /* for now */
294 MagickNewImage(m_wand,width,height,c_wand);
295 MagickSetImageChannelDepth(m_wand, AllChannels, 16);
296 MagickSetImageDepth(m_wand, 16);
297 iterator=NewPixelIterator(m_wand);
298 if ((iterator == (PixelIterator *) NULL) )
299 ThrowWandException(m_wand);
300 register ssize_t x;
301 ssize_t y;
302 for (y=0; y < (ssize_t) height; y++)
303 {
304 pixels=PixelGetNextIteratorRow(iterator,&width);
305 if ((pixels == (PixelWand **) NULL))
306 break;
307 for (x=0; x < (ssize_t) width; x++)
308 {
309 PixelGetMagickColor(pixels[x],&pixel);
310 int r,g,b;
311 r=0;g=0;b=0;
312
313 /* add the quad in */
314 int quad_x,quad_y;
315 quad_x = x + quad_xoffset;
316 quad_y = y + quad_yoffset;
317
318 if ((quad_x >= 0)&&(quad_x < quad_width)&&(quad_y >= 0)&&(quad_y < quad_height)) {
319 unsigned short *rl;
320 rl = quad_buf+((quad_y*quad_width)+quad_x)*3;
321 if (*rl) {
322 r = desired_r * 256;
323 g = desired_g * 256;
324 b = desired_b * 256;
325 }
326 }
327 int source_x,source_y;
328 source_x = ((double)(quad_x)) * one_over_scale - xoffset;
329 source_y = ((double)(quad_y)) * one_over_scale - yoffset;
330
331 unsigned int alpha;
332 /* find the alpha */
333 alpha = alpha_buf[((source_y*local_width)+source_x)*3];
334
335 if (alpha>=32768) {
336 alpha = 50000 + (alpha-32768)*(65535-50000)/(65536);
337 }
338 else {
339 alpha = 33000 + (alpha*20000)/65536;
340 }
341 if (alpha>65535) alpha=65535;
342 if (alpha<0) alpha=0;
343
344 /* find the source r,g,b */
345 unsigned int source_r,source_g,source_b;
346 unsigned short *source_rgbp = source_buf+((source_y*local_width)+source_x)*3;
347 source_r = *(source_rgbp++);
348 source_g = *(source_rgbp++);
349 source_b = *(source_rgbp++);
350
351 r = ((source_r * alpha) + r * (65536-alpha))/65536;
352 g = ((source_g * alpha) + g * (65536-alpha))/65536;
353 b = ((source_b * alpha) + b * (65536-alpha))/65536;
354
355 pixel.red=r;
356 pixel.green=g;
357 pixel.blue=b;
358 PixelSetMagickColor(pixels[x],&pixel);
359 }
360 (void) PixelSyncIterator(iterator);
361 }
362 if (y < (ssize_t) MagickGetImageHeight(m_wand))
363 ThrowWandException(m_wand);
364 iterator=DestroyPixelIterator(iterator);
365
366
367 /*
368 Write the image then destroy it.
369 */
370
371 char oname[20000];
372 sprintf(oname,"%18.18qd_%lf_%lf_%s_%lf_%lf_%lf.png",(long long)(average_diff*average_diff+average_alpha*average_alpha),
373 average_diff,average_alpha,file_name,xoffset,yoffset,scale);
374
375 MagickBooleanType status;
376 status=MagickWriteImages(m_wand,oname,MagickTrue);
377 if (status == MagickFalse)
378 ThrowWandException(m_wand);
379 m_wand=DestroyMagickWand(m_wand);
380 }
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422 /* usage - input file r g b iterations
423 With standard input being a list of filenames or
424 a list of the output of cycleone. For the output of cyclone, it makes
425 demonstration images so that you can see how the alogrithm picked the spot.
426
427 */
428 int main(int argc,char **argv)
429 {
430 /* set the stack limit to 500 megabytes */
431 make_stack_really_big();
432
433 /* seed1 ip_Address fname */
434 char *iname=argv[1];
435 double desired_r = atof(argv[2]);
436 double desired_g = atof(argv[3]);
437 double desired_b = atof(argv[4]);
438 int iterations = atoi(argv[5]);
439
440 unsigned char *otherrand;
441 int other;
442 unsigned short *rgbbuf;
443 int number_of_points;
444 int number_second_points;
445 struct point *points_to_look_at;
446 struct point *second_points_to_look_at;
447 struct point *end_points_to_look_at;
448 struct point *temp_points;
449 int number_end_points;
450 MagickWand *m_wand = NULL;
451 PixelWand *c_wand = NULL;
452 PixelWand *c2_wand = NULL;
453 MagickPixelPacket pixel;
454
455 MagickWandGenesis();
456 ssize_t width,height;
457
458 unsigned short *source_buffer;
459 unsigned short *alpha_buffer;
460 source_buffer = (unsigned short *)malloc(sizeof(short)*3*512*20*512*20);
461 alpha_buffer = (unsigned short *)malloc(sizeof(short)*3*512*20*512*20);
462
463 read_image(iname,&width,&height,&rgbbuf);
464
465 char buf[20000];
466 while (gets(buf)) {
467 char file_name[10000];
468 double average_diff;
469 double average_alpha;
470 double xoffset;
471 double yoffset;
472 double scale;
473 int direct_flag = (strchr(buf,'|')?1:0);
474
475 char source_name[10000],alpha_name[10000];
476 if (direct_flag) { /* if this is a pipe delimited output of cyclone_pick being pumped back in */
477 char buf2[10000];
478 /* format is <score>|<average_diff>|<average_alpha>|<file_name>|<xoffset>|<yoffset>|<scale> */
479 field(buf,file_name,3);
480 field(buf,buf2,1); average_diff = atof(buf2);
481 field(buf,buf2,2); average_alpha = atof(buf2);
482 field(buf,buf2,4); xoffset = atof(buf2);
483 field(buf,buf2,5); yoffset = atof(buf2);
484 field(buf,buf2,6); scale = atof(buf2);
485 }
486 else {
487 strcpy(file_name,buf);
488 }
489
490 /* build the filenames for the tile images to use */
491 sprintf(source_name,"../ri/%s",file_name);
492 sprintf(alpha_name,"../rk/%s",file_name);
493
494 int local_width;
495 int local_height;
496 MagickWand *source_wand = NULL;
497 MagickWand *alpha_wand = NULL;
498 source_wand =NewMagickWand();
499 alpha_wand =NewMagickWand();
500 MagickReadImage(source_wand,source_name);
501 MagickReadImage(alpha_wand,alpha_name);
502 local_width = MagickGetImageWidth(source_wand);
503 local_height = MagickGetImageHeight(source_wand);
504 if ((local_width != 512)||(local_height != 512)) {
505 fprintf(stderr,"%s is not 512x512. exiting\n",source_name);
506 exit(-1);
507 }
508 local_width = MagickGetImageWidth(alpha_wand);
509 local_height = MagickGetImageHeight(alpha_wand);
510 if ((local_width != 512)||(local_height != 512)) {
511 fprintf(stderr,"%s is not 512x512. exiting\n",alpha_name);
512 exit(-1);
513 }
514
515 /* convert the wand into rgb pixels so it is easier to do random io on them */
516 convert_rgb(source_wand,local_width,local_height,source_buffer);
517 convert_rgb(alpha_wand,local_width,local_height,alpha_buffer);
518
519 if (!direct_flag) { /* we need to find various fits. */
520
521 int i;
522 for (i=0;i<iterations;i++) {
523 MagickWand *source_scaled_wand;
524 MagickWand *alpha_scaled_wand;
525 xoffset = ((double)(rand()%(2*1024*1024)) ) /(1024.*1024.)-1.; /* -1 to 1 */
526 yoffset = ((double)(rand()%(2*1024*1024)) ) /(1024.*1024.)-1.; /* -1 to 1 */
527 scale = ((double)(rand()%(1024*1024)) ) /(1024.*1024.); /* 0 to 1 */
528 xoffset *= (double)(local_width);
529 yoffset *= (double)(local_height);
530 scale = 0.3333 + scale*3.0;
531 scale = scale * scale; /* so scale is between 1/9 and 9 */
532 double one_over_scale = 1.0 / scale;
533
534 int scaled_width,scaled_height;
535 scaled_width = (((double)(local_width))*scale);
536 scaled_height = ((double)(local_height)*scale);
537
538 /* First - see if the coordinates fit - because many don't fit, no need to look further */
539 /* and also see if the image has alphas in the coverage area */
540 int x,y;
541 int flag;
542 flag=1;
543 for (y=0;y<height;y++) { /*x and y are on our original image */
544 for (x=0;x<width;x++) {
545 unsigned short *rgbp = rgbbuf+((y*width)+x)*3;
546 if (*rgbp) { /* if we are not black on the source square */
547 int sourcex,sourcey;
548 sourcex = ((double)(x))*one_over_scale - xoffset;
549 sourcey = ((double)(y))*one_over_scale - yoffset;
550 if ((sourcex<0)||(sourcey<0)||(sourcex>=local_width)||(sourcey>=local_height)) { /* out of bounds */
551 flag=0;
552 break;
553 }
554 /* in bounds - see if we have a value */
555 unsigned short *alphap = alpha_buffer+((sourcey*local_width)+sourcex)*3;
556 if (!(*alphap)) { /* if this spot is black */
557 flag=0;
558 break;
559 }
560 /* well, this pixel on the source quad has a correlated pixel on the image here, so we are ok.
561 but we need one for every pixel to be considered good */
562 } /* if we have a pixel to check for in the source quad */
563 } /* while we go through the x coordinates of each item in the source quad */
564 if (!flag) break;
565 } /* while we go throught the y coordinates */
566 if (!flag) {
567 continue; /* this image did not fit */
568 }
569
570 /* OK, the image fit. now we are going to get two factors:
571 1. the ratio percentage of the image that fits well - if we clip off the inside green, then it doesnt fit well
572 2. the closeness of the image to the original color - in distance squared - with smaller being better
573 these two factors will help us decide what images to choose
574 */
575
576 {
577 double column_rtally; /* tally of all added up numbers for all columns. This is added first, so we are adding like scale of numbers
578 - like scale helps with the accuracy of things */
579 double column_gtally;
580 double column_btally;
581 double row_rtally; /* tally of all columns for each row. This is the complete tally - for red. */
582 double row_gtally;
583 double row_btally;
584 double row_size; /* number of pixelz that we have fopr our quadaleteral */
585 double column_size; /* used to build row_size */
586
587 row_rtally = 0.;
588 row_gtally = 0.;
589 row_btally = 0.;
590 row_size = 0.;
591
592 for (y=0;y<height;y++) {
593 column_rtally = 0.;
594 column_gtally = 0.;
595 column_btally = 0.;
596 column_size = 0.;
597 for (x=0;x<width;x++) {
598 unsigned short *rgbp = rgbbuf+((y*width)+x)*3;
599 int sourcex,sourcey;
600 sourcex = ((double)(x))*one_over_scale - xoffset;
601 sourcey = ((double)(y))*one_over_scale - yoffset;
602
603 if (*rgbp) { /* if we are not black on the source square */
604 column_size++;
605 if ((sourcex<0)||(sourcey<0)||(sourcex>=local_width)||(sourcey>=local_height)) { /* out of bounds */
606 fprintf(stderr,"impossible out of bounds\n");
607 exit(-1);
608 }
609
610 /* figure out color average so we can compare to the pixel average */
611 unsigned short *source_rgbp = source_buffer+((sourcey*local_width)+sourcex)*3;
612 column_rtally += *(source_rgbp++);
613 column_gtally += *(source_rgbp++);
614 column_btally += *(source_rgbp++);
615 } /* if this is part of our area */
616 } /* for each x */
617 row_size += column_size;
618 row_rtally += column_rtally;
619 row_gtally += column_gtally;
620 row_btally += column_btally;
621 } /* for each y */
622
623
624 double average_r;
625 double average_g;
626 double average_b;
627 if (row_size != 0.) {
628 average_r = (row_rtally / row_size);
629 average_g = (row_gtally / row_size);
630 average_b = (row_btally / row_size);
631 double r,g,b;
632 int diff;
633 r = (average_r / 256.);
634 g = (average_g / 256.);
635 b = (average_b / 256.);
636 diff = (r-desired_r)*(r-desired_r) +
637 (g-desired_g)*(g-desired_g) +
638 (b-desired_b)*(b-desired_b);
639 average_diff= diff;
640 }
641 else {
642 average_diff = 1000000;
643 }
644 } /* computing average_diff */
645
646 {
647 double column_atally; /* alpha is really the amount that the necessary image does not fit in the square. */
648 double alpha_row_size; /* number of pixelz that we matched between the two stuff. */
649 double alpha_column_size;
650 double row_atally;
651 alpha_row_size = 0;
652 row_atally = 0.;
653
654 for (y=0;y<local_height;y++) {
655 column_atally = 0.;
656 alpha_column_size = 0.;
657 for (x=0;x<local_width;x++) {
658 unsigned short *alphap = alpha_buffer+((y*local_width)+x)*3;
659
660
661 if ((*alphap)>=32768) { /* if this spot is considered an essential part of the picture */
662 alpha_column_size++;
663
664 int rgbx,rgby;
665 rgbx = ( ((double)(x))+xoffset)*scale;
666 rgby = ( ((double)(y))+yoffset)*scale;
667
668 if ((rgbx>=0)&&(rgby>=0)&&(rgbx<width)&&(rgby<height)) {
669 unsigned short *rgbp = rgbbuf+((rgby*width)+rgbx)*3;
670 if (*rgbp) { /* if we are showing the required alpha spot */
671 continue; /* great. go to the next pixel */
672 }
673 }
674
675 /* If we are here, either the required alpha spot is outside the range of the image, or the
676 required alpha spot is outside the quad boundary. Either way, we have an error compared to the
677 desired output.
678 This is done based on the alpha bounds, instead of based on the quad bounds on purpose because
679 before we just looked at things relative to the quad bounds, and images where the spot was outside
680 of the alpha complete scored perfect 0 for alpha difference. Bad Bad Bad.
681 */
682 column_atally+= (*alphap - 32768 + 256); /* bad bad bad - and gets worse the deeper we cut into the image */
683 } /* if the spot is essential part of the picture */
684 } /* for each x */
685 alpha_row_size += alpha_column_size;
686 row_atally += column_atally;
687 } /* for each y */
688
689
690 if (alpha_row_size != 0.) {
691 average_alpha = row_atally / alpha_row_size;
692 }
693 else {
694 average_alpha = 1000000000;
695 }
696 /* make alpha more important */
697 /* average_alpha = average_alpha *0.13; */
698 /* ^^^ fudge for ccyclone. Removed for antique*/
699 } /* block to compute alpha metric */
700
701 printf("%18.18qd|%lf|%lf|%s|%lf|%lf|%lf\n",(long long)(average_diff*average_diff+average_alpha*average_alpha),
702 average_diff,average_alpha,file_name,xoffset,yoffset,scale);
703
704 } /* for each of 1000 tries */
705 } /* BIG BIG IF - if we are estimating an image */
706 else {
707 make_demonstration_image(rgbbuf,width,height,local_width,local_height,source_buffer,alpha_buffer,average_diff,average_alpha,file_name,xoffset,yoffset,scale,
708 desired_r,desired_g,desired_b);
709 }
710 source_wand = DestroyMagickWand(source_wand);
711 alpha_wand = DestroyMagickWand(alpha_wand);
712 } /* for each file */
713
714
715 MagickWandTerminus();
716 return(0);
717 }
718

  ViewVC Help
Powered by ViewVC 1.1.5