00001
00002 #ifndef vil_line_filter_txx_
00003 #define vil_line_filter_txx_
00004
00005
00006
00007
00008
00009 #include "vil_line_filter.h"
00010 #include <vil/vil_fill.h>
00011 #include <vcl_cassert.h>
00012
00013
00014
00015
00016
00017
00018 template <class Type>
00019 void vil_line_filter<Type>::light_lines_3x3(vil_image_view<vxl_byte>& line_dir,
00020 vil_image_view<float>& line_str,
00021 vil_image_view<Type>const& image,
00022 float edge_thresh)
00023 {
00024 assert(image.nplanes()==1);
00025 unsigned ni = image.ni();
00026 unsigned nj = image.nj();
00027 vcl_ptrdiff_t istep = image.istep();
00028 vcl_ptrdiff_t jstep = image.jstep();
00029
00030 line_dir.set_size(ni,nj,1);
00031 line_str.set_size(ni,nj,1);
00032
00033 vcl_ptrdiff_t d_istep = line_dir.istep();
00034 vcl_ptrdiff_t d_jstep = line_dir.jstep();
00035 vxl_byte* d_data = line_dir.top_left_ptr();
00036 vcl_ptrdiff_t s_istep = line_str.istep();
00037 vcl_ptrdiff_t s_jstep = line_str.jstep();
00038 float* s_data = line_str.top_left_ptr();
00039
00040
00041 vil_fill_line(d_data,ni,d_istep,vxl_byte(0));
00042 vil_fill_line(d_data+(nj-1)*d_jstep,ni,d_istep,vxl_byte(0));
00043 vil_fill_line(s_data,ni,s_istep,0.0f);
00044 vil_fill_line(s_data+(nj-1)*s_jstep,ni,s_istep,0.0f);
00045
00046 d_data += d_jstep;
00047 s_data += s_jstep;
00048 const Type* im_data = image.top_left_ptr()+jstep+istep;
00049
00050 int ni1 = ni-1;
00051 int nj1 = nj-1;
00052
00053
00054 vcl_ptrdiff_t nistep = -istep;
00055 vcl_ptrdiff_t njstep = -jstep;
00056 vcl_ptrdiff_t xjstep = istep+jstep;
00057 vcl_ptrdiff_t ynistep = jstep-istep;
00058 vcl_ptrdiff_t xnjstep = istep-jstep;
00059 vcl_ptrdiff_t ninjstep = -istep-jstep;
00060
00061 for (int y=1;y<nj1;++y)
00062 {
00063 vxl_byte* d_row = d_data; d_row[0]=0; d_row+=d_istep;
00064 float* s_row = s_data; s_row[0]=0; s_row+=s_istep;
00065 const Type* i_row = im_data;
00066 for (int x=1;x<ni1;++x)
00067 {
00068
00069
00070 float f1 = float(i_row[nistep]) +float(i_row[istep]);
00071 float f2 = float(i_row[ninjstep])+float(i_row[xjstep]);
00072 float f3 = float(i_row[njstep]) +float(i_row[jstep]);
00073 float f4 = float(i_row[ynistep]) +float(i_row[xnjstep]);
00074
00075
00076 vxl_byte best_d = 1;
00077 float max_f = f1;
00078 if (f2>max_f) { best_d=2; max_f=f2;}
00079 if (f3>max_f) { best_d=3; max_f=f3;}
00080 if (f4>max_f) { best_d=4; max_f=f4;}
00081
00082 float edge_s = 0.5f*max_f + (*i_row)/3.0f -(f1+f2+f3+f4)/6.0f;
00083 if (edge_s>edge_thresh)
00084 {
00085 *d_row = best_d;
00086 *s_row = edge_s;
00087 }
00088 else
00089 {
00090 *d_row=0; *s_row=0;
00091 }
00092
00093 d_row+=d_istep;
00094 s_row+=s_istep;
00095 i_row+=istep;
00096 }
00097
00098 d_row[0]=0;
00099 s_row[0]=0;
00100
00101 d_data += d_jstep;
00102 s_data += s_jstep;
00103 im_data += jstep;
00104 }
00105 }
00106
00107
00108
00109
00110
00111 template <class Type>
00112 void vil_line_filter<Type>::dark_lines_3x3(vil_image_view<vxl_byte>& line_dir,
00113 vil_image_view<float>& line_str,
00114 vil_image_view<Type>const& image,
00115 float edge_thresh)
00116 {
00117 assert(image.nplanes()==1);
00118 unsigned ni = image.ni();
00119 unsigned nj = image.nj();
00120 vcl_ptrdiff_t istep = image.istep();
00121 vcl_ptrdiff_t jstep = image.jstep();
00122
00123 line_dir.set_size(ni,nj,1);
00124 line_str.set_size(ni,nj,1);
00125
00126 vcl_ptrdiff_t d_istep = line_dir.istep();
00127 vcl_ptrdiff_t d_jstep = line_dir.jstep();
00128 vxl_byte* d_data = line_dir.top_left_ptr();
00129 vcl_ptrdiff_t s_istep = line_str.istep();
00130 vcl_ptrdiff_t s_jstep = line_str.jstep();
00131 float* s_data = line_str.top_left_ptr();
00132
00133
00134 vil_fill_line(d_data,ni,d_istep,vxl_byte(0));
00135 vil_fill_line(d_data+(nj-1)*d_jstep,ni,d_istep,vxl_byte(0));
00136 vil_fill_line(s_data,ni,s_istep,0.0f);
00137 vil_fill_line(s_data+(nj-1)*s_jstep,ni,s_istep,0.0f);
00138
00139 d_data += d_jstep;
00140 s_data += s_jstep;
00141 const Type* im_data = image.top_left_ptr()+jstep+istep;
00142
00143 int ni1 = ni-1;
00144 int nj1 = nj-1;
00145
00146
00147 vcl_ptrdiff_t nistep = -istep;
00148 vcl_ptrdiff_t njstep = -jstep;
00149 vcl_ptrdiff_t xjstep = istep+jstep;
00150 vcl_ptrdiff_t ynistep = jstep-istep;
00151 vcl_ptrdiff_t xnjstep = istep-jstep;
00152 vcl_ptrdiff_t ninjstep = -istep-jstep;
00153
00154 for (int y=1;y<nj1;++y)
00155 {
00156 vxl_byte* d_row = d_data; d_row[0]=0; d_row+=d_istep;
00157 float* s_row = s_data; s_row[0]=0; s_row+=s_istep;
00158 const Type* i_row = im_data;
00159 for (int x=1;x<ni1;++x)
00160 {
00161
00162
00163 float f1 = float(i_row[nistep]) +float(i_row[istep]);
00164 float f2 = float(i_row[ninjstep])+float(i_row[xjstep]);
00165 float f3 = float(i_row[njstep]) +float(i_row[jstep]);
00166 float f4 = float(i_row[xnjstep]) +float(i_row[ynistep]);
00167
00168
00169 vxl_byte best_d = 1;
00170 float min_f = f1;
00171 if (f2<min_f) { best_d=2; min_f=f2;}
00172 if (f3<min_f) { best_d=3; min_f=f3;}
00173 if (f4<min_f) { best_d=4; min_f=f4;}
00174
00175 float edge_s = (f1+f2+f3+f4)/6.0f - 0.5f*min_f - (*i_row)/3.0f;
00176 if (edge_s>edge_thresh)
00177 {
00178 *d_row = best_d;
00179 *s_row = edge_s;
00180 }
00181 else
00182 {
00183 *d_row=0; *s_row=0;
00184 }
00185
00186 d_row+=d_istep;
00187 s_row+=s_istep;
00188 i_row+=istep;
00189 }
00190
00191 d_row[0]=0;
00192 s_row[0]=0;
00193
00194 d_data += d_jstep;
00195 s_data += s_jstep;
00196 im_data += jstep;
00197 }
00198 }
00199
00200
00201
00202
00203
00204
00205 template <class Type>
00206 void vil_line_filter<Type>::light_lines_5x5(vil_image_view<vxl_byte>& line_dir,
00207 vil_image_view<float>& line_str,
00208 vil_image_view<Type>const& image,
00209 float edge_thresh)
00210 {
00211 assert(image.nplanes()==1);
00212 unsigned ni = image.ni();
00213 unsigned nj = image.nj();
00214 vcl_ptrdiff_t istep = image.istep();
00215 vcl_ptrdiff_t jstep = image.jstep();
00216
00217 line_dir.set_size(ni,nj,1);
00218 line_str.set_size(ni,nj,1);
00219
00220 vcl_ptrdiff_t d_istep = line_dir.istep();
00221 vcl_ptrdiff_t d_jstep = line_dir.jstep();
00222 vxl_byte* d_data = line_dir.top_left_ptr();
00223 vcl_ptrdiff_t s_istep = line_str.istep();
00224 vcl_ptrdiff_t s_jstep = line_str.jstep();
00225 float* s_data = line_str.top_left_ptr();
00226
00227
00228 vil_fill_line(d_data,ni,d_istep,vxl_byte(0));
00229 vil_fill_line(d_data+d_jstep,ni,d_istep,vxl_byte(0));
00230 vil_fill_line(d_data+(nj-1)*d_jstep,ni,d_istep,vxl_byte(0));
00231 vil_fill_line(d_data+(nj-2)*d_jstep,ni,d_istep,vxl_byte(0));
00232 vil_fill_line(s_data,ni,s_istep,0.0f);
00233 vil_fill_line(s_data+s_jstep,ni,s_istep,0.0f);
00234 vil_fill_line(s_data+(nj-1)*s_jstep,ni,s_istep,0.0f);
00235 vil_fill_line(s_data+(nj-2)*s_jstep,ni,s_istep,0.0f);
00236
00237 d_data += 2*d_jstep;
00238 s_data += 2*s_jstep;
00239 const Type* im_data = image.top_left_ptr()+2*(jstep+istep);
00240
00241 int ni2 = ni-2;
00242 int nj2 = nj-2;
00243
00244
00245 vcl_ptrdiff_t i1a = -2*istep;
00246 vcl_ptrdiff_t i1b = -istep;
00247 vcl_ptrdiff_t i1c = istep;
00248 vcl_ptrdiff_t i1d = 2*istep;
00249
00250 vcl_ptrdiff_t i2c = istep+jstep;
00251 vcl_ptrdiff_t i2a = -2*i2c;
00252 vcl_ptrdiff_t i2b = -1*i2c;
00253 vcl_ptrdiff_t i2d = 2*i2c;
00254
00255 vcl_ptrdiff_t i3a = -2*jstep;
00256 vcl_ptrdiff_t i3b = -1*jstep;
00257 vcl_ptrdiff_t i3c = jstep;
00258 vcl_ptrdiff_t i3d = 2*jstep;
00259
00260 vcl_ptrdiff_t i4c = istep-jstep;
00261 vcl_ptrdiff_t i4a = -2*i4c;
00262 vcl_ptrdiff_t i4b = -1*i4c;
00263 vcl_ptrdiff_t i4d = 2*i4c;
00264
00265 for (int y=2;y<nj2;++y)
00266 {
00267 vxl_byte* d_row = d_data; d_row[0]=0; d_row+=d_istep;d_row[0]=0; d_row+=d_istep;
00268 float* s_row = s_data; s_row[0]=0; s_row+=s_istep;s_row[0]=0; s_row+=s_istep;
00269 const Type* i_row = im_data;
00270 for (int x=2;x<ni2;++x)
00271 {
00272
00273
00274 float f1 = float(i_row[i1a])+float(i_row[i1b])+float(i_row[i1c])+float(i_row[i1d]);
00275 float f2 = float(i_row[i2a])+float(i_row[i2b])+float(i_row[i2c])+float(i_row[i2d]);
00276 float f3 = float(i_row[i3a])+float(i_row[i3b])+float(i_row[i3c])+float(i_row[i3d]);
00277 float f4 = float(i_row[i4a])+float(i_row[i4b])+float(i_row[i4c])+float(i_row[i4d]);
00278
00279
00280 vxl_byte best_d = 1;
00281 float max_f = f1;
00282 if (f2>max_f) { best_d=2; max_f=f2;}
00283 if (f3>max_f) { best_d=3; max_f=f3;}
00284 if (f4>max_f) { best_d=4; max_f=f4;}
00285
00286
00287 float edge_s = (17.0f/60) * max_f + 0.2f*(*i_row) -(f1+f2+f3+f4)/12;
00288 if (edge_s>edge_thresh)
00289 {
00290 *d_row = best_d;
00291 *s_row = edge_s;
00292 }
00293 else
00294 {
00295 *d_row=0; *s_row=0;
00296 }
00297
00298 d_row+=d_istep;
00299 s_row+=s_istep;
00300 i_row+=istep;
00301 }
00302
00303 d_row[0]=0; d_row[d_istep]=0;
00304 s_row[0]=0; s_row[s_istep]=0;
00305
00306 d_data += d_jstep;
00307 s_data += s_jstep;
00308 im_data += jstep;
00309 }
00310 }
00311
00312
00313 template <class Type>
00314 void vil_line_filter<Type>::dark_lines_5x5(vil_image_view<vxl_byte>& line_dir,
00315 vil_image_view<float>& line_str,
00316 vil_image_view<Type>const& image,
00317 float edge_thresh)
00318 {
00319 assert(image.nplanes()==1);
00320 unsigned ni = image.ni();
00321 unsigned nj = image.nj();
00322 vcl_ptrdiff_t istep = image.istep();
00323 vcl_ptrdiff_t jstep = image.jstep();
00324
00325 line_dir.set_size(ni,nj,1);
00326 line_str.set_size(ni,nj,1);
00327
00328 vcl_ptrdiff_t d_istep = line_dir.istep();
00329 vcl_ptrdiff_t d_jstep = line_dir.jstep();
00330 vxl_byte* d_data = line_dir.top_left_ptr();
00331 vcl_ptrdiff_t s_istep = line_str.istep();
00332 vcl_ptrdiff_t s_jstep = line_str.jstep();
00333 float* s_data = line_str.top_left_ptr();
00334
00335
00336 vil_fill_line(d_data,ni,d_istep,vxl_byte(0));
00337 vil_fill_line(d_data+d_jstep,ni,d_istep,vxl_byte(0));
00338 vil_fill_line(d_data+(nj-1)*d_jstep,ni,d_istep,vxl_byte(0));
00339 vil_fill_line(d_data+(nj-2)*d_jstep,ni,d_istep,vxl_byte(0));
00340 vil_fill_line(s_data,ni,s_istep,0.0f);
00341 vil_fill_line(s_data+s_jstep,ni,s_istep,0.0f);
00342 vil_fill_line(s_data+(nj-1)*s_jstep,ni,s_istep,0.0f);
00343 vil_fill_line(s_data+(nj-2)*s_jstep,ni,s_istep,0.0f);
00344
00345 d_data += 2*d_jstep;
00346 s_data += 2*s_jstep;
00347 const Type* im_data = image.top_left_ptr()+2*(jstep+istep);
00348
00349 int ni2 = ni-2;
00350 int nj2 = nj-2;
00351
00352
00353 vcl_ptrdiff_t i1a = -2*istep;
00354 vcl_ptrdiff_t i1b = -istep;
00355 vcl_ptrdiff_t i1c = istep;
00356 vcl_ptrdiff_t i1d = 2*istep;
00357
00358 vcl_ptrdiff_t i2c = istep+jstep;
00359 vcl_ptrdiff_t i2a = -2*i2c;
00360 vcl_ptrdiff_t i2b = -1*i2c;
00361 vcl_ptrdiff_t i2d = 2*i2c;
00362
00363 vcl_ptrdiff_t i3a = -2*jstep;
00364 vcl_ptrdiff_t i3b = -1*jstep;
00365 vcl_ptrdiff_t i3c = jstep;
00366 vcl_ptrdiff_t i3d = 2*jstep;
00367
00368 vcl_ptrdiff_t i4c = istep-jstep;
00369 vcl_ptrdiff_t i4a = -2*i4c;
00370 vcl_ptrdiff_t i4b = -1*i4c;
00371 vcl_ptrdiff_t i4d = 2*i4c;
00372
00373 for (int y=2;y<nj2;++y)
00374 {
00375 vxl_byte* d_row = d_data; d_row[0]=0; d_row+=d_istep;d_row[0]=0; d_row+=d_istep;
00376 float* s_row = s_data; s_row[0]=0; s_row+=s_istep;s_row[0]=0; s_row+=s_istep;
00377 const Type* i_row = im_data;
00378 for (int x=2;x<ni2;++x)
00379 {
00380
00381
00382 float f1 = float(i_row[i1a])+float(i_row[i1b])+float(i_row[i1c])+float(i_row[i1d]);
00383 float f2 = float(i_row[i2a])+float(i_row[i2b])+float(i_row[i2c])+float(i_row[i2d]);
00384 float f3 = float(i_row[i3a])+float(i_row[i3b])+float(i_row[i3c])+float(i_row[i3d]);
00385 float f4 = float(i_row[i4a])+float(i_row[i4b])+float(i_row[i4c])+float(i_row[i4d]);
00386
00387
00388 vxl_byte best_d = 1;
00389 float min_f = f1;
00390 if (f2<min_f) { best_d=2; min_f=f2;}
00391 if (f3<min_f) { best_d=3; min_f=f3;}
00392 if (f4<min_f) { best_d=4; min_f=f4;}
00393
00394
00395 float edge_s = (f1+f2+f3+f4)/12 - (17.0f/60) * min_f - 0.2f*(*i_row);
00396 if (edge_s>edge_thresh)
00397 {
00398 *d_row = best_d;
00399 *s_row = edge_s;
00400 }
00401 else
00402 {
00403 *d_row=0; *s_row=0;
00404 }
00405
00406 d_row+=d_istep;
00407 s_row+=s_istep;
00408 i_row+=istep;
00409 }
00410
00411 d_row[0]=0; d_row[d_istep]=0;
00412 s_row[0]=0; s_row[s_istep]=0;
00413
00414 d_data += d_jstep;
00415 s_data += s_jstep;
00416 im_data += jstep;
00417 }
00418 }
00419
00420
00421 #undef VIL_LINE_FILTER_INSTANTIATE
00422 #define VIL_LINE_FILTER_INSTANTIATE(T) \
00423 template class vil_line_filter<T >
00424
00425 #endif