core/vil/algo/vil_correlate_2d.h
Go to the documentation of this file.
00001 // This is core/vil/algo/vil_correlate_2d.h
00002 #ifndef vil_correlate_2d_h_
00003 #define vil_correlate_2d_h_
00004 //:
00005 // \file
00006 // \brief 2D Convolution
00007 // \author Tim Cootes
00008 
00009 #include <vcl_compiler.h>
00010 #include <vcl_cassert.h>
00011 #include <vil/vil_image_view.h>
00012 
00013 //: Evaluate dot product between kernel and src_im
00014 // Returns  sum_ijp src_im[i*istep+j*jstep+p*pstep]*kernel(i,j,p)
00015 // \relatesalso vil_image_view
00016 template <class srcT, class kernelT, class accumT>
00017 inline accumT vil_correlate_2d_at_pt(const srcT *src_im, vcl_ptrdiff_t s_istep,
00018                                      vcl_ptrdiff_t s_jstep, vcl_ptrdiff_t s_pstep,
00019                                      const vil_image_view<kernelT>& kernel,
00020                                      accumT)
00021 {
00022   unsigned ni = kernel.ni();
00023   unsigned nj = kernel.nj();
00024   unsigned np = kernel.nplanes();
00025 
00026   vcl_ptrdiff_t k_istep = kernel.istep(), k_jstep = kernel.jstep();
00027 
00028   accumT sum=0;
00029   for (unsigned p = 0; p<np; ++p)
00030   {
00031     // Select first row of p-th plane
00032     const srcT*  src_row  = src_im + p*s_pstep;
00033     const kernelT* k_row =  kernel.top_left_ptr() + p*kernel.planestep();
00034 
00035     for (unsigned int j=0;j<nj;++j,src_row+=s_jstep,k_row+=k_jstep)
00036     {
00037       const srcT* sp = src_row;
00038       const kernelT* kp = k_row;
00039       // Sum over j-th row
00040       for (unsigned int i=0;i<ni;++i, sp += s_istep, kp += k_istep)
00041         sum += accumT(*sp)*accumT(*kp);
00042     }
00043   }
00044 
00045   return sum;
00046 }
00047 
00048 //: Correlate kernel with srcT
00049 // dest is resized to (1+src_im.ni()-kernel.ni())x(1+src_im.nj()-kernel.nj())
00050 // (a one plane image).
00051 // On exit dest(x,y) = sum_ij src_im(x+i,y+j)*kernel(i,j)
00052 // \relatesalso vil_image_view
00053 template <class srcT, class destT, class kernelT, class accumT>
00054 inline void vil_correlate_2d(const vil_image_view<srcT>& src_im,
00055                              vil_image_view<destT>& dest_im,
00056                              const vil_image_view<kernelT>& kernel,
00057                              accumT ac)
00058 {
00059   int ni = 1+src_im.ni()-kernel.ni(); assert(ni >= 0);
00060   int nj = 1+src_im.nj()-kernel.nj(); assert(nj >= 0);
00061   vcl_ptrdiff_t s_istep = src_im.istep(), s_jstep = src_im.jstep();
00062   vcl_ptrdiff_t s_pstep = src_im.planestep();
00063 
00064   dest_im.set_size(ni,nj,1);
00065   vcl_ptrdiff_t d_istep = dest_im.istep(),d_jstep = dest_im.jstep();
00066 
00067   // Select first row of p-th plane
00068   const srcT*  src_row  = src_im.top_left_ptr();
00069   destT* dest_row = dest_im.top_left_ptr();
00070 
00071   for (int j=0;j<nj;++j,src_row+=s_jstep,dest_row+=d_jstep)
00072   {
00073     const srcT* sp = src_row;
00074     destT* dp = dest_row;
00075     for (int i=0;i<ni;++i, sp += s_istep, dp += d_istep)
00076       *dp = (destT)vil_correlate_2d_at_pt(sp,s_istep,s_jstep,s_pstep,kernel,ac);
00077       // Correlate at src(i,j)
00078   }
00079 }
00080 
00081 #endif // vil_correlate_2d_h_