contrib/mul/vil3d/algo/vil3d_smooth_121.h
Go to the documentation of this file.
00001 // This is mul/vil3d/algo/vil3d_smooth_121.h
00002 #ifndef vil3d_smooth_121_h_
00003 #define vil3d_smooth_121_h_
00004 //:
00005 // \file
00006 // \brief Smooth 3D image with a (1 2 1)/4 filter.
00007 // \author Tim Cootes
00008 
00009 #include <vil3d/vil3d_image_view.h>
00010 #include <vil3d/vil3d_switch_axes.h>
00011 
00012 //: Smooth src_im by applying (0.25 0.5 0.25) filter along i axis
00013 //  Resulting image has same size. Border pixels (i=0,ni-1) set to zero.
00014 template<class srcT, class destT>
00015 void vil3d_smooth_121_i(const vil3d_image_view<srcT>& src_im,
00016                         vil3d_image_view<destT>& smooth_im)
00017 {
00018   const unsigned n_i = src_im.ni(),
00019                  n_j = src_im.nj(),
00020                  n_k = src_im.nk(),
00021                  n_p = src_im.nplanes();
00022   const unsigned ni1 = n_i-1;
00023   const vcl_ptrdiff_t s_istep = src_im.istep(),
00024                     s_jstep = src_im.jstep(),
00025                     s_kstep = src_im.kstep(),
00026                     s_pstep = src_im.planestep();
00027 
00028   smooth_im.set_size(n_i, n_j, n_k, n_p);
00029 
00030   const vcl_ptrdiff_t d_istep = smooth_im.istep(),
00031                       d_jstep = smooth_im.jstep(),
00032                       d_kstep = smooth_im.kstep(),
00033                       d_pstep = smooth_im.planestep();
00034 
00035   // Select first plane
00036   const srcT*  src_plane = src_im.origin_ptr();
00037   destT*      dest_plane = smooth_im.origin_ptr();
00038   for (unsigned p=0; p<n_p; ++p, src_plane+=s_pstep, dest_plane+=d_pstep)
00039   {
00040     // Select first slice of p-th plane
00041     const srcT* src_slice = src_plane;
00042     destT*     dest_slice = dest_plane;
00043     for (unsigned k=0; k<n_k; ++k, src_slice+=s_kstep, dest_slice+=d_kstep)
00044     {
00045       // Apply convolution to each row in turn
00046       // Note: Could check if either istep is 1 for speed optimisation.
00047       const srcT* src_row = src_slice;
00048       destT*     dest_row = dest_slice;
00049 
00050       for (unsigned int j=0; j<n_j; ++j, src_row+=s_jstep, dest_row+=d_jstep)
00051       {
00052         const srcT *s = src_row+s_istep;
00053         destT * d = dest_row+d_istep;
00054         destT * end_d = dest_row + ni1*d_istep;
00055         *dest_row=0;  // Zero the border
00056         *end_d = 0;
00057         for (;d!=end_d;d+=d_istep,s+=s_istep)
00058           *d = 0.25f*s[-s_istep] + 0.5f*s[0] + 0.25f*s[s_istep];
00059       }
00060     }
00061   }
00062 }
00063 
00064 //: Smooth src_im by applying (0.25 0.5 0.25) filter along j axis
00065 //  Resulting image has same size. Border pixels (j=0,nj-1) set to zero.
00066 template<class srcT, class destT>
00067 void vil3d_smooth_121_j(const vil3d_image_view<srcT>& src_im,
00068                         vil3d_image_view<destT>& smooth_im)
00069 {
00070   smooth_im.set_size(src_im.ni(),src_im.nj(),src_im.nk(),src_im.nplanes());
00071 
00072   // Generate new views so that j-axis becomes the i-axis
00073   vil3d_image_view<srcT> src_jik = vil3d_switch_axes_jik(src_im);
00074   vil3d_image_view<destT> smooth_jik = vil3d_switch_axes_jik(smooth_im);
00075   vil3d_smooth_121_i(src_jik,smooth_jik);
00076 }
00077 
00078 //: Smooth src_im by applying (0.25 0.5 0.25) filter along k axis
00079 //  Resulting image has same size. Border pixels (k=0,nk-1) set to zero.
00080 template<class srcT, class destT>
00081 void vil3d_smooth_121_k(const vil3d_image_view<srcT>& src_im,
00082                         vil3d_image_view<destT>& smooth_im)
00083 {
00084   smooth_im.set_size(src_im.ni(),src_im.nj(),src_im.nk(),src_im.nplanes());
00085 
00086   // Generate new views so that j-axis becomes the i-axis
00087   vil3d_image_view<srcT> src_kij = vil3d_switch_axes_kij(src_im);
00088   vil3d_image_view<destT> smooth_kij = vil3d_switch_axes_kij(smooth_im);
00089   vil3d_smooth_121_i(src_kij,smooth_kij);
00090 }
00091 
00092 //: Smooth src_im by applying (0.25 0.5 0.25) filter along each axis in turn
00093 //  Resulting image has same size. Border pixels set to zero.
00094 template<class srcT, class destT>
00095 void vil3d_smooth_121(const vil3d_image_view<srcT>& src_im,
00096                         vil3d_image_view<destT>& smooth_im)
00097 {
00098   vil3d_image_view<destT> tmp_im;
00099   vil3d_smooth_121_i(src_im,smooth_im);  // Use smooth_im as temporary store
00100   vil3d_smooth_121_j(smooth_im,tmp_im);
00101   vil3d_smooth_121_k(tmp_im,smooth_im);  // Overwrite smooth_im with final result
00102 }
00103 
00104 #endif // vil3d_smooth_121_h_