25#include "fmi_image_filter.h"
26#include "fmi_image_histogram.h"
27#include "fmi_image_filter_speck.h"
44static int probe_book_initialized = 0;
46Histogram PROBE_SPECK_HISTOGRAM;
47int (* PROBE_SPECK_HISTOGRAM_INFO)(Histogram);
53 static int rotx[4]={ 1, 0, 0,-1};
58 static int roty[4]={ 0,-1, 1, 0};
63int ROT_CODE(
int i,
int j){
64 return ( (((i+j)&64)+2*((i-j)&64))/64 );
73void probe_speck(
int i,
int j,
unsigned char min_value){
76 static unsigned char g;
78 if (!legal_coords(PROBE_DOMAIN,i,j)){
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;
88 if ((g=get_pixel(PROBE_DOMAIN,i,j,0))<min_value){
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;
98 if (get_pixel(PROBE_TARGET,i,j,0)!=UNVISITED)
101 put_pixel(PROBE_TARGET,i,j,0,VISITED);
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;
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);
131void propagate_attribute(
int i,
int j,
unsigned char min_value,
unsigned char attribute){
133 if (!legal_coords(PROBE_DOMAIN,i,j))
return;
134 if (get_pixel(PROBE_DOMAIN,i,j,0)<min_value)
return;
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);
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);
150void traverse_image(
int i,
int j,
int min_value){
157 if (!legal_coords(PROBE_DOMAIN,i,j))
return;
159 if (get_pixel(PROBE_BOOK,i,j,0)!=UNVISITED)
return;
162 if (get_pixel(PROBE_DOMAIN,i,j,0)<min_value){
164 put_pixel(PROBE_BOOK,i,j,0,DETECTED);
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);}
179 clear_histogram_full(PROBE_SPECK_HISTOGRAM);
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;
190 probe_speck(i,j,min_value);
191 put_pixel(PROBE_BOOK,i,j,0,DETECTED);
194 attribute=PROBE_SPECK_HISTOGRAM_INFO(PROBE_SPECK_HISTOGRAM);
195 if (histogram_scaling_function!=NULL)
196 attribute=histogram_scaling_function(histogram_scaling_parameter,attribute);
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);
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");
212void Binaryprobe(
FmiImage *domain,
FmiImage *source,
FmiImage *trace,
int (* histogram_function)(Histogram),
unsigned char min_value){
214 fmi_debug(3,
"filter_specks");
215 if (source->channels!=1)
216 fmi_error(
"filter_specks: other than single-channel source");
221 if (probe_book_initialized == 0) {
222 init_new_image(PROBE_BOOK);
223 probe_book_initialized = 1;
226 canonize_image(source,PROBE_BOOK);
227 canonize_image(source,PROBE_TARGET);
228 fill_image(PROBE_BOOK,UNVISITED);
231 PROBE_SPECK_HISTOGRAM_INFO=histogram_function;
234 fmi_debug(4,
"filter_specks...");
236 for (i=0;i<source->width;i++)
237 for (j=0;j<source->height;j++)
239 traverse_image(i,j,min_value);
241 fmi_debug(4,
"filter_specks, DONE.");
244 write_image(
"probe",PROBE_BOOK,PGM_RAW);
246 reset_image(PROBE_BOOK);
249void detect_specks(
FmiImage *source,
FmiImage *trace,
unsigned char min_value,
int (* histogram_function)(Histogram)){
250 Binaryprobe(source,source,trace,histogram_function,min_value);
254void test_rotation(
FmiImage *target,
FmiImage *trace,
int i,
int j,
int rec_depth){
257 if (!legal_coords(target,i,j))
return;
258 if (get_pixel(trace,i,j,0)!=UNVISITED)
return;
260 put_pixel(trace,i,j,0,10+dir);
265 if ((rec_depth&255)==0) {
266 fprintf(stderr,
"\ti=%d \tj=%d \tdepth=%d\n",i,j,rec_depth); fflush(stderr);
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);