ROPO
Loading...
Searching...
No Matches
fmi_image_filter.c
1
22#include <math.h>
23#include "fmi_util.h"
24#include "fmi_image.h"
25#include "fmi_image_filter.h"
26
27void detect_vert_gradient(FmiImage *source, FmiImage *trace)
28{
29 int i, j, k;
30 int j_upper, j_lower;
31 int g;
32 canonize_image(source, trace);
33
34 for (k = 0; k < source->channels; k++) {
35 for (j = 0; j < source->height; j++) {
36 j_upper = j - 1;
37 j_lower = j + 1;
38 for (i = 0; i < source->width; i++) {
39 g = (get_pixel(source, i, j_upper, k)
40 - get_pixel(source, i, j_lower, k)) / 2 + 128;
41 if (g > 254)
42 g = 254;
43 if (g < 2)
44 g = 2;
45 put_pixel(trace, i, j, k, g);
46 }
47 }
48 }
49}
50
51void detect_horz_gradient(FmiImage *source, FmiImage *trace)
52{
53 int i, j, k;
54 int i_left, i_right;
55 int g;
56 canonize_image(source, trace);
57
58 for (k = 0; k < source->channels; k++) {
59 for (i = 0; i < source->width; i++) {
60 i_left = i - 1;
61 i_right = i + 1;
62 for (j = 0; j < source->height; j++) {
63 g = (get_pixel(source, i_right, j, k) - get_pixel(source, i_left, j, k)) / 2 + 128;
64 if (g > 254)
65 g = 254;
66 if (g < 2)
67 g = 2;
68 put_pixel(trace, i, j, k, g);
69 }
70 }
71 }
72}
73
74
75void detect_vert_maxima(FmiImage *source,FmiImage *trace){
76 int i,j,k;
77 Byte g,g_upper,g_lower,gmax;
78 canonize_image(source,trace);
79 /*check_image_properties(source,trace); */
80
81 for (k=0;k<source->channels;k++){
82 for (j=1;j<source->height-1;j++){
83 for (i=0;i<source->width;i++){
84 g = get_pixel(source,i,j,k);
85 g_upper = get_pixel(source,i,j-1,k);
86 g_lower = get_pixel(source,i,j+1,k);
87 gmax = MAX(g_upper,g_lower);
88 /*put_pixel(trace,i,j,k,gmax); */
89 if (g>gmax)
90 put_pixel(trace,i,j,k,(Byte)(g-gmax));
91 else
92 put_pixel(trace,i,j,k,0);
93 }
94 }
95 }
96}
97
98/* calculate RELATIVE "shoulder", 242 => 2 393 => 3 , divide by should avg */
99void detect_vert_maxima2(FmiImage *source, FmiImage *trace)
100{
101 int i, j, k;
102 Byte g, g_sum; /*g_upper,g_lower; */
103 int gt;
104 canonize_image(source, trace);
105 /*check_image_properties(source,trace); */
106
107 for (k = 0; k < source->channels; k++) {
108 for (j = 1; j < source->height - 1; j++) {
109 for (i = 0; i < source->width; i++) {
110 g = get_pixel(source, i, j, k);
111 /* g_upper=get_pixel(source,i,j-1,k);
112 g_lower=get_pixel(source,i,j+1,k);
113 gt=(2*g-g_upper-g_lower)/(1+g_upper+g_lower);
114 */
115 g_sum = (get_pixel(source, i, j - 1, k)
116 + get_pixel(source, i, j + 1, k));
117 gt = (2 * g - g_sum) / (1 + g_sum);
118 gt = MAX(0,gt);
119 /* gt=pseudo_sigmoid(128,gt); */
120 put_pixel(trace, i, j, k, gt);
121 }
122 }
123 }
124}
125
126void detect_horz_edges(FmiImage *source, FmiImage *trace)
127{
128 int i, j, k;
129 int g, g2;
130 canonize_image(source, trace);
131 /*check_image_properties(source,trace); */
132
133 for (k = 0; k < source->channels; k++) {
134 for (j = 1; j < source->height - 1; j++) {
135 for (i = 0; i < source->width; i++) {
136 g = get_pixel(source, i, j, k) - get_pixel(source, i, j - 1, k);
137 g2 = get_pixel(source, i, j, k) - get_pixel(source, i, j + 1, k);
138 g = MAX(g,g2);
139 g = MAX(0,g);
140 put_pixel(trace, i, j, k, g);
141 }
142 }
143 }
144 if (FMI_DEBUG(3))
145 write_image("edges", trace, PGM_RAW);
146}
147
148void detect_horz_maxima(FmiImage *source, FmiImage *trace)
149{
150 int i, j, k;
151 unsigned char g, g_left, g_right, gmax, gt;
152 canonize_image(source, trace);
153
154 for (k = 0; k < source->channels; k++) {
155 for (i = 1; i < source->width - 1; i++) {
156 for (j = 0; j < source->height; j++) {
157 g = get_pixel(source, i, j, k);
158 g_left = get_pixel(source, i - 1, j, k);
159 g_right = get_pixel(source, i + 1, j, k);
160 gmax = MAX(g_left,g_right);
161 if (g > gmax) {
162 gt = get_pixel(trace, i, j, k);
163 put_pixel(trace, i, j, k, MAX(gt,g-gmax));
164 }
165 /* else */
166 /* put_pixel(trace,i,j,k,0); */
167 }
168 }
169 }
170}
171
172void detect_vert_edges(FmiImage *source,FmiImage *trace){
173 int i,j,k;
174 int g,g2;
175 canonize_image(source,trace);
176 /*check_image_properties(source,trace); */
177
178 for (k=0;k<source->channels;k++){
179 for (i=1;i<source->width-1;i++){
180 for (j=0;j<source->height;j++){
181 g =get_pixel(source,i,j,k)-get_pixel(source,i-1,j,k);
182 g2=get_pixel(source,i,j,k)-get_pixel(source,i+1,j,k);
183 g=MAX(g,g2);
184 g=MAX(0,g);
185 put_pixel(trace,i,j,k,g);}
186 }
187 }
188 if (FMI_DEBUG(5)) write_image("debug_edges",trace,PGM_RAW);
189}
190
191void iir_right(FmiImage *source, FmiImage *trace, int promille)
192{
193 int i, j, k;
194 int g, g_old;
195 canonize_image(source, trace);
196 for (k = 0; k < source->channels; k++)
197 for (j = 0; j < source->height; j++) {
198 g_old = 0;
199 for (i = 0; i < source->width; i++) {
200 g = get_pixel(source, i, j, k);
201 g = MAX(g,g_old);
202 put_pixel(trace, i, j, k, g);
203 g_old = g * promille / 1000;
204 }
205 }
206 if (FMI_DEBUG(5))
207 write_image("debug_iir_right", trace, PGM_RAW);
208}
209
210void iir_left(FmiImage *source, FmiImage *trace, int promille)
211{
212 int i, j, k;
213 int g, g_old;
214 canonize_image(source, trace);
215 for (k = 0; k < source->channels; k++)
216 for (j = 0; j < source->height; j++) {
217 g_old = 0;
218 for (i = source->width - 1; i >= 0; i--) {
219 g = get_pixel(source, i, j, k);
220 g = MAX(g,g_old);
221 put_pixel(trace, i, j, k, g);
222 g_old = g * promille / 1000;
223 }
224 }
225 if (FMI_DEBUG(5))
226 write_image("debug_iir_left", trace, PGM_RAW);
227}
228
229void iir_up(FmiImage *source, FmiImage *trace, int promille)
230{
231 int i, j, k;
232 int g, g_old;
233 canonize_image(source, trace);
234 for (k = 0; k < source->channels; k++)
235 for (i = 0; i < source->width; i++) {
236 g_old = 0;
237 for (j = 0; j < source->height; j++) {
238 g = get_pixel(source, i, j, k);
239 g = MAX(g,g_old);
240 put_pixel(trace, i, j, k, g);
241 g_old = g * promille / 1000;
242 }
243 }
244 if (FMI_DEBUG(5))
245 write_image("debug_iir_up", trace, PGM_RAW);
246}
247
248void iir_down(FmiImage *source, FmiImage *trace, int promille)
249{
250 int i, j, k;
251 int g, g_old;
252 canonize_image(source, trace);
253 for (k = 0; k < source->channels; k++)
254 for (i = 0; i < source->width; i++) {
255 g_old = 0;
256 for (j = source->height - 1; j >= 0; j--) {
257 g = get_pixel(source, i, j, k);
258 g = MAX(g,g_old);
259 put_pixel(trace, i, j, k, g);
260 g_old = g * promille / 1000;
261 }
262 }
263 if (FMI_DEBUG(5))
264 write_image("debug_iir_down", trace, PGM_RAW);
265}
266
267void mask_image(FmiImage *source, FmiImage *mask, Byte threshold, Byte c)
268{
269 register int i;
270 check_image_properties(source, mask);
271 if (FMI_DEBUG(3))
272 image_info(source);
273
274 for (i = 0; i < source->volume; i++)
275 if (mask->array[i] < threshold)
276 source->array[i] = c;
277
278}
279
280void threshold_image(FmiImage *source,FmiImage *target,Byte threshold){
281 register int i;
282 Byte c;
283 for (i=0;i<source->volume;i++){
284 c=source->array[i];
285 target->array[i]=(c>threshold)?c:0;
286 }
287}
288
289void binarize_image(FmiImage *source,FmiImage *target,Byte c){
290 register int i;
291 for (i=0;i<source->volume;i++)
292 target->array[i]=(source->array[i]>c)?255:0;
293}
294
295#define MAXVAL 250
296void propagate_right(FmiImage *source, FmiImage *domain, FmiImage *target,
297 signed char slope, void(* put_func)(FmiImage *, int, int, int, Byte))
298{
299 register int i, j, k;
300 int c;
301
302 check_image_properties(domain, target);
303 if (source != NULL)
304 check_image_properties(domain, source);
305 for (k = 0; k < domain->channels; k++) {
306 for (j = 0; j < domain->height; j++) {
307 c = 0;
308 for (i = 0; i < domain->width; i++) {
309 /*for (i=1;i<domain->width-1;i++){ */
310 /* printf("\nDomain (%d,%d)=%d ",i,j,get_pixel(domain,i,j,k)) ; */
311 if (((int) get_pixel(domain, i, j, k)) > 0) {
312 if (c == 0) {
313 /* printf("N "); */
314 if (source != NULL) {
315 c = (int) get_pixel(source, i, j, k);
316 if (c == 0)
317 c = 1;
318 } else
319 c = 1;
320 } else {
321 c = c + slope;
322 if (c > MAXVAL)
323 c = MAXVAL - 1;
324 if (c < 1)
325 c = 1;
326 }
327 } else
328 c = 0;
329 /* c2=get_pixel(target,i,j,k); c=MAX(c,c2); */
330 put_func(target, i, j, k, (Byte) c);
331 }
332 }
333 }
334}
335
336void propagate_left(FmiImage *source, FmiImage *domain, FmiImage *target,
337 signed char slope, void(* put_func)(FmiImage *, int, int, int, Byte))
338{
339 register int i, j, k;
340 int c;
341
342 for (k = 0; k < domain->channels; k++) {
343 for (j = 0; j < domain->height; j++) {
344 c = 0;
345 for (i = domain->width - 1; i >= 0; i--) {
346 /*for (i=domain->width-2;i>0;i--){ */
347 if (((int) get_pixel(domain, i, j, k)) > 0) {
348 if (c == 0) {
349 /* START MARKER MODE ... */
350 if (source != NULL) {
351 c = (int) get_pixel(source, i, j, k); /* ... with local start value */
352 if (c == 0)
353 c = 1;
354 } else
355 c = 1;
356 } /* ... with value 1 */
357 else {
358 /* CONTINUE MARKER MODE */
359 c = c + slope;
360 if (c > MAXVAL)
361 c = MAXVAL - 2;
362 if (c < 1)
363 c = 1;
364 }
365 } else
366 /* domain==0 */
367 c = 0; /* RETURN TO SEARCH MODE */
368 /*c2=get_pixel(target,i,j,k); c=MAX(c,c2); */
369 put_func(target, i, j, k, (Byte) c);
370 }
371 }
372 }
373}
374
375void propagate_up(FmiImage *source, FmiImage *domain, FmiImage *target,
376 signed char slope, void(* put_func)(FmiImage *, int, int, int, Byte))
377{
378 register int i, j, k;
379 int c;
380
381 for (k = 0; k < domain->channels; k++) {
382 for (i = 0; i < domain->width; i++) {
383 c = 0;
384 for (j = 0; j < domain->height; j++) {
385 if (get_pixel(domain, i, j, k) > 0) {
386 if (c == 0) {
387 if (source != NULL) {
388 c = get_pixel(source, i, j, k);
389 if (c == 0)
390 c = 1;
391 } else
392 c = 1;
393 } else {
394 c = c + slope;
395 if (c > MAXVAL)
396 c = MAXVAL - 3;
397 if (c < 1)
398 c = 1;
399 }
400 } else
401 c = 0;
402 /* c2=get_pixel(target,i,j,k); c=MAX(c,c2); */
403 put_func(target, i, j, k, (unsigned char) c);
404 }
405 }
406 }
407}
408
409void propagate_down(FmiImage *source, FmiImage *domain, FmiImage *target,
410 signed char slope, void(* put_func)(FmiImage *, int, int, int, Byte))
411{
412 register int i, j, k;
413 int c;
414
415 for (k = 0; k < domain->channels; k++) {
416 for (i = 0; i < domain->width; i++) {
417 c = 0;
418 for (j = domain->height - 1; j >= 0; j--) {
419 if (get_pixel(domain, i, j, k) > 0) {
420 if (c == 0) {
421 if (source != NULL) {
422 c = get_pixel(source, i, j, k);
423 if (c == 0)
424 c = 1;
425 } else
426 c = 1;
427 } else {
428 c = c + slope;
429 if (c > MAXVAL)
430 c = MAXVAL - 4;
431 if (c < 1)
432 c = 1;
433 }
434 } else
435 c = 0;
436 /*c2=get_pixel(target,i,j,k); c=MAX(c,c2); */
437 put_func(target, i, j, k, (unsigned char) c);
438 }
439 }
440 }
441}
442
443
444
445void horz_seg_lengths(FmiImage *source, FmiImage *target)
446{
447 propagate_right(NULL, source, target, 1, put_pixel);
448 if (FMI_DEBUG(5))
449 write_image("debug_horz_seg_lengths_1", target, PGM_RAW);
450 propagate_left(target, source, target, 0, put_pixel);
451 if (FMI_DEBUG(4))
452 write_image("debug_horz_seg_lengths", target, PGM_RAW);
453}
454
455void vert_seg_lengths(FmiImage *source, FmiImage *target)
456{
457 propagate_up(NULL, source, target, 1, put_pixel);
458 if (FMI_DEBUG(5))
459 write_image("debug_vert_seg_lengths_1", target, PGM_RAW);
460 propagate_down(target, source, target, 0, put_pixel);
461 if (FMI_DEBUG(4))
462 write_image("debug_vert_seg_lengths", target, PGM_RAW);
463}
464
465void row_statistics(FmiImage *source, Byte *nonzero, Byte *avg, Byte *pow)
466{
467 register int i, j;
468 int nz, s;
469 long int s2;
470 Byte c;
471 for (j = 0; j < source->height; j++) {
472 nz = 0;
473 s = 0;
474 s2 = 0;
475 for (i = 0; i < source->width; i++) {
476 c = get_pixel(source, i, j, 0);
477 /*nz+=(c>0); */
478 if (c > 0)
479 ++nz;
480 s += c;
481 s2 += c * c;
482 }
483 /* printf("%d nz=%d s=%d s2=%d (w=%d)\n",j,nz,s,s2,source->width); */
484 if (nonzero != NULL)
485 nonzero[j] = (255 * nz) / source->width;
486 if (avg != NULL)
487 avg[j] = s / source->width;
488 if (pow != NULL)
489 pow[j] = sqrt(s2 / source->width);
490 }
491}
492
493void col_statistics(FmiImage *source, Byte *nonzero, Byte *avg, Byte *pow)
494{
495 register int i, j;
496 int nz, s;
497 long int s2;
498 Byte c;
499 for (i = 0; i < source->width; i++) {
500 nz = 0;
501 s = 0;
502 s2 = 0;
503 for (j = 0; j < source->height; j++) {
504 c = get_pixel(source, i, j, 0);
505 nz += (c > 0);
506 s += c;
507 s2 += c * c;
508 }
509 if (nonzero != NULL)
510 nonzero[j] = 255 * nz / source->width;
511 if (avg != NULL)
512 avg[j] = s / source->width;
513 if (pow != NULL)
514 pow[j] = sqrt(s2 / source->width);
515 }
516}
517