core/vil/algo/vil_median.txx
Go to the documentation of this file.
00001 #ifndef vil_median_txx_
00002 #define vil_median_txx_
00003 //:
00004 // \file
00005 // \brief Perform median filtering on images
00006 // \author Tim Cootes
00007 
00008 #include "vil_median.h"
00009 #include <vcl_cassert.h>
00010 
00011 //: Computes median value of pixels under structuring element.
00012 // dest_image(i0,j0) is the median value of the pixels under the
00013 // structuring element when it is centred on src_image(i0,j0)
00014 template <class T>
00015 void vil_median(const vil_image_view<T>& src_image,
00016                 vil_image_view<T>& dest_image,
00017                 const vil_structuring_element& element)
00018 {
00019   assert(src_image.nplanes()==1);
00020   unsigned ni = src_image.ni();
00021   unsigned nj = src_image.nj();
00022   dest_image.set_size(ni,nj,1);
00023 
00024   vcl_ptrdiff_t s_istep = src_image.istep(),  s_jstep = src_image.jstep();
00025   vcl_ptrdiff_t d_istep = dest_image.istep(), d_jstep = dest_image.jstep();
00026 
00027   const T* src_row0 = src_image.top_left_ptr();
00028   T* dest_row0 = dest_image.top_left_ptr();
00029 
00030   vcl_vector<vcl_ptrdiff_t> offset;
00031   vil_compute_offsets(offset,element,s_istep,s_jstep);
00032 
00033   vcl_vector<T> value_wkspce;
00034 
00035   // Define box in which all element will be valid
00036   int ilo = -element.min_i();
00037   int ihi = ni-1-element.max_i();
00038   int jlo = -element.min_j();
00039   int jhi = nj-1-element.max_j();
00040 
00041   // Deal with left edge
00042   for (int i=0;i<ilo;++i)
00043     for (unsigned int j=0;j<nj;++j)
00044       dest_image(i,j,0)=vil_sorted_value(src_image,0,element,i,j,value_wkspce,0.5);
00045   // Deal with right edge
00046   for (unsigned int i=ihi+1;i<ni;++i)
00047     for (unsigned int j=0;j<nj;++j)
00048       dest_image(i,j,0)=vil_sorted_value(src_image,0,element,i,j,value_wkspce,0.5);
00049   // Deal with bottom edge
00050   for (int i=ilo;i<=ihi;++i)
00051     for (int j=0;j<jlo;++j)
00052       dest_image(i,j,0)=vil_sorted_value(src_image,0,element,i,j,value_wkspce,0.5);
00053   // Deal with top edge
00054   for (int i=ilo;i<=ihi;++i)
00055     for (unsigned int j=jhi+1;j<nj;++j)
00056       dest_image(i,j,0)=vil_sorted_value(src_image,0,element,i,j,value_wkspce,0.5);
00057 
00058   // No bounds checks in the interior, so we must make sure there is enough space in
00059   // the workspace.
00060   value_wkspce.resize( offset.size() );
00061   int rank = int(0.5*(offset.size()-1));
00062   for (int j=jlo;j<=jhi;++j)
00063   {
00064     const T* src_p = src_row0 + j*s_jstep + ilo*s_istep;
00065     T* dest_p = dest_row0 + j*d_jstep + ilo * d_istep;
00066 
00067     for (int i=ilo;i<=ihi;++i,src_p+=s_istep,dest_p+=d_istep)
00068       *dest_p=vil_sorted_value(src_p,&offset[0],value_wkspce.begin(),offset.size(),rank);
00069   }
00070 }
00071 
00072 #undef VIL_MEDIAN_INSTANTIATE
00073 #define VIL_MEDIAN_INSTANTIATE(T) \
00074 template void vil_median(const vil_image_view< T >& src_image, \
00075                          vil_image_view< T >& dest_image, \
00076                          const vil_structuring_element& element)
00077 
00078 #endif // vil_median_txx_