00001 #include "vil3d_distance_transform.h"
00002
00003
00004
00005
00006
00007 #include <vil3d/vil3d_image_view.h>
00008 #include <vil3d/algo/vil3d_fill_boundary.h>
00009 #include <vil3d/algo/vil3d_threshold.h>
00010 #include <vil3d/vil3d_slice.h>
00011 #include <vil/vil_fill.h>
00012 #include <vcl_cassert.h>
00013 #include <vcl_algorithm.h>
00014
00015
00016
00017
00018
00019
00020
00021
00022 void vil3d_signed_distance_transform(vil3d_image_view<float>& image, const float distance_link_i, const float distance_link_j, const float distance_link_k)
00023 {
00024 unsigned ni = image.ni(),nj = image.nj(), nk = image.nk();
00025 unsigned nplanes = image.nplanes();
00026
00027
00028 vil3d_image_view<bool> image2(ni,nj,nk,nplanes);
00029 vil3d_threshold_below(image,image2,0.1f);
00030 vil3d_fill_boundary(image2);
00031
00032
00033 vil3d_distance_transform(image,distance_link_i,distance_link_j,distance_link_k);
00034
00035
00036 vcl_ptrdiff_t istep0 = image.istep();
00037 vcl_ptrdiff_t istep2 = image2.istep();
00038 float *p0 = image.origin_ptr();
00039 bool *p1 = image2.origin_ptr();
00040
00041 for (unsigned int k=0; k<nk; ++k)
00042 for (unsigned int j=0; j<nj; ++j)
00043 for (unsigned int i=0; i<ni; ++i,p0+=istep0,p1+=istep2)
00044 {
00045 if (*p1)
00046 *p0 *= -1.0f;
00047 }
00048 }
00049
00050
00051 template<class T> void print_values(const vil_image_view<T> &img)
00052 {
00053 for (int j = 0; j < img.nj(); j++)
00054 {
00055 for (int i = 0; i < img.ni(); i++)
00056 vcl_cout << img(i,j) << ' ';
00057 vcl_cout << vcl_endl;
00058 }
00059 }
00060
00061 template<class T> void print_values(const vil3d_image_view<T> &img)
00062 {
00063 for (int k = 0; k < img.nk(); k++)
00064 for (int j = 0; j < img.nj(); j++)
00065 {
00066 for (int i = 0; i < img.ni(); i++)
00067 vcl_cout << img(i,j,k) << ' ';
00068 vcl_cout << vcl_endl;
00069 }
00070 }
00071
00072
00073
00074
00075
00076
00077
00078 void vil3d_signed_distance_transform(const vil3d_image_view<bool>& mask,
00079 vil3d_image_view<float>& image,
00080 float max_dist,
00081 const float distance_link_i,
00082 const float distance_link_j,
00083 const float distance_link_k)
00084 {
00085 image.set_size(mask.ni(),mask.nj(),mask.nk(),mask.nplanes());
00086 image.fill(max_dist);
00087
00088 unsigned ni = image.ni();
00089 unsigned nj = image.nj();
00090 unsigned nk = image.nk(), k;
00091 unsigned nplanes = image.nplanes();
00092
00093 vil_image_view<bool> mask_slice(mask.ni(),mask.nk(),mask.nplanes());
00094 vil_image_view<float> image_slice(ni,nj,nplanes);
00095
00096 image.fill(max_dist);
00097
00098 vil3d_image_view<float> image_inverse(ni,nj,nk,nplanes);
00099 image_inverse.fill(0.0f);
00100
00101 for (k=0;k<nk;k++)
00102 {
00103 mask_slice = vil3d_slice_ij(mask,k);
00104 image_slice = vil3d_slice_ij(image,k);
00105 vil_fill_mask(image_slice,mask_slice,0.0f);
00106 image_slice = vil3d_slice_ij(image_inverse,k);
00107 vil_fill_mask(image_slice,mask_slice,max_dist);
00108 }
00109
00110
00111 vil3d_distance_transform(image,distance_link_i,distance_link_j,distance_link_k);
00112 vil3d_distance_transform(image_inverse,distance_link_i,distance_link_j,distance_link_k);
00113
00114 float *p0 = image.origin_ptr();
00115 float *p1 = image_inverse.origin_ptr();
00116
00117 for (unsigned int k=0; k<nk; ++k)
00118 for (unsigned int j=0; j<nj; ++j)
00119 for (unsigned int i=0; i<ni; ++i,p0+=image.istep(),p1+=image_inverse.istep())
00120 *p0 -= *p1;
00121 }
00122
00123
00124
00125
00126
00127
00128 void vil3d_distance_transform(vil3d_image_view<float>& image, const float distance_link_i, const float distance_link_j, const float distance_link_k)
00129 {
00130
00131 vil3d_distance_transform_one_way(image,distance_link_i,distance_link_j,distance_link_k);
00132
00133
00134 unsigned ni = image.ni(), nj = image.nj(), nk = image.nk();
00135 vil3d_image_view<float> flip_image(image.memory_chunk(),
00136 &image(ni-1,nj-1,nk-1), ni,nj,nk,1,
00137 -image.istep(), -image.jstep(), -image.kstep(),
00138 image.nplanes());
00139 vil3d_distance_transform_one_way(flip_image,distance_link_i,distance_link_j,distance_link_k);
00140 }
00141
00142
00143
00144
00145
00146
00147 void vil3d_distance_transform_with_dir(vil3d_image_view<float>& image,
00148 vil3d_image_view<vil_rgb<float> >& orient,
00149 const float distance_link_i,
00150 const float distance_link_j,
00151 const float distance_link_k)
00152 {
00153
00154 vil3d_distance_transform_one_way_with_dir(image,orient,distance_link_i,distance_link_j,distance_link_k);
00155
00156
00157 unsigned ni = image.ni(), nj = image.nj(), nk = image.nk();
00158 vil3d_image_view<float> flip_image(image.memory_chunk(),
00159 &image(ni-1,nj-1,nk-1), ni,nj,nk,1,
00160 -image.istep(), -image.jstep(), -image.kstep(),
00161 image.nplanes());
00162
00163
00164 vil3d_image_view<vil_rgb<float> >::iterator it = orient.begin();
00165 while (it != orient.end()) {
00166 vil_rgb<float>& v = *it;
00167 v*=-1.0;
00168 it++;
00169 }
00170
00171
00172 vil3d_image_view<vil_rgb<float> > flip_orient(orient.memory_chunk(),
00173 &orient(ni-1,nj-1,nk-1), ni,nj,nk,1,
00174 -orient.istep(), -orient.jstep(), -orient.kstep(),
00175 orient.nplanes());
00176
00177
00178 vil3d_distance_transform_one_way_with_dir(flip_image,flip_orient,distance_link_i,distance_link_j,distance_link_k);
00179 }
00180
00181
00182
00183
00184
00185
00186
00187 void vil3d_distance_transform_one_way(vil3d_image_view<float>& image,
00188 const float distance_link_i,
00189 const float distance_link_j,
00190 const float distance_link_k)
00191 {
00192 assert(image.nplanes()==1);
00193 unsigned ni = image.ni();
00194 unsigned nj = image.nj();
00195 unsigned nk = image.nk();
00196 unsigned ni2 = ni-2;
00197 unsigned nj2 = nj-2;
00198
00199 vcl_ptrdiff_t istep = image.istep(), jstep = image.jstep(), kstep = image.kstep();
00200 vcl_ptrdiff_t o1 = -istep, o2 = -jstep-istep, o3 = -jstep, o4 = -jstep+istep;
00201 vcl_ptrdiff_t o5 = -kstep, o6 = -kstep-istep, o7 = -kstep-jstep-istep;
00202 vcl_ptrdiff_t o8 = -kstep-jstep, o9 = -kstep-jstep+istep, o10 = -kstep+istep;
00203 vcl_ptrdiff_t o11 = -kstep+jstep+istep, o12 = -kstep+jstep, o13 = -kstep+jstep-istep;
00204
00205 float *page0 = image.origin_ptr();
00206
00207 const float distance_link_ij=vcl_sqrt(distance_link_i*distance_link_i+distance_link_j*distance_link_j);
00208 const float distance_link_ik=vcl_sqrt(distance_link_i*distance_link_i+distance_link_k*distance_link_k);
00209 const float distance_link_jk=vcl_sqrt(distance_link_j*distance_link_j+distance_link_k*distance_link_k);
00210 const float distance_link_ijk=vcl_sqrt(distance_link_i*distance_link_i+distance_link_j*distance_link_j+distance_link_k*distance_link_k);
00211
00212
00213 float *p0 = page0 + istep;
00214
00215
00216 for (unsigned i=0;i<=ni2;++i,p0+=istep)
00217 {
00218 *p0 = vcl_min(p0[-istep]+distance_link_i,*p0);
00219 }
00220
00221
00222 float *row0 = page0+jstep;
00223
00224 for (unsigned j=1;j<nj;++j,row0+=jstep)
00225 {
00226
00227 *row0 = vcl_min(row0[o3]+distance_link_j,*row0);
00228 *row0 = vcl_min(row0[o4]+distance_link_ij,*row0);
00229
00230
00231 float *p0 = row0+istep;
00232 for (unsigned i=0;i<ni2;i++,p0+=istep)
00233 {
00234 *p0 = vcl_min(p0[o1]+distance_link_i ,*p0);
00235 *p0 = vcl_min(p0[o2]+distance_link_ij,*p0);
00236 *p0 = vcl_min(p0[o3]+distance_link_j ,*p0);
00237 *p0 = vcl_min(p0[o4]+distance_link_ij,*p0);
00238 }
00239
00240
00241 *p0 = vcl_min(p0[o1]+distance_link_i ,*p0);
00242 *p0 = vcl_min(p0[o2]+distance_link_ij,*p0);
00243 *p0 = vcl_min(p0[o3]+distance_link_j ,*p0);
00244 }
00245
00246
00247 page0 += kstep;
00248 for (unsigned k=1;k<nk;k++,page0+=kstep)
00249 {
00250 row0 = page0;
00251
00252
00253 *row0 = vcl_min(row0[o5] +distance_link_k, *row0);
00254 *row0 = vcl_min(row0[o10]+distance_link_ik,*row0);
00255 *row0 = vcl_min(row0[o11]+distance_link_ijk,*row0);
00256 *row0 = vcl_min(row0[o12]+distance_link_jk,*row0);
00257
00258 float *p0 = row0+istep;
00259
00260 for (unsigned i=0;i<ni2;i++,p0+=istep)
00261 {
00262 *p0 = vcl_min(p0[o1] +distance_link_i ,*p0);
00263 *p0 = vcl_min(p0[o5] +distance_link_k ,*p0);
00264 *p0 = vcl_min(p0[o6] +distance_link_ik,*p0);
00265 *p0 = vcl_min(p0[o10]+distance_link_ik,*p0);
00266 *p0 = vcl_min(p0[o11]+distance_link_ijk,*p0);
00267 *p0 = vcl_min(p0[o12]+distance_link_jk,*p0);
00268 *p0 = vcl_min(p0[o13]+distance_link_ijk,*p0);
00269 }
00270
00271
00272 *p0 = vcl_min(p0[o1] +distance_link_i ,*p0);
00273 *p0 = vcl_min(p0[o5] +distance_link_k ,*p0);
00274 *p0 = vcl_min(p0[o6] +distance_link_ik,*p0);
00275 *p0 = vcl_min(p0[o12]+distance_link_jk,*p0);
00276 *p0 = vcl_min(p0[o13]+distance_link_ijk,*p0);
00277
00278
00279 row0 += jstep;
00280
00281 for (unsigned j=0;j<nj2;j++,row0+=jstep)
00282 {
00283
00284 *row0 = vcl_min(row0[o3] +distance_link_j, *row0);
00285 *row0 = vcl_min(row0[o4] +distance_link_ij,*row0);
00286 *row0 = vcl_min(row0[o5] +distance_link_k, *row0);
00287 *row0 = vcl_min(row0[o8] +distance_link_jk,*row0);
00288 *row0 = vcl_min(row0[o9] +distance_link_ijk,*row0);
00289 *row0 = vcl_min(row0[o10]+distance_link_ik,*row0);
00290 *row0 = vcl_min(row0[o11]+distance_link_ijk,*row0);
00291 *row0 = vcl_min(row0[o12]+distance_link_jk,*row0);
00292
00293
00294 p0 = row0 + istep;
00295 for (unsigned i=0;i<ni2;i++,p0+=istep)
00296 {
00297 *p0 = vcl_min(p0[o1] +distance_link_i, *p0);
00298 *p0 = vcl_min(p0[o2] +distance_link_ij,*p0);
00299 *p0 = vcl_min(p0[o3] +distance_link_j, *p0);
00300 *p0 = vcl_min(p0[o4] +distance_link_ij,*p0);
00301 *p0 = vcl_min(p0[o5] +distance_link_k, *p0);
00302 *p0 = vcl_min(p0[o6] +distance_link_ik,*p0);
00303 *p0 = vcl_min(p0[o7] +distance_link_ijk,*p0);
00304 *p0 = vcl_min(p0[o8] +distance_link_jk,*p0);
00305 *p0 = vcl_min(p0[o9] +distance_link_ijk,*p0);
00306 *p0 = vcl_min(p0[o10]+distance_link_ik,*p0);
00307 *p0 = vcl_min(p0[o11]+distance_link_ijk,*p0);
00308 *p0 = vcl_min(p0[o12]+distance_link_jk,*p0);
00309 *p0 = vcl_min(p0[o13]+distance_link_ijk,*p0);
00310 }
00311
00312
00313 *p0 = vcl_min(p0[o1] +distance_link_i, *p0);
00314 *p0 = vcl_min(p0[o2] +distance_link_ij,*p0);
00315 *p0 = vcl_min(p0[o3] +distance_link_j, *p0);
00316 *p0 = vcl_min(p0[o5] +distance_link_k, *p0);
00317 *p0 = vcl_min(p0[o6] +distance_link_ik,*p0);
00318 *p0 = vcl_min(p0[o7] +distance_link_ijk,*p0);
00319 *p0 = vcl_min(p0[o8] +distance_link_jk,*p0);
00320 *p0 = vcl_min(p0[o12]+distance_link_jk,*p0);
00321 *p0 = vcl_min(p0[o13]+distance_link_ijk,*p0);
00322 }
00323
00324
00325
00326
00327 *row0 = vcl_min(row0[o3] +distance_link_j, *row0);
00328 *row0 = vcl_min(row0[o4] +distance_link_ij,*row0);
00329 *row0 = vcl_min(row0[o5] +distance_link_k, *row0);
00330 *row0 = vcl_min(row0[o8] +distance_link_jk,*row0);
00331 *row0 = vcl_min(row0[o9] +distance_link_ijk,*row0);
00332 *row0 = vcl_min(row0[o10]+distance_link_ik,*row0);
00333
00334
00335 p0 = row0 + istep;
00336 for (unsigned i=0;i<ni2;i++,p0+=istep)
00337 {
00338 *p0 = vcl_min(p0[o1] +distance_link_i, *p0);
00339 *p0 = vcl_min(p0[o2] +distance_link_ij,*p0);
00340 *p0 = vcl_min(p0[o3] +distance_link_j, *p0);
00341 *p0 = vcl_min(p0[o4] +distance_link_ij,*p0);
00342 *p0 = vcl_min(p0[o5] +distance_link_k, *p0);
00343 *p0 = vcl_min(p0[o6] +distance_link_ik,*p0);
00344 *p0 = vcl_min(p0[o7] +distance_link_ijk,*p0);
00345 *p0 = vcl_min(p0[o8] +distance_link_jk,*p0);
00346 *p0 = vcl_min(p0[o9] +distance_link_ijk,*p0);
00347 *p0 = vcl_min(p0[o10]+distance_link_ik,*p0);
00348 }
00349
00350
00351 *p0 = vcl_min(p0[o1] +distance_link_i, *p0);
00352 *p0 = vcl_min(p0[o2] +distance_link_ij,*p0);
00353 *p0 = vcl_min(p0[o3] +distance_link_j, *p0);
00354 *p0 = vcl_min(p0[o5] +distance_link_k, *p0);
00355 *p0 = vcl_min(p0[o6] +distance_link_ik,*p0);
00356 *p0 = vcl_min(p0[o7] +distance_link_ijk,*p0);
00357 *p0 = vcl_min(p0[o8] +distance_link_jk,*p0);
00358 }
00359 }
00360
00361 float vil3d_min_comp(float const& a, float const& b, bool& comp)
00362 {
00363 if (a < b)
00364 comp=true;
00365 else
00366 comp=false;
00367 return vcl_min(a,b);
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 void vil3d_distance_transform_one_way_with_dir(vil3d_image_view<float>& image,
00380 vil3d_image_view<vil_rgb<float> >& orient,
00381 const float distance_link_i,
00382 const float distance_link_j,
00383 const float distance_link_k)
00384 {
00385 assert(image.nplanes()==1);
00386 unsigned ni = image.ni();
00387 unsigned nj = image.nj();
00388 unsigned nk = image.nk();
00389 assert(ni == orient.ni() && nj == orient.nj() && nk == orient.nk());
00390 unsigned ni2 = ni-2;
00391 unsigned nj2 = nj-2;
00392
00393 vcl_ptrdiff_t istep = image.istep(), jstep = image.jstep(), kstep = image.kstep();
00394 vcl_ptrdiff_t orient_istep = orient.istep(), orient_jstep = orient.jstep(), orient_kstep = orient.kstep();
00395
00396 vcl_ptrdiff_t o1 = -istep, o2 = -jstep-istep, o3 = -jstep, o4 = -jstep+istep;
00397 vcl_ptrdiff_t o5 = -kstep, o6 = -kstep-istep, o7 = -kstep-jstep-istep;
00398 vcl_ptrdiff_t o8 = -kstep-jstep, o9 = -kstep-jstep+istep, o10 = -kstep+istep;
00399 vcl_ptrdiff_t o11 = -kstep+jstep+istep, o12 = -kstep+jstep, o13 = -kstep+jstep-istep;
00400
00401 vcl_ptrdiff_t oo1 = -orient_istep;
00402 vcl_ptrdiff_t oo2 = -orient_jstep-orient_istep;
00403 vcl_ptrdiff_t oo3 = -orient_jstep;
00404 vcl_ptrdiff_t oo4 = -orient_jstep+orient_istep;
00405 vcl_ptrdiff_t oo5 = -orient_kstep;
00406 vcl_ptrdiff_t oo6 = -orient_kstep-orient_istep;
00407 vcl_ptrdiff_t oo7 = -orient_kstep-orient_jstep-orient_istep;
00408 vcl_ptrdiff_t oo8 = -orient_kstep-orient_jstep;
00409 vcl_ptrdiff_t oo9 = -orient_kstep-orient_jstep+orient_istep;
00410 vcl_ptrdiff_t oo10 = -orient_kstep+orient_istep;
00411 vcl_ptrdiff_t oo11 = -orient_kstep+orient_jstep+orient_istep;
00412 vcl_ptrdiff_t oo12 = -orient_kstep+orient_jstep;
00413 vcl_ptrdiff_t oo13 = -orient_kstep+orient_jstep-orient_istep;
00414
00415
00416
00417 vil_rgb<float> v1(1,0,0);
00418 vil_rgb<float> v2(1,1,0);
00419 vil_rgb<float> v3(0,1,0);
00420 vil_rgb<float> v4(-1,1,0);
00421 vil_rgb<float> v5(0,0,1);
00422 vil_rgb<float> v6(1,0,1);
00423 vil_rgb<float> v7(1,1,1);
00424 vil_rgb<float> v8(0,1,1);
00425 vil_rgb<float> v9(-1,1,1);
00426 vil_rgb<float> v10(-1,0,1);
00427 vil_rgb<float> v11(-1,-1,1);
00428 vil_rgb<float> v12(0,-1,1);
00429 vil_rgb<float> v13(1,-1,1);
00430
00431 float *page0 = image.origin_ptr();
00432 vil_rgb<float> *orient_page0 = orient.origin_ptr();
00433
00434 const float distance_link_ij=vcl_sqrt(distance_link_i*distance_link_i+distance_link_j*distance_link_j);
00435 const float distance_link_ik=vcl_sqrt(distance_link_i*distance_link_i+distance_link_k*distance_link_k);
00436 const float distance_link_jk=vcl_sqrt(distance_link_j*distance_link_j+distance_link_k*distance_link_k);
00437 const float distance_link_ijk=vcl_sqrt(distance_link_i*distance_link_i+distance_link_j*distance_link_j+distance_link_k*distance_link_k);
00438
00439
00440 float *p0 = page0 + istep;
00441 vil_rgb<float> *orient_p0 = orient_page0 + orient_istep;
00442
00443 bool found;
00444
00445
00446 for (unsigned i=0;i<=ni2;++i,p0+=istep,orient_p0+=orient_istep)
00447 {
00448 *p0 = vil3d_min_comp(p0[-istep]+distance_link_i,*p0,found);
00449 if (found) *orient_p0 = orient_p0[-orient_istep]+v1;
00450 }
00451
00452
00453 float *row0 = page0+jstep;
00454 vil_rgb<float> *orient_row0 = orient_page0 + orient_jstep;
00455
00456 for (unsigned j=1;j<nj;++j,row0+=jstep,orient_row0+=orient_jstep)
00457 {
00458
00459 *row0 = vil3d_min_comp(row0[o3]+distance_link_j,*row0,found);
00460 if (found) *orient_row0=orient_row0[oo3]+v3;
00461
00462 *row0 = vil3d_min_comp(row0[o4]+distance_link_ij,*row0,found);
00463 if (found) *orient_row0=orient_row0[oo4]+v4;
00464
00465
00466 float *p0 = row0+istep;
00467 vil_rgb<float> *orient_p0 = orient_row0 + orient_istep;
00468 for (unsigned i=0;i<ni2;i++,p0+=istep,orient_p0+=orient_istep)
00469 {
00470 *p0 = vil3d_min_comp(p0[o1]+distance_link_i ,*p0,found);
00471 if (found) *orient_p0=orient_p0[oo1]+v1;
00472 *p0 = vil3d_min_comp(p0[o2]+distance_link_ij,*p0,found);
00473 if (found) *orient_p0=orient_p0[oo2]+v2;
00474 *p0 = vil3d_min_comp(p0[o3]+distance_link_j ,*p0,found);
00475 if (found) *orient_p0=orient_p0[oo3]+v3;
00476 *p0 = vil3d_min_comp(p0[o4]+distance_link_ij,*p0,found);
00477 if (found) *orient_p0=orient_p0[oo4]+v4;
00478 }
00479
00480
00481 *p0 = vil3d_min_comp(p0[o1]+distance_link_i ,*p0,found);
00482 if (found) *orient_p0=orient_p0[oo1]+v1;
00483 *p0 = vil3d_min_comp(p0[o2]+distance_link_ij,*p0,found);
00484 if (found) *orient_p0=orient_p0[oo2]+v2;
00485 *p0 = vil3d_min_comp(p0[o3]+distance_link_j ,*p0,found);
00486 if (found) *orient_p0=orient_p0[oo3]+v3;
00487 }
00488
00489
00490 page0 += kstep;
00491 orient_page0+=orient_kstep;
00492 for (unsigned k=1;k<nk;k++,page0+=kstep, orient_page0+=orient_kstep)
00493 {
00494 row0 = page0;
00495 orient_row0 = orient_page0;
00496
00497 *row0 = vil3d_min_comp(row0[o5] +distance_link_k, *row0,found);
00498 if (found) *orient_row0 = orient_row0[oo5]+v5;
00499 *row0 = vil3d_min_comp(row0[o10]+distance_link_ik,*row0,found);
00500 if (found) *orient_row0 = orient_row0[oo10]+v10;
00501 *row0 = vil3d_min_comp(row0[o11]+distance_link_ijk,*row0,found);
00502 if (found) *orient_row0 = orient_row0[oo11]+v11;
00503 *row0 = vil3d_min_comp(row0[o12]+distance_link_jk,*row0,found);
00504 if (found) *orient_row0 = orient_row0[oo12]+v12;
00505
00506 float *p0 = row0+istep;
00507 vil_rgb<float> *orient_p0 = orient_row0+orient_istep;
00508
00509 for (unsigned i=0;i<ni2;i++,p0+=istep,orient_p0+=orient_istep)
00510 {
00511 *p0 = vil3d_min_comp(p0[o1] +distance_link_i ,*p0,found);
00512 if (found) *orient_p0=orient_p0[oo1]+v1;
00513 *p0 = vil3d_min_comp(p0[o5] +distance_link_k ,*p0,found);
00514 if (found) *orient_p0=orient_p0[oo5]+v5;
00515 *p0 = vil3d_min_comp(p0[o6] +distance_link_ik,*p0,found);
00516 if (found) *orient_p0=orient_p0[oo6]+v6;
00517 *p0 = vil3d_min_comp(p0[o10]+distance_link_ik,*p0,found);
00518 if (found) *orient_p0=orient_p0[oo10]+v10;
00519 *p0 = vil3d_min_comp(p0[o11]+distance_link_ijk,*p0,found);
00520 if (found) *orient_p0=orient_p0[oo11]+v11;
00521 *p0 = vil3d_min_comp(p0[o12]+distance_link_jk,*p0,found);
00522 if (found) *orient_p0=orient_p0[oo12]+v12;
00523 *p0 = vil3d_min_comp(p0[o13]+distance_link_ijk,*p0,found);
00524 if (found) *orient_p0=orient_p0[oo13]+v13;
00525 }
00526
00527
00528 *p0 = vil3d_min_comp(p0[o1] +distance_link_i ,*p0,found);
00529 if (found) *orient_p0=orient_p0[oo1]+v1;
00530 *p0 = vil3d_min_comp(p0[o5] +distance_link_k ,*p0,found);
00531 if (found) *orient_p0=orient_p0[oo5]+v5;
00532 *p0 = vil3d_min_comp(p0[o6] +distance_link_ik,*p0,found);
00533 if (found) *orient_p0=orient_p0[oo6]+v6;
00534 *p0 = vil3d_min_comp(p0[o12]+distance_link_jk,*p0,found);
00535 if (found) *orient_p0=orient_p0[oo12]+v12;
00536 *p0 = vil3d_min_comp(p0[o13]+distance_link_ijk,*p0,found);
00537 if (found) *orient_p0=orient_p0[oo13]+v13;
00538
00539
00540 row0 += jstep;
00541 orient_row0 += orient_jstep;
00542 for (unsigned j=0;j<nj2;j++,row0+=jstep,orient_row0+=orient_jstep)
00543 {
00544
00545 *row0 = vil3d_min_comp(row0[o3] +distance_link_j, *row0,found);
00546 if (found) *orient_row0=orient_row0[oo3]+v3;
00547 *row0 = vil3d_min_comp(row0[o4] +distance_link_ij,*row0,found);
00548 if (found) *orient_row0=orient_row0[oo4]+v4;
00549 *row0 = vil3d_min_comp(row0[o5] +distance_link_k, *row0,found);
00550 if (found) *orient_row0=orient_row0[oo5]+v5;
00551 *row0 = vil3d_min_comp(row0[o8] +distance_link_jk,*row0,found);
00552 if (found) *orient_row0=orient_row0[oo8]+v8;
00553 *row0 = vil3d_min_comp(row0[o9] +distance_link_ijk,*row0,found);
00554 if (found) *orient_row0=orient_row0[oo9]+v9;
00555 *row0 = vil3d_min_comp(row0[o10]+distance_link_ik,*row0,found);
00556 if (found) *orient_row0=orient_row0[oo10]+v10;
00557 *row0 = vil3d_min_comp(row0[o11]+distance_link_ijk,*row0,found);
00558 if (found) *orient_row0=orient_row0[oo11]+v11;
00559 *row0 = vil3d_min_comp(row0[o12]+distance_link_jk,*row0,found);
00560 if (found) *orient_row0=orient_row0[oo12]+v12;
00561
00562
00563 p0 = row0 + istep;
00564 orient_p0 = orient_row0 + orient_istep;
00565 for (unsigned i=0;i<ni2;i++,p0+=istep,orient_p0+=orient_istep)
00566 {
00567 *p0 = vil3d_min_comp(p0[o1] +distance_link_i, *p0,found);
00568 if (found) *orient_p0=orient_p0[oo1]+v1;
00569 *p0 = vil3d_min_comp(p0[o2] +distance_link_ij,*p0,found);
00570 if (found) *orient_p0=orient_p0[oo2]+v2;
00571 *p0 = vil3d_min_comp(p0[o3] +distance_link_j, *p0,found);
00572 if (found) *orient_p0=orient_p0[oo3]+v3;
00573 *p0 = vil3d_min_comp(p0[o4] +distance_link_ij,*p0,found);
00574 if (found) *orient_p0=orient_p0[oo4]+v4;
00575 *p0 = vil3d_min_comp(p0[o5] +distance_link_k, *p0,found);
00576 if (found) *orient_p0=orient_p0[oo5]+v5;
00577 *p0 = vil3d_min_comp(p0[o6] +distance_link_ik,*p0,found);
00578 if (found) *orient_p0=orient_p0[oo6]+v6;
00579 *p0 = vil3d_min_comp(p0[o7] +distance_link_ijk,*p0,found);
00580 if (found) *orient_p0=orient_p0[oo7]+v7;
00581 *p0 = vil3d_min_comp(p0[o8] +distance_link_jk,*p0,found);
00582 if (found) *orient_p0=orient_p0[oo8]+v8;
00583 *p0 = vil3d_min_comp(p0[o9] +distance_link_ijk,*p0,found);
00584 if (found) *orient_p0=orient_p0[oo9]+v9;
00585 *p0 = vil3d_min_comp(p0[o10]+distance_link_ik,*p0,found);
00586 if (found) *orient_p0=orient_p0[oo10]+v10;
00587 *p0 = vil3d_min_comp(p0[o11]+distance_link_ijk,*p0,found);
00588 if (found) *orient_p0=orient_p0[oo11]+v11;
00589 *p0 = vil3d_min_comp(p0[o12]+distance_link_jk,*p0,found);
00590 if (found) *orient_p0=orient_p0[oo12]+v12;
00591 *p0 = vil3d_min_comp(p0[o13]+distance_link_ijk,*p0,found);
00592 if (found) *orient_p0=orient_p0[oo13]+v13;
00593 }
00594
00595
00596 *p0 = vil3d_min_comp(p0[o1] +distance_link_i, *p0,found);
00597 if (found) *orient_p0=orient_p0[oo1]+v1;
00598 *p0 = vil3d_min_comp(p0[o2] +distance_link_ij,*p0,found);
00599 if (found) *orient_p0=orient_p0[oo2]+v2;
00600 *p0 = vil3d_min_comp(p0[o3] +distance_link_j, *p0,found);
00601 if (found) *orient_p0=orient_p0[oo3]+v3;
00602 *p0 = vil3d_min_comp(p0[o5] +distance_link_k, *p0,found);
00603 if (found) *orient_p0=orient_p0[oo5]+v5;
00604 *p0 = vil3d_min_comp(p0[o6] +distance_link_ik,*p0,found);
00605 if (found) *orient_p0=orient_p0[oo6]+v6;
00606 *p0 = vil3d_min_comp(p0[o7] +distance_link_ijk,*p0,found);
00607 if (found) *orient_p0=orient_p0[oo7]+v7;
00608 *p0 = vil3d_min_comp(p0[o8] +distance_link_jk,*p0,found);
00609 if (found) *orient_p0=orient_p0[oo8]+v8;
00610 *p0 = vil3d_min_comp(p0[o12]+distance_link_jk,*p0,found);
00611 if (found) *orient_p0=orient_p0[oo12]+v12;
00612 *p0 = vil3d_min_comp(p0[o13]+distance_link_ijk,*p0,found);
00613 if (found) *orient_p0=orient_p0[oo13]+v13;
00614 }
00615
00616
00617
00618
00619 *row0 = vil3d_min_comp(row0[o3] +distance_link_j, *row0,found);
00620 if (found) *orient_row0=orient_row0[oo3]+v3;
00621 *row0 = vil3d_min_comp(row0[o4] +distance_link_ij,*row0,found);
00622 if (found) *orient_row0=orient_row0[oo4]+v4;
00623 *row0 = vil3d_min_comp(row0[o5] +distance_link_k, *row0,found);
00624 if (found) *orient_row0=orient_row0[oo5]+v5;
00625 *row0 = vil3d_min_comp(row0[o8] +distance_link_jk,*row0,found);
00626 if (found) *orient_row0=orient_row0[oo8]+v8;
00627 *row0 = vil3d_min_comp(row0[o9] +distance_link_ijk,*row0,found);
00628 if (found) *orient_row0=orient_row0[oo9]+v9;
00629 *row0 = vil3d_min_comp(row0[o10]+distance_link_ik,*row0,found);
00630 if (found) *orient_row0=orient_row0[oo10]+v10;
00631
00632
00633 p0 = row0 + istep;
00634 orient_p0 = orient_row0 + orient_istep;
00635 for (unsigned i=0;i<ni2;i++,p0+=istep,orient_p0+=orient_istep)
00636 {
00637 *p0 = vil3d_min_comp(p0[o1] +distance_link_i, *p0,found);
00638 if (found) *orient_p0=orient_p0[oo1]+v1;
00639 *p0 = vil3d_min_comp(p0[o2] +distance_link_ij,*p0,found);
00640 if (found) *orient_p0=orient_p0[oo2]+v2;
00641 *p0 = vil3d_min_comp(p0[o3] +distance_link_j, *p0,found);
00642 if (found) *orient_p0=orient_p0[oo3]+v3;
00643 *p0 = vil3d_min_comp(p0[o4] +distance_link_ij,*p0,found);
00644 if (found) *orient_p0=orient_p0[oo4]+v4;
00645 *p0 = vil3d_min_comp(p0[o5] +distance_link_k, *p0,found);
00646 if (found) *orient_p0=orient_p0[oo5]+v5;
00647 *p0 = vil3d_min_comp(p0[o6] +distance_link_ik,*p0,found);
00648 if (found) *orient_p0=orient_p0[oo6]+v6;
00649 *p0 = vil3d_min_comp(p0[o7] +distance_link_ijk,*p0,found);
00650 if (found) *orient_p0=orient_p0[oo7]+v7;
00651 *p0 = vil3d_min_comp(p0[o8] +distance_link_jk,*p0,found);
00652 if (found) *orient_p0=orient_p0[oo8]+v8;
00653 *p0 = vil3d_min_comp(p0[o9] +distance_link_ijk,*p0,found);
00654 if (found) *orient_p0=orient_p0[oo9]+v9;
00655 *p0 = vil3d_min_comp(p0[o10]+distance_link_ik,*p0,found);
00656 if (found) *orient_p0=orient_p0[oo10]+v10;
00657 }
00658
00659
00660 *p0 = vil3d_min_comp(p0[o1] +distance_link_i, *p0,found);
00661 if (found) *orient_p0=orient_p0[oo1]+v1;
00662 *p0 = vil3d_min_comp(p0[o2] +distance_link_ij,*p0,found);
00663 if (found) *orient_p0=orient_p0[oo2]+v2;
00664 *p0 = vil3d_min_comp(p0[o3] +distance_link_j, *p0,found);
00665 if (found) *orient_p0=orient_p0[oo3]+v3;
00666 *p0 = vil3d_min_comp(p0[o5] +distance_link_k, *p0,found);
00667 if (found) *orient_p0=orient_p0[oo5]+v5;
00668 *p0 = vil3d_min_comp(p0[o6] +distance_link_ik,*p0,found);
00669 if (found) *orient_p0=orient_p0[oo6]+v6;
00670 *p0 = vil3d_min_comp(p0[o7] +distance_link_ijk,*p0,found);
00671 if (found) *orient_p0=orient_p0[oo7]+v7;
00672 *p0 = vil3d_min_comp(p0[o8] +distance_link_jk,*p0,found);
00673 if (found) *orient_p0=orient_p0[oo8]+v8;
00674 }
00675 }
00676
00677
00678
00679
00680
00681 void vil3d_distance_transform(const vil3d_image_view<bool>& mask,
00682 vil3d_image_view<float>& distance_image,
00683 float max_dist)
00684 {
00685 distance_image.set_size(mask.ni(),mask.nj(),mask.nk());
00686 distance_image.fill(max_dist);
00687
00688
00689 vil3d_distance_transform(distance_image);
00690 }
00691