core/vil/algo/vil_exp_filter_1d.h
Go to the documentation of this file.
00001 #ifndef vil_exp_filter_1d_h_
00002 #define vil_exp_filter_1d_h_
00003 //:
00004 // \file
00005 // \brief Apply exponential filter
00006 // \author Tim Cootes
00007 
00008 #include <vil/vil_image_view.h>
00009 
00010 //: Apply exponential filter to 1D data
00011 //  Apply filter to n values src[i*sstep] to produce output dest[i*dstep]
00012 //  Symmetric exponential filter of the form exp(c*|x|) applied. c=log(k)
00013 //  Uses fast recursive implementation.
00014 template <class srcT, class destT, class accumT>
00015 inline void vil_exp_filter_1d(const srcT* src, vcl_ptrdiff_t sstep,
00016                               destT* dest, vcl_ptrdiff_t dstep,
00017                               int n, accumT k)
00018 {
00019   const srcT* s = src;
00020   const srcT* src_end = src + n*sstep;
00021   double f = (1-k)/(1+k);
00022 
00023   // Forward pass
00024   accumT rt=0;
00025   while (s!=src_end)
00026   {
00027     rt += *s;
00028     *dest = destT(f * rt);
00029     rt *= k;
00030     s+=sstep; dest+=dstep;
00031   }
00032 
00033   // Backward pass
00034   s-=sstep; dest-=dstep;
00035   src_end = src-sstep;
00036   rt=0;
00037   while (s!=src_end)
00038   {
00039     // Central value already included once, so only add it after updating dest.
00040     *dest += destT(f * rt);
00041     rt += *s;
00042     rt *= k;
00043     s-=sstep; dest-=dstep;
00044   }
00045 }
00046 
00047 //: Apply exponential filter along i to src_im to produce dest_im
00048 //  Symmetric exponential filter of the form exp(c*|i|) applied. c=log(k)
00049 //  Uses fast recursive implementation.
00050 // \relatesalso vil_image_view
00051 template <class srcT, class destT, class accumT>
00052 inline void vil_exp_filter_i(const vil_image_view<srcT>& src_im,
00053                              vil_image_view<destT>& dest_im,
00054                              accumT k)
00055 {
00056   unsigned ni = src_im.ni();
00057   unsigned nj = src_im.nj();
00058   dest_im.set_size(ni,nj,src_im.nplanes());
00059   vcl_ptrdiff_t s_istep = src_im.istep(), s_jstep = src_im.jstep();
00060   vcl_ptrdiff_t d_istep = dest_im.istep(),d_jstep = dest_im.jstep();
00061 
00062   for (unsigned p=0;p<src_im.nplanes();++p)
00063   {
00064     const srcT*  src_row  = src_im.top_left_ptr()+p*src_im.planestep();
00065     destT* dest_row = dest_im.top_left_ptr()+p*dest_im.planestep();
00066     // Filter each row
00067     for (unsigned j=0;j<nj;++j,src_row+=s_jstep,dest_row+=d_jstep)
00068       vil_exp_filter_1d(src_row,s_istep, dest_row,d_istep,   ni, k);
00069   }
00070 }
00071 
00072 //: Apply exponential filter along j to src_im to produce dest_im
00073 //  Symmetric exponential filter of the form exp(c*|j|) applied. c=log(k)
00074 //  Uses fast recursive implementation.
00075 // \relatesalso vil_image_view
00076 template <class srcT, class destT, class accumT>
00077 inline void vil_exp_filter_j(const vil_image_view<srcT>& src_im,
00078                              vil_image_view<destT>& dest_im,
00079                              accumT k)
00080 {
00081   unsigned ni = src_im.ni();
00082   unsigned nj = src_im.nj();
00083   dest_im.set_size(ni,nj,src_im.nplanes());
00084   vcl_ptrdiff_t s_istep = src_im.istep(), s_jstep = src_im.jstep();
00085   vcl_ptrdiff_t d_istep = dest_im.istep(),d_jstep = dest_im.jstep();
00086 
00087   for (unsigned p=0;p<src_im.nplanes();++p)
00088   {
00089     const srcT*  src_col  = src_im.top_left_ptr()+p*src_im.planestep();
00090     destT* dest_col = dest_im.top_left_ptr()+p*dest_im.planestep();
00091     // Filter each col
00092     for (unsigned i=0;i<ni;++i,src_col+=s_istep,dest_col+=d_istep)
00093       vil_exp_filter_1d(src_col,s_jstep, dest_col,d_jstep,   nj, k);
00094   }
00095 }
00096 
00097 #endif // vil_exp_filter_1d_h_