ROPO
Loading...
Searching...
No Matches
fmi_image_filter_speck.c
1
22#include <stdio.h>
23#include "fmi_util.h"
24#include "fmi_image.h"
25#include "fmi_image_filter.h"
26#include "fmi_image_histogram.h"
27#include "fmi_image_filter_speck.h"
28
29/* THIS IS THE GOOD OLD BINARY PROBE */
30
31#define UNVISITED 0
32#define DETECTED 128
33#define DONE 255
34
35/* shared with the new fmi_image_speck */
36FmiImage *PROBE_DOMAIN;
37FmiImage *PROBE_SOURCE;
38FmiImage *PROBE_TARGET;
39FmiImage PROBE_BOOK[1];
40
44static int probe_book_initialized = 0;
45
46Histogram PROBE_SPECK_HISTOGRAM;
47int (* PROBE_SPECK_HISTOGRAM_INFO)(Histogram);
48
49/*=========================================================================*/
50
51/* unit steps in four directions */
52int ROTX(int dir){
53 static int rotx[4]={ 1, 0, 0,-1};
54 return (rotx[dir&3]);
55}
56
57int ROTY(int dir){
58 static int roty[4]={ 0,-1, 1, 0};
59 return (roty[dir&3]);
60}
61
62/* stack-minimisation trick */
63int ROT_CODE(int i,int j){
64 return ( (((i+j)&64)+2*((i-j)&64))/64 );
65}
66
67
68/* trace = book keeping image */
69
70/* subroutine: process single speck */
71/*void probe_speck(FmiImage *target,FmiImage *trace,int i,int j,unsigned char min_value,Histogram PROBE_SPECK_HISTOGRAM){ */
72/*void probe_speck(FmiImage *domain,FmiImage *trace,int i,int j,unsigned char min_value){ */
73void probe_speck(int i,int j,unsigned char min_value){
74 /* ,int *area,int histogram[256],int *perimeter){ */
75 int dir;
76 static unsigned char g;
77
78 if (!legal_coords(PROBE_DOMAIN,i,j)){ /* OUTSIDE IMAGE */
79 PROBE_SPECK_HISTOGRAM[HIST_SIZE]++;
80 PROBE_SPECK_HISTOGRAM[HIST_PERIMx3]+=3;
81 PROBE_SPECK_HISTOGRAM[HIST_SUM_I]+=i;
82 PROBE_SPECK_HISTOGRAM[HIST_SUM_J]+=j;
83 PROBE_SPECK_HISTOGRAM[HIST_SUM_II]+=i*i;
84 PROBE_SPECK_HISTOGRAM[HIST_SUM_JJ]+=j*j;
85 PROBE_SPECK_HISTOGRAM[HIST_SUM_IJ]+=i*j;
86 return;}
87
88 if ((g=get_pixel(PROBE_DOMAIN,i,j,0))<min_value){ /* OUTSIDE SPECK */
89 PROBE_SPECK_HISTOGRAM[HIST_SIZE]++;
90 PROBE_SPECK_HISTOGRAM[HIST_PERIMx3]+=3;
91 PROBE_SPECK_HISTOGRAM[HIST_SUM_I]+=i;
92 PROBE_SPECK_HISTOGRAM[HIST_SUM_J]+=j;
93 PROBE_SPECK_HISTOGRAM[HIST_SUM_II]+=i*i;
94 PROBE_SPECK_HISTOGRAM[HIST_SUM_JJ]+=j*j;
95 PROBE_SPECK_HISTOGRAM[HIST_SUM_IJ]+=i*j;
96 return;}
97
98 if (get_pixel(PROBE_TARGET,i,j,0)!=UNVISITED) /* ALREADY MARKED */
99 return;
100
101 put_pixel(PROBE_TARGET,i,j,0,VISITED);
102 /* ++(*area); */
103 PROBE_SPECK_HISTOGRAM[HIST_AREA]++;
104 g=get_pixel(PROBE_SOURCE,i,j,0);
105 PROBE_SPECK_HISTOGRAM[g]++;
106 if (g<PROBE_SPECK_HISTOGRAM[HIST_MIN])
107 PROBE_SPECK_HISTOGRAM[HIST_MIN]=g;
108 if (g>PROBE_SPECK_HISTOGRAM[HIST_MAX])
109 PROBE_SPECK_HISTOGRAM[HIST_MAX]=g;
110
111 /*
112 histogram[HIST_SUM_I]+=i;
113 histogram[HIST_SUM_J]+=j;
114 histogram[HIST_SUM_II]+=i*i;
115 histogram[HIST_SUM_JJ]+=j*j;
116 histogram[HIST_SUM_IY]+=i*j;
117 */
118 /* if (histogram[HIST_SUM_II]>(INT_MAX/16)) */
119 /* printf("SUM_II=%d\n",histogram[HIST_SUM_II]); */
120
121 dir=ROT_CODE(i,j);
122 probe_speck(i+ROTX(dir ),j+ROTY(dir ),min_value);
123 probe_speck(i+ROTX(dir+1),j+ROTY(dir+1),min_value);
124 probe_speck(i+ROTX(dir+2),j+ROTY(dir+2),min_value);
125 probe_speck(i+ROTX(dir+3),j+ROTY(dir+3),min_value);
126 return;
127}
128
129/* subroutine: process single speck */
130/*void propagate_attribute(FmiImage *domain,FmiImage *trace,int i,int j,unsigned char min_value,unsigned char attribute){ */
131void propagate_attribute(int i,int j,unsigned char min_value,unsigned char attribute){
132 int dir;
133 if (!legal_coords(PROBE_DOMAIN,i,j)) return; /* OUTSIDE IMAGE */
134 if (get_pixel(PROBE_DOMAIN,i,j,0)<min_value) return; /* OUTSIDE SPECK */
135 if (get_pixel(PROBE_BOOK, i,j,0)==DONE) return;
136 put_pixel(PROBE_TARGET,i,j,0,attribute);
137 put_pixel(PROBE_BOOK,i,j,0,DONE);
138 if (FMI_DEBUG(1)){
139 /* fprintf(stderr," i=%d j=%d area=%d\n",i,j,area);fflush(stderr); */
140 };
141 dir=ROT_CODE(i,j);
142 propagate_attribute(i+ROTX(dir ),j+ROTY(dir ),min_value,attribute);
143 propagate_attribute(i+ROTX(dir+1),j+ROTY(dir+1),min_value,attribute);
144 propagate_attribute(i+ROTX(dir+2),j+ROTY(dir+2),min_value,attribute);
145 propagate_attribute(i+ROTX(dir+3),j+ROTY(dir+3),min_value,attribute);
146}
147
148/* MAIN PROCESS (recursive) */
149/*void traverse_image(FmiImage *target,FmiImage *trace,int i,int j,int min_value){ */
150void traverse_image(int i,int j,int min_value){
151 /* static int area,perimeter; */
152 /* static int histogram[256]; */
153 /* static Histogram histogram; */
154 /* Histogram histogram; */
155 int attribute;
156 int dir;
157 if (!legal_coords(PROBE_DOMAIN,i,j)) return;
158 /* if (get_pixel(trace,i,j,0)!=UNVISITED) return; */
159 if (get_pixel(PROBE_BOOK,i,j,0)!=UNVISITED) return;
160
161 /* fprintf(stderr,"traverse, i=%d, j=%d \n",i,j); */
162 if (get_pixel(PROBE_DOMAIN,i,j,0)<min_value){
163 /* put_pixel(trace,i,j,0,0); */
164 put_pixel(PROBE_BOOK,i,j,0,DETECTED);
165 /* SEARCH MODE (continue searching segments in image) */
166 dir=ROT_CODE(i,j);
167 /*dir=0; */
168 traverse_image(i+ROTX(dir ),j+ROTY(dir ),min_value);
169 traverse_image(i+ROTX(dir+1),j+ROTY(dir+1),min_value);
170 traverse_image(i+ROTX(dir+2),j+ROTY(dir+2),min_value);
171 traverse_image(i+ROTX(dir+3),j+ROTY(dir+3),min_value);}
172 else{
173 /* SPECK PROBE MODE */
174 /* DETECT SPECK, COMPUTE ITS AREA, HISTOGRAM, PERIMETER ON THE RUN */
175 /* histogram[HIST_AREA]=0; */
176 /* histogram[HIST_PERIMx3]=0; */
177 /* clear_histogram(histogram); */
178
179 clear_histogram_full(PROBE_SPECK_HISTOGRAM);
180 /* PROBE_SPECK_HISTOGRAM[HIST_MIN]=255; */
181 PROBE_SPECK_HISTOGRAM[HIST_MIN]=255;
182 PROBE_SPECK_HISTOGRAM[HIST_SUM_I]=0;
183 PROBE_SPECK_HISTOGRAM[HIST_SUM_J]=0;
184 PROBE_SPECK_HISTOGRAM[HIST_SUM_II]=0;
185 PROBE_SPECK_HISTOGRAM[HIST_SUM_JJ]=0;
186 PROBE_SPECK_HISTOGRAM[HIST_SUM_IJ]=0;
187
188
189 /* probe_speck(target,trace,i,j,min_value,PROBE_SPECK_HISTOGRAM); */
190 probe_speck(i,j,min_value);
191 put_pixel(PROBE_BOOK,i,j,0,DETECTED);
192
193 /* attribute=histogram_function(PROBE_SPECK_HISTOGRAM); */
194 attribute=PROBE_SPECK_HISTOGRAM_INFO(PROBE_SPECK_HISTOGRAM);
195 if (histogram_scaling_function!=NULL)
196 attribute=histogram_scaling_function(histogram_scaling_parameter,attribute);
197
198 if (FMI_DEBUG(5)){
199 fprintf(stderr," found speck, i=%d, j=%d \n",i,j);
200 fprintf(stderr," size: %d \n",(int)PROBE_SPECK_HISTOGRAM[HIST_AREA]);
201 fprintf(stderr," function value: %d \n",attribute);
202 fflush(stderr);}
203
204 if (attribute<1) attribute=1;
205 if (attribute>250) attribute=250;
206 propagate_attribute(i,j,min_value,attribute);
207 fmi_debug(5,"mark_speck_size finished");
208 }
209}
210
211/* CLIENT (STARTER) */
212void Binaryprobe(FmiImage *domain,FmiImage *source,FmiImage *trace,int (* histogram_function)(Histogram),unsigned char min_value){
213 register int i,j;
214 fmi_debug(3,"filter_specks");
215 if (source->channels!=1)
216 fmi_error("filter_specks: other than single-channel source");
217 PROBE_DOMAIN=domain;
218 PROBE_SOURCE=source;
219 PROBE_TARGET=trace;
220
221 if (probe_book_initialized == 0) {
222 init_new_image(PROBE_BOOK);
223 probe_book_initialized = 1;
224 }
225
226 canonize_image(source,PROBE_BOOK);
227 canonize_image(source,PROBE_TARGET);
228 fill_image(PROBE_BOOK,UNVISITED);
229 fill_image(trace,0);
230
231 PROBE_SPECK_HISTOGRAM_INFO=histogram_function;
232
233
234 fmi_debug(4,"filter_specks...");
235
236 for (i=0;i<source->width;i++)
237 for (j=0;j<source->height;j++)
238 /*traverse_image(source,trace,i,j,min_value); */
239 traverse_image(i,j,min_value);
240
241 fmi_debug(4,"filter_specks, DONE.");
242
243 if (FMI_DEBUG(5))
244 write_image("probe",PROBE_BOOK,PGM_RAW);
245
246 reset_image(PROBE_BOOK);
247}
248
249void detect_specks(FmiImage *source,FmiImage *trace,unsigned char min_value,int (* histogram_function)(Histogram)){
250 Binaryprobe(source,source,trace,histogram_function,min_value);
251}
252
253/* DEBUGGING... */
254void test_rotation(FmiImage *target,FmiImage *trace,int i,int j,int rec_depth){
255 int dir=1;
256 /*int k,l; */
257 if (!legal_coords(target,i,j)) return;
258 if (get_pixel(trace,i,j,0)!=UNVISITED) return;
259 /* fprintf(stderr,"\ti=%d \tj=%d \tdepth=%d\n",i,j,rec_depth); fflush(stderr); */
260 put_pixel(trace,i,j,0,10+dir);
261 /* fprintf(stderr,"ok\n"); fflush(stderr); */
262 /* for (i=0;i<target->width;i++) */
263 /* for (j=0;j<target->height;j++){ */
264
265 if ((rec_depth&255)==0) {
266 fprintf(stderr,"\ti=%d \tj=%d \tdepth=%d\n",i,j,rec_depth); fflush(stderr);
267 }
268 dir=ROT_CODE(i,j);
269 put_pixel(trace,i,j,0,10+dir);
270 put_pixel(target,i,j,0,(rec_depth>>8)&255);
271 test_rotation(target,trace,i+ROTX(dir ),j+ROTY(dir ),rec_depth+1);
272 test_rotation(target,trace,i+ROTX(dir+1),j+ROTY(dir+1),rec_depth+1);
273 test_rotation(target,trace,i+ROTX(dir+2),j+ROTY(dir+2),rec_depth+1);
274 test_rotation(target,trace,i+ROTX(dir+3),j+ROTY(dir+3),rec_depth+1);
275 /* fmi_debug(1,"finito"); */
276}
277
278