contrib/mul/vil3d/algo/vil3d_erode.h
Go to the documentation of this file.
00001 #ifndef vil3d_erode_h_
00002 #define vil3d_erode_h_
00003 //:
00004 // \file
00005 // \brief Perform greyscale erosion on 3D images
00006 // \author Tim Cootes Ian Scott
00007 
00008 #include <vil3d/vil3d_image_view.h>
00009 #include <vil3d/vil3d_crop.h>
00010 #include <vil3d/algo/vil3d_structuring_element.h>
00011 #include <vcl_cassert.h>
00012 
00013 //: Return minimum of im[offset[k]], k=0..n;
00014 template <class T>
00015 inline T vil3d_erode(const T* im, const vcl_ptrdiff_t* offset, unsigned n)
00016 {
00017   T min_v = im[offset[0]];
00018   for (unsigned i=1;i<n;++i) if (im[offset[i]] < min_v) min_v=im[offset[i]];
00019   return min_v;
00020 }
00021 
00022 //: Erodes src_image to produce dest_image (assumed single plane)
00023 // \relatesalso vil3d_image_view
00024 // \relatesalso vil3d_structuring_element
00025 template <class T>
00026 void vil3d_erode(const vil3d_image_view<T>& src_image,
00027                  vil3d_image_view<T>& dest_image,
00028                  const vil3d_structuring_element& element)
00029 {
00030   assert(src_image.nplanes()==1);
00031   unsigned ni = src_image.ni(); assert(ni>0);
00032   unsigned nj = src_image.nj(); assert(nj>0);
00033   unsigned nk = src_image.nk(); assert(nk>0);
00034   dest_image.set_size(ni,nj,nk,1);
00035 
00036   vcl_ptrdiff_t s_istep = src_image.istep(),  s_jstep = src_image.jstep();
00037   vcl_ptrdiff_t s_kstep = src_image.kstep();
00038   vcl_ptrdiff_t d_istep = dest_image.istep();
00039 
00040   vcl_vector<vcl_ptrdiff_t> offset;
00041   vil3d_compute_offsets(offset,element,s_istep,s_jstep,s_kstep);
00042 
00043   // Define box in which all element will be valid
00044   int ilo = -element.min_i();
00045   int ihi = ni-1-element.max_i();
00046   int jlo = -element.min_j();
00047   int jhi = nj-1-element.max_j();
00048   int klo = -element.min_k();
00049   int khi = nk-1-element.max_k();
00050 
00051   // Zero low and high i sides
00052   if (ilo>0)    vil3d_crop(dest_image,0,ilo,0,nj,0,nk).fill(0);
00053   if (ihi<int(ni)-1) vil3d_crop(dest_image,ihi+1,ni-ihi-1,0,nj,0,nk).fill(0);
00054 
00055   // Zero low and high j sides
00056   if (jlo>0)    vil3d_crop(dest_image,0,ni,0,jlo,0,nk).fill(0);
00057   if (jhi<int(nj)-1) vil3d_crop(dest_image,0,ni,jhi+1,nj-jhi-1,0,nk).fill(0);
00058 
00059   // Zero low and high k sides
00060   if (klo>0)    vil3d_crop(dest_image,0,ni,0,nj,0,klo).fill(0);
00061   if (khi<int(nk)-1) vil3d_crop(dest_image,0,ni,0,nj,khi+1,nk-khi-1).fill(0);
00062 
00063   for (int k=klo;k<=khi;++k)
00064     for (int j=jlo;j<=jhi;++j)
00065     {
00066       const T* src_p = &src_image(ilo,j,k);
00067       T* dest_p = &dest_image(ilo,j,k);
00068 
00069       for (int i=ilo;i<=ihi;++i,src_p+=s_istep,dest_p+=d_istep)
00070         *dest_p=vil3d_erode(src_p,&offset[0],offset.size());
00071     }
00072 }
00073 
00074 #endif // vil3d_erode_h_