vil_exp_filter_1d.h
Go to the documentation of this file.
1 #ifndef vil_exp_filter_1d_h_
2 #define vil_exp_filter_1d_h_
3 //:
4 // \file
5 // \brief Apply exponential filter
6 // \author Tim Cootes
7 
8 #include <vil/vil_image_view.h>
9 
10 //: Apply exponential filter to 1D data
11 // Apply filter to n values src[i*sstep] to produce output dest[i*dstep]
12 // Symmetric exponential filter of the form exp(c*|x|) applied. c=log(k)
13 // Uses fast recursive implementation.
14 template <class srcT, class destT, class accumT>
15 inline void vil_exp_filter_1d(const srcT* src, std::ptrdiff_t sstep,
16  destT* dest, std::ptrdiff_t dstep,
17  int n, accumT k)
18 {
19  const srcT* s = src;
20  const srcT* src_end = src + n*sstep;
21  double f = (1-k)/(1+k);
22 
23  // Forward pass
24  accumT rt=0;
25  while (s!=src_end)
26  {
27  rt += *s;
28  *dest = destT(f * rt);
29  rt *= k;
30  s+=sstep; dest+=dstep;
31  }
32 
33  // Backward pass
34  s-=sstep; dest-=dstep;
35  src_end = src-sstep;
36  rt=0;
37  while (s!=src_end)
38  {
39  // Central value already included once, so only add it after updating dest.
40  *dest += destT(f * rt);
41  rt += *s;
42  rt *= k;
43  s-=sstep; dest-=dstep;
44  }
45 }
46 
47 //: Apply exponential filter along i to src_im to produce dest_im
48 // Symmetric exponential filter of the form exp(c*|i|) applied. c=log(k)
49 // Uses fast recursive implementation.
50 // \relatesalso vil_image_view
51 template <class srcT, class destT, class accumT>
52 inline void vil_exp_filter_i(const vil_image_view<srcT>& src_im,
53  vil_image_view<destT>& dest_im,
54  accumT k)
55 {
56  unsigned ni = src_im.ni();
57  unsigned nj = src_im.nj();
58  dest_im.set_size(ni,nj,src_im.nplanes());
59  std::ptrdiff_t s_istep = src_im.istep(), s_jstep = src_im.jstep();
60  std::ptrdiff_t d_istep = dest_im.istep(),d_jstep = dest_im.jstep();
61 
62  for (unsigned p=0;p<src_im.nplanes();++p)
63  {
64  const srcT* src_row = src_im.top_left_ptr()+p*src_im.planestep();
65  destT* dest_row = dest_im.top_left_ptr()+p*dest_im.planestep();
66  // Filter each row
67  for (unsigned j=0;j<nj;++j,src_row+=s_jstep,dest_row+=d_jstep)
68  vil_exp_filter_1d(src_row,s_istep, dest_row,d_istep, ni, k);
69  }
70 }
71 
72 //: Apply exponential filter along j to src_im to produce dest_im
73 // Symmetric exponential filter of the form exp(c*|j|) applied. c=log(k)
74 // Uses fast recursive implementation.
75 // \relatesalso vil_image_view
76 template <class srcT, class destT, class accumT>
77 inline void vil_exp_filter_j(const vil_image_view<srcT>& src_im,
78  vil_image_view<destT>& dest_im,
79  accumT k)
80 {
81  unsigned ni = src_im.ni();
82  unsigned nj = src_im.nj();
83  dest_im.set_size(ni,nj,src_im.nplanes());
84  std::ptrdiff_t s_istep = src_im.istep(), s_jstep = src_im.jstep();
85  std::ptrdiff_t d_istep = dest_im.istep(),d_jstep = dest_im.jstep();
86 
87  for (unsigned p=0;p<src_im.nplanes();++p)
88  {
89  const srcT* src_col = src_im.top_left_ptr()+p*src_im.planestep();
90  destT* dest_col = dest_im.top_left_ptr()+p*dest_im.planestep();
91  // Filter each col
92  for (unsigned i=0;i<ni;++i,src_col+=s_istep,dest_col+=d_istep)
93  vil_exp_filter_1d(src_col,s_jstep, dest_col,d_jstep, nj, k);
94  }
95 }
96 
97 #endif // vil_exp_filter_1d_h_
Concrete view of image data of type T held in memory.
Definition: vil_fwd.h:13
void set_size(unsigned ni, unsigned nj) override
resize current planes to ni x nj.
std::ptrdiff_t jstep() const
Add this to your pixel pointer to get next j pixel.
unsigned ni() const
Width.
unsigned nj() const
Height.
std::ptrdiff_t planestep() const
Add this to your pixel pointer to get pixel on next plane.
void vil_exp_filter_1d(const srcT *src, std::ptrdiff_t sstep, destT *dest, std::ptrdiff_t dstep, int n, accumT k)
Apply exponential filter to 1D data.
A base class reference-counting view of some image data.
void vil_exp_filter_j(const vil_image_view< srcT > &src_im, vil_image_view< destT > &dest_im, accumT k)
Apply exponential filter along j to src_im to produce dest_im.
void vil_exp_filter_i(const vil_image_view< srcT > &src_im, vil_image_view< destT > &dest_im, accumT k)
Apply exponential filter along i to src_im to produce dest_im.
T * top_left_ptr()
Pointer to the first (top left in plane 0) pixel.
unsigned nplanes() const
Number of planes.
std::ptrdiff_t istep() const
Add this to your pixel pointer to get next i pixel.