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

Contents of /eyes/eyes.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (show annotations)
Thu Mar 8 11:49:30 2012 UTC (6 years, 1 month ago) by hib
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +97 -2 lines
File MIME type: text/plain
building girl3 (jenni)
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <math.h>
5
6 #include "util.h"
7 #include "uthash.h"
8
9
10 struct close_struct {
11 char value[7];
12 UT_hash_handle hh;
13 };
14
15
16 struct pixel {
17 int used;
18 int width;
19 int height;
20 int bigbig; /* big size */
21 int wh; /* width * height */
22 int r;
23 int g;
24 int b;
25 int rmark;
26 int gmark;
27 int bmark;
28 double rnet;
29 double gnet;
30 double bnet;
31 double strength;
32 char *fname;
33 struct pixel *next;
34 };
35
36
37
38 struct tile {
39 int x;
40 int y;
41 int r;
42 int g;
43 int b;
44 struct pixel *pixel;
45 };
46
47
48 struct close_struct *too_close;
49
50
51 struct pixel *pixels[256][256][256]; /* r g b */
52
53 struct tile *tiles;
54 int width;
55 int length;
56
57 int fieldh(char *x,int fieldnum) {
58 while (fieldnum && *x) {
59 if ((*x == '|')||(*x == ' ')) fieldnum--;
60 x++;
61 }
62 int t;
63 t=0;
64 sscanf(x,"%x",&t);
65 return t;
66 }
67
68
69
70
71 int read_pixels(char *fname) {
72 int r,g,b;
73 for (r=0;r<256;r++)
74 for (g=0;g<256;g++)
75 for (b=0;b<256;b++)
76 pixels[r][g][b]=NULL;
77 FILE *xf;
78 xf = fopen(fname,"r");
79 if (!xf) {
80 fprintf(stderr,"cannot read %s\n",fname);
81 exit(-1);
82 }
83 char buf[100000];
84 while (fgets(buf,99999,xf)) {
85 buf[strlen(buf)-1]='\0'; /* get rid of newline */
86 char fn[10000];
87 struct pixel *pixel;
88 pixel = (struct pixel *)calloc(sizeof(struct pixel),1);
89
90 field(buf,fn,0);
91 pixel->fname = strdup(fn);
92 pixel->width=fieldi(buf,1);
93 pixel->height=fieldi(buf,2);
94 pixel->r=fieldh(buf,3);
95 pixel->g=fieldh(buf,4);
96 pixel->b=fieldh(buf,5);
97 int big;
98 if (pixel->width > pixel->height) big=pixel->width; else big=pixel->height;
99 pixel->bigbig=big*big;
100 pixel->wh = pixel->width * pixel->height;
101
102 pixel->next = pixels[pixel->r][pixel->g][pixel->b];
103 pixels[pixel->r][pixel->g][pixel->b] = pixel;
104 }
105 fclose(xf);
106 }
107
108
109
110
111 int read_source(char *fname,int xwidth,int xlength) {
112 width=xwidth;
113 length=xlength;
114 tiles = (struct tile *)calloc(sizeof(struct tile),width*length);
115 if (!tiles) {
116 fprintf(stderr,"memory bug\n");
117 exit(-1);
118 }
119 int x,y;
120 int r,g,b;
121 FILE *xf;
122 xf = fopen(fname,"r");
123 if (!xf) {
124 fprintf(stderr,"cannot read %s\n",fname);
125 exit(-1);
126 }
127 char buf[100000];
128 while (fgets(buf,99999,xf)) {
129 buf[strlen(buf)-1]='\0'; /* get rid of newline */
130 struct tile *tile;
131 x=fieldi(buf,0);
132 y=fieldi(buf,1);
133 r=fieldi(buf,2);
134 g=fieldi(buf,3);
135 b=fieldi(buf,4);
136 tile = tiles + (y*width+x);
137 tile->x = x;
138 tile->y = y;
139 tile->r = r;
140 tile->g = g;
141 tile->b = b;
142 }
143 fclose(xf);
144 }
145
146
147
148
149
150
151
152
153
154 int assign_pixels(char *fname) {
155 int range,x,y;
156 int r,g,b;
157 FILE *xf;
158 xf = fopen(fname,"r");
159 if (!xf) {
160 fprintf(stderr,"cannot read %s\n",fname);
161 exit(-1);
162 }
163 int xf2flag;
164 int seq=1;
165 FILE *xf2;
166
167
168 /* note - we come back here if we had stuff too close */
169 morework:
170 xf2flag = 0;
171 if (too_close) {
172 char bb[200];
173 sprintf(bb,"too_close%d.dat",seq);
174 xf2=fopen(bb,"w");
175 if (!xf2) {
176 fprintf(stderr,"cannopt open %s for writing\n",bb);
177 exit(-1);
178 }
179 }
180
181 char buf[100000];
182 while (fgets(buf,99999,xf)) {
183 buf[strlen(buf)-1]='\0'; /* get rid of newline */
184 struct tile *tile;
185 range=fieldi(buf,0);
186 x=fieldi(buf,1);
187 y=fieldi(buf,2);
188
189 /* find the tile */
190 tile = tiles + (y*width+x);
191 double radius;
192 double bigconstant = 1.0/(65536.+65536.+65536.); /* Special */
193
194 int rsquared;
195 int rtarget;
196 int gtarget;
197 int btarget;
198 rtarget=tile->r;
199 gtarget=tile->g;
200 btarget=tile->b;
201 double rt = rtarget;
202 double gt = gtarget;
203 double bt = btarget;
204 double oldradius=0.;
205 radius = 1.;
206 while (1) {
207 int rmin,rmax,gmin,gmax,bmin,bmax;
208 rmin = tile->r-radius; if (rmin<0) rmin=0;
209 rmax = tile->r+radius; if (rmax>255) rmax=255;
210 gmin = tile->g-radius; if (gmin<0) gmin=0;
211 gmax = tile->g+radius; if (gmax>255) gmax=255;
212 bmin = tile->b-radius; if (bmin<0) bmin=0;
213 bmax = tile->b+radius; if (bmax>255) bmax=255;
214 rsquared = radius*radius;
215 double oldrsquared = oldradius*oldradius;
216 double beststrength =1000000.;
217 struct pixel *bestpixel = NULL;
218 struct pixel *bestprevpixel = NULL;
219
220 for (r=rmin;r<=rmax;r++) {
221 for (g=gmin;g<=gmax;g++) {
222 for (b=bmin;b<=bmax;b++) {
223 int distance_squared = (r-rtarget)*(r-rtarget) +
224 (b-btarget)*(b-btarget) +
225 (g-gtarget)*(g-gtarget);
226 if ((distance_squared >= oldrsquared)&&(distance_squared < rsquared)) {
227 struct pixel *prevpixel;
228 struct pixel *pixel;
229 prevpixel=NULL;
230 pixel=pixels[r][g][b];
231 while (pixel) {
232 int wh = pixel->wh;
233 int bigbig = pixel->bigbig;
234 int bigbigmwh=bigbig-wh;
235 if (pixel->used) {
236 prevpixel = pixel;
237 pixel=pixel->next;
238 continue;
239 }
240 if (bigbigmwh==0) {
241 pixel->rmark=r;
242 pixel->gmark=g;
243 pixel->bmark=b;
244 pixel->rnet=r;
245 pixel->gnet=g;
246 pixel->bnet=b;
247 pixel->strength = distance_squared; /* nice- saves time */
248 }
249 else {
250
251 /*
252 pixel->rmark = targetr - ((wh * r)/bigbig)
253 * bigbig / (bigbigmwh);
254 Well, we can reduce some of this */
255
256 pixel->rmark = (rtarget * bigbig - wh * r) / (bigbigmwh);
257 pixel->gmark = (gtarget * bigbig - wh * g) / (bigbigmwh);
258 pixel->bmark = (btarget * bigbig - wh * b) / (bigbigmwh);
259 if (pixel->rmark <0) pixel->rmark = 0;
260 if (pixel->rmark >255) pixel->rmark = 255;
261 if (pixel->gmark <0) pixel->gmark = 0;
262 if (pixel->gmark >255) pixel->gmark = 255;
263 if (pixel->bmark <0) pixel->bmark = 0;
264 if (pixel->bmark >255) pixel->bmark = 255;
265
266 pixel->rnet = (double)( r * wh + pixel->rmark * bigbigmwh) / (double)(bigbig);
267 pixel->gnet = (double)( g * wh + pixel->gmark * bigbigmwh) / (double)(bigbig);
268 pixel->bnet = (double)( b * wh + pixel->bmark * bigbigmwh) / (double)(bigbig);
269 /* high strength is bad. low is good!
270 strength will use the distance (squared)
271 for comaprison between the mark color and the
272 target color. But there might be two
273 pictures with the same distance , so we use a fractional
274 quality indicator in addition to strength to show the difference
275 between rgb and the mark rgb. The best fit will
276 have no distance.
277 */
278 /* old distance calculation
279 pixel->strength = (rt-pixel->rnet)*(rt-pixel->rnet) +
280 (gt-pixel->gnet)*(gt-pixel->gnet) +
281 (bt-pixel->bnet)*(bt-pixel->bnet);
282 OK - so in this case, the strength is equal to the
283 best distinace - but the distance could be lopsided.
284 because there might be an r difference really great
285 compared to the g and be difference. So instead.
286 if we make strength the greatest of the distance, we then
287 will make it more likely that a box is within the hue.
288 and we don't need to multiplybut that avoids absolute values
289 hopefully this will help get rid of the redness on black tiles.
290 */
291 double s = (rt-pixel->rnet)*(rt-pixel->rnet);
292 double sg = (gt-pixel->gnet)*(gt-pixel->gnet);
293 if (sg>s) s=sg;
294 sg = (bt-pixel->bnet)*(bt-pixel->bnet);
295 if (sg >s) s=sg;
296 pixel->strength = sg;
297 double strength2 = (r-pixel->rmark)*(r-pixel->rmark) +
298 (g-pixel->gmark)*(g-pixel->gmark) +
299 (b-pixel->bmark)*(b-pixel->bmark);
300 // fprintf(stdout,"S %lf %lf\n",pixel->strength,strength2*bigconstant);
301 pixel->strength = (double)((int)(pixel->strength)+0)
302 + ((double)strength2) * bigconstant; /* = / 65536*3 */
303 } /* if we are not perfect */
304 if (pixel->strength < beststrength) {
305 beststrength = pixel->strength;
306 bestpixel = pixel;
307 bestprevpixel = prevpixel;
308 }
309 prevpixel = pixel;
310 pixel=pixel->next;
311 } /* while looking through all pixels that match the current color */
312 } /* if we are in the radius */
313 } /* for each blue */
314 } /* for each green */
315 } /* for each red */
316 if (bestpixel) { /* we got one */
317 tile->pixel = bestpixel;
318 bestpixel->used=1;
319 /* if (bestprevpixel) {
320 bestprevpixel->next = bestpixel->next;
321 }
322 else {
323 printf("bp %lx to %lx\n", pixels[bestpixel->r][bestpixel->g][bestpixel->b], bestpixel->next);
324 pixels[bestpixel->r][bestpixel->g][bestpixel->b] = bestpixel->next;
325 }*/
326 /*R bestpixel->next = NULL;*/
327 {
328 /* OK, we got a match, but it might be too close to another match (which was determined by
329 a human being. If so, we re-add the page to xf2 and process it afterwards
330 But we still eliminate the possibility. */
331 struct close_struct *c;
332 char try[200];
333 if (strncmp(bestpixel->fname,"./i/",4)==0) {
334 strcpy(try,bestpixel->fname+4);
335 }
336 else if (strncmp(bestpixel->fname,"./",2)==0) {
337 strcpy(try,bestpixel->fname+2);
338 }
339 else {
340 strcpy(try,bestpixel->fname);
341 }
342 try[6]='\0';
343 HASH_FIND_STR(too_close,try,c);
344 if (c) {
345 fprintf(stderr,"close %d,%d %s\n",x,y,bestpixel->fname);
346 fprintf(xf2,"%s\n",buf);
347 xf2flag = 1;
348 }
349 else {
350 printf("%03d|%03d|%s|%d|%d|%06x|%d|%d|%d|%lf|%lf|%06x|%d|%d|%d||%lf|%lf|%lf||%d|%d|%d||%d|\n",
351 x,y,bestpixel->fname,bestpixel->width,bestpixel->height,
352 bestpixel->rmark*65536+bestpixel->gmark*256+bestpixel->bmark,
353 bestpixel->rmark,bestpixel->gmark,bestpixel->bmark,
354 sqrt(bestpixel->strength),radius,
355 rtarget*65536+gtarget*256+btarget,
356 rtarget,gtarget,btarget,
357 bestpixel->rnet,bestpixel->gnet,bestpixel->bnet,
358 bestpixel->r,bestpixel->g,bestpixel->b,
359 range);
360 }
361 } /* block that checks if duplicate */
362 /*
363
364 1 x
365 2 y
366 3 filename
367 4 width
368 5 height
369 6 rmark,gmark,bmark - too big!
370 7 rmark
371 8 gmark negative? WTF?
372 9 bmark
373 10 sqrt(strength) - how close
374 11 radius - search radius
375 12 target RGB
376 13 target r
377 14 target g
378 15 target b
379 16 rnet
380 17 gnet
381 18 bnet
382 19 bestpixel r
383 20 bestpixel g
384 21 bestpixel b
385 22 range
386 */
387 break;
388 }
389 oldradius = radius;
390 radius = radius * 2.;
391 } /* for each incrementing radius */
392 } /* while getting the file */
393 fclose(xf);
394 if (xf2flag) {
395 fclose(xf2);
396 char bb[200];
397 sprintf(bb,"too_close%d.dat",seq);
398 xf=fopen(bb,"r");
399 if (!xf) {
400 fprintf(stderr,"cannopt open %s for reading\n",bb);
401 exit(-1);
402 }
403 seq = seq + 1;
404 goto morework;
405 }
406 }
407
408
409 int read_too_close(char *fname)
410 {
411 too_close = NULL;
412 FILE *xf;
413 xf=fopen(fname,"r");
414 if (xf) {
415 char buf[20000];
416 while (fgets(buf,20000-1,xf)) {
417 buf[6]='\0';
418 struct close_struct *c;
419 HASH_FIND_STR(too_close,buf,c);
420 if (!c) {
421 c = malloc(sizeof(struct close_struct));
422 if (!c) {
423 fprintf(stderr,"Out of memory! darn!\n");
424 exit(-1);
425 }
426 strcpy(c->value,buf);
427 HASH_ADD_KEYPTR(hh,too_close,c->value,6,c);
428 fprintf(stderr,"added %s\n",buf);
429 }
430 }
431 fclose(xf);
432 }
433 }
434
435
436 int main()
437 {
438 read_too_close("too_close.txt");
439 read_pixels("analysis.txt");
440 read_source("source.txt",144,48);
441 assign_pixels("points.txt");
442 }
443
444

  ViewVC Help
Powered by ViewVC 1.1.5