contrib/mul/vil3d/algo/vil3d_grad_1x3.h
Go to the documentation of this file.
00001 #ifndef vil3d_grad_1x3_h_
00002 #define vil3d_grad_1x3_h_
00003 //:
00004 //  \file
00005 //  \brief Apply 1x3 gradient operator (-0.5 0 0.5) to image data
00006 //  \author Tim Cootes
00007 
00008 #include <vil3d/vil3d_image_view.h>
00009 #include <vil3d/vil3d_switch_axes.h>
00010 #include <vxl_config.h>
00011 
00012 //: Compute gradients of an image using (-0.5 0 0.5) Sobel filters
00013 //  Computes both i,j and k gradients of an ni x nj x nk plane of data
00014 //  1 pixel border around grad images is set to zero
00015 // \relatesalso vil3d_image_view
00016 template<class srcT, class destT>
00017 void vil3d_grad_1x3(const vil3d_image_view<srcT>& src,
00018                     vil3d_image_view<destT>& grad_i,
00019                     vil3d_image_view<destT>& grad_j,
00020                     vil3d_image_view<destT>& grad_k);
00021 
00022 //: Compute gradients of an image using (-0.5 0 0.5) filters
00023 //  Computes both i,j and k gradients of an image.
00024 //  grad_ijk has three times as many planes as src, with dest plane (3i) being the i-gradient
00025 //  of source plane i and dest plane (3i+1) being the j-gradient etc
00026 //  1 pixel border around grad images is set to zero
00027 // \relatesalso vil3d_image_view
00028 template<class srcT, class destT>
00029 void vil3d_grad_1x3(const vil3d_image_view<srcT>& src,
00030                     vil3d_image_view<destT>& grad_ijk);
00031 
00032 //: Compute square gradient magnitude of 3D image
00033 //  Use (-0.5,0,+0.5) filters in i,j,k
00034 template<class srcT, class destT>
00035 void vil3d_grad_1x3_mag_sq(const vil3d_image_view<srcT>& src,
00036                     vil3d_image_view<destT>& grad_mag2);
00037 
00038 //: Compute gradients of single plane of 2D data using (-0.5 0 0.5) filters
00039 //  Computes both i,j and k gradients of an ni x nj x nk plane of data
00040 //  1 pixel border around grad images is set to zero
00041 void vil3d_grad_1x3_1plane(const vil3d_image_view<vxl_byte>& src,
00042                     vil3d_image_view<float>& grad_i,
00043                     vil3d_image_view<float>& grad_j,
00044                     vil3d_image_view<float>& grad_k);
00045 
00046 //: Compute gradients of single plane of 2D data using (-0.5 0 0.5) filters
00047 //  Computes both i,j and k gradients of an ni x nj x nk plane of data
00048 //  1 pixel border around grad images is set to zero
00049 void vil3d_grad_1x3_1plane(const vil3d_image_view<float>& src,
00050                     vil3d_image_view<float>& grad_i,
00051                     vil3d_image_view<float>& grad_j,
00052                     vil3d_image_view<float>& grad_k);
00053 
00054 //: Compute gradients of single plane of 2D data using (-0.5 0 0.5) filters
00055 //  Computes both i,j and k gradients of an ni x nj x nk plane of data
00056 //  1 pixel border around grad images is set to zero
00057 void vil3d_grad_1x3_1plane(const vil3d_image_view<vxl_int_32>& src,
00058                     vil3d_image_view<float>& grad_i,
00059                     vil3d_image_view<float>& grad_j,
00060                     vil3d_image_view<float>& grad_k);
00061 
00062 //: Compute square dgradient magnitude of single plane of 3D data
00063 //  Use (-0.5,0,+0.5) filters in i,j,k
00064 void vil3d_grad_1x3_mag_sq_1plane(const vil3d_image_view<vxl_byte>& src_im,
00065                     vil3d_image_view<float>& grad_mag2);
00066 
00067 //: Compute square gradient magnitude of single plane of 3D data
00068 //  Use (-0.5,0,+0.5) filters in i,j,k
00069 void vil3d_grad_1x3_mag_sq_1plane(const vil3d_image_view<float>& src_im,
00070                     vil3d_image_view<float>& grad_mag2);
00071 
00072 //: Compute square gradient magnitude of single plane of 3D data
00073 //  Use (-0.5,0,+0.5) filters in i,j,k
00074 void vil3d_grad_1x3_mag_sq_1plane(const vil3d_image_view<vxl_int_32>& src_im,
00075                     vil3d_image_view<float>& grad_mag2);
00076 
00077 //: Compute gradient by applying (-0.5 0 0.5) filter along i axis
00078 //  Resulting image has same size. Border pixels (i=0,ni-1) set to zero.
00079 template<class srcT, class destT>
00080 void vil3d_grad_1x3_i(const vil3d_image_view<srcT>& src_im,
00081                       vil3d_image_view<destT>& grad_im)
00082 {
00083   const unsigned n_i = src_im.ni(),
00084                  n_j = src_im.nj(),
00085                  n_k = src_im.nk(),
00086                  n_p = src_im.nplanes();
00087   const unsigned ni1 = n_i-1;
00088   const vcl_ptrdiff_t s_istep = src_im.istep(),
00089                     s_jstep = src_im.jstep(),
00090                     s_kstep = src_im.kstep(),
00091                     s_pstep = src_im.planestep();
00092 
00093   grad_im.set_size(n_i, n_j, n_k, n_p);
00094 
00095   const vcl_ptrdiff_t d_istep = grad_im.istep(),
00096                       d_jstep = grad_im.jstep(),
00097                       d_kstep = grad_im.kstep(),
00098                       d_pstep = grad_im.planestep();
00099 
00100   // Select first plane
00101   const srcT*  src_plane = src_im.origin_ptr();
00102   destT*      dest_plane = grad_im.origin_ptr();
00103   for (unsigned p=0; p<n_p; ++p, src_plane+=s_pstep, dest_plane+=d_pstep)
00104   {
00105     // Select first slice of p-th plane
00106     const srcT* src_slice = src_plane;
00107     destT*     dest_slice = dest_plane;
00108     for (unsigned k=0; k<n_k; ++k, src_slice+=s_kstep, dest_slice+=d_kstep)
00109     {
00110       // Apply convolution to each row in turn
00111       // Note: Could check if either istep is 1 for speed optimisation.
00112       const srcT* src_row = src_slice;
00113       destT*     dest_row = dest_slice;
00114 
00115       for (unsigned int j=0; j<n_j; ++j, src_row+=s_jstep, dest_row+=d_jstep)
00116       {
00117         const srcT *s1 = src_row;
00118         const srcT *s2 = src_row+2*s_istep;
00119         destT * d = dest_row+d_istep;
00120         destT * end_d = dest_row + ni1*d_istep;
00121         *dest_row=0;  // Zero the border
00122         *end_d = 0;
00123         for (; d!=end_d; d+=d_istep,s1+=s_istep,s2+=s_istep)
00124           *d = 0.5f * (*s2 - *s1);
00125       }
00126     }
00127   }
00128 }
00129 
00130 //: Compute gradient by applying (-0.5 0 0.5) filter along j axis
00131 //  Resulting image has same size. Border pixels (j=0,nj-1) set to zero.
00132 template<class srcT, class destT>
00133 void vil3d_grad_1x3_j(const vil3d_image_view<srcT>& src_im,
00134                         vil3d_image_view<destT>& grad_im)
00135 {
00136   grad_im.set_size(src_im.ni(),src_im.nj(),src_im.nk(),src_im.nplanes());
00137 
00138   // Generate new views so that j-axis becomes the i-axis
00139   vil3d_image_view<srcT> src_jik = vil3d_switch_axes_jik(src_im);
00140   vil3d_image_view<destT> grad_jik = vil3d_switch_axes_jik(grad_im);
00141   vil3d_grad_1x3_i(src_jik,grad_jik);
00142 }
00143 
00144 //: Compute gradient by applying (-0.5 0 0.5) filter along k axis
00145 //  Resulting image has same size. Border pixels (k=0,nk-1) set to zero.
00146 template<class srcT, class destT>
00147 void vil3d_grad_1x3_k(const vil3d_image_view<srcT>& src_im,
00148                         vil3d_image_view<destT>& grad_im)
00149 {
00150   grad_im.set_size(src_im.ni(),src_im.nj(),src_im.nk(),src_im.nplanes());
00151 
00152   // Generate new views so that j-axis becomes the i-axis
00153   vil3d_image_view<srcT> src_kij = vil3d_switch_axes_kij(src_im);
00154   vil3d_image_view<destT> grad_kij = vil3d_switch_axes_kij(grad_im);
00155   vil3d_grad_1x3_i(src_kij,grad_kij);
00156 }
00157 
00158 #endif // vil3d_grad_1x3_h_