vil_gauss_filter.h
Go to the documentation of this file.
1 // This is core/vil/algo/vil_gauss_filter.h
2 #ifndef vil_gauss_filter_h_
3 #define vil_gauss_filter_h_
4 //:
5 // \file
6 // \brief Smooths images.
7 // \author Ian Scott
8 
9 #include <vector>
10 #ifdef _MSC_VER
11 # include <vcl_msvc_warnings.h>
12 #endif
13 #include <vil/vil_image_view.h>
15 #include <vil/vil_transpose.h>
16 
18 {
19  double sigma_;
20  double filt2_, filt1_, filt0_;
24  public:
25  //: Set the
26  explicit vil_gauss_filter_5tap_params(double sigma_);
27  //: The width of the Gaussian
28  double sigma() const {return sigma_;}
29 
30  //: Filter tap value
31  // The value of the two outside elements of the 5-tap 1D FIR filter
32  double filt2() const { return filt2_;}
33  //: Filter tap value
34  // The value of elements 2 and 4 of the 5-tap 1D FIR filter
35  double filt1() const { return filt1_;}
36  //: Filter tap value
37  // The value of the central element of the 5-tap 1D FIR filter
38  double filt0() const { return filt0_;}
39 
40  //: Filter tap value
41  // The value of the first element of the 3 tap 1D FIR filter for use at the edge of the window
42  // Corresponds to the filt2_ elements in a symmetrical filter
43  double filt_edge2() const { return filt_edge2_;}
44  //: Filter tap value
45  // The value of the second element of the 3 tap 1D FIR filter for use at the edge of the window
46  // Corresponds to the filt1_ elements in a symmetrical filter
47  double filt_edge1() const { return filt_edge1_;}
48  //: Filter tap value
49  // The value of the third element of the 3 tap 1D FIR filter for use at the edge of the window
50  // Corresponds to the filt0_ element in a symmetrical filter
51  double filt_edge0() const { return filt_edge0_;}
52 
53  //: Filter tap value
54  // The value of the first element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
55  // Corresponds to the filt2_ elements in a symmetrical filter
56  double filt_pen_edge2() const { return filt_pen_edge2_;}
57  //: Filter tap value
58  // The value of the second element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
59  // Corresponds to the filt1_ elements in a symmetrical filter
60  double filt_pen_edge1() const { return filt_pen_edge1_;}
61  //: Filter tap value
62  // The value of the third element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
63  // Corresponds to the filt0_ elements in a symmetrical filter
64  double filt_pen_edge0() const { return filt_pen_edge0_;}
65  //: Filter tap value
66  // The value of the fourth element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
67  // Corresponds to the filt1_ elements in a symmetrical filter
68  double filt_pen_edge_n1() const { return filt_pen_edge_n1_;}
69 };
70 
71 
72 //: Smooth a single plane src_im to produce dest_im
73 // Applies 5 element FIR filter in x and y.
74 // Assumes dest_im has sufficient data allocated.
75 template <class srcT, class destT>
76 void vil_gauss_filter_5tap(const srcT* src_im, std::ptrdiff_t src_ystep,
77  unsigned ni, unsigned nj,
78  destT* dest_im, std::ptrdiff_t dest_ystep,
79  const vil_gauss_filter_5tap_params& params,
80  destT* work);
81 
82 //: Smooth a src_im to produce dest_im
83 // Applies 5 element FIR filter in x and y.
84 template <class srcT, class destT>
86  vil_image_view<destT>& dest_im,
87  const vil_gauss_filter_5tap_params &params,
88  vil_image_view<destT> &work);
89 
90 
91 //: Smooth a src_im to produce dest_im
92 // Applies 5 element FIR filter in x and y.
93 template <class srcT, class destT>
94 inline void vil_gauss_filter_5tap(const vil_image_view<srcT>& src_im,
95  vil_image_view<destT>& dest_im,
96  const vil_gauss_filter_5tap_params &params)
97 {
99  vil_gauss_filter_5tap(src_im, dest_im, params, work);
100 }
101 
102 
103 //: Generate an n-tap FIR filter from a Gaussian function.
104 // The filter uses the equation $k D^d \exp -\frac{x^2}{2\sigma^2} $,
105 // where D is the differential operator, and k is a normalising constant.
106 // \param diff The number of differential operators to apply to the filter.
107 // If you want just a normal gaussian, set diff to 0.
108 // \param sd The width of the gaussian.
109 //
110 // The taps will be calculated using the integral of the above equation over
111 // the pixel width. However, aliasing will reduce the meaningfulness of
112 // your filter when sd << (diff+1). In most applications you will
113 // want filter.size() ~= sd*7, which will avoid significant truncation,
114 // without wasting the outer taps on near-zero values.
115 void vil_gauss_filter_gen_ntap(double sd, unsigned diff,
116  std::vector<double> &filter_dest);
117 
118 //: Smooth a src_im to produce dest_im with gaussian of width sd
119 // Generates gaussian filter of width sd, using (2*half_width+1)
120 // values in the filter. Typically half_width>3sd.
121 // Convolves this with src_im to generate dest_im.
122 template <class srcT, class destT>
123 inline void vil_gauss_filter_1d(const vil_image_view<srcT>& src_im,
124  vil_image_view<destT>& dest_im,
125  double sd, unsigned half_width)
126 {
127  std::vector<double> filter(2*half_width+1);
128  vil_gauss_filter_gen_ntap(sd,0,filter);
129  vil_convolve_1d(src_im,dest_im,&filter[half_width],-int(half_width),half_width,
131 }
132 
133 //: Smooth a src_im to produce dest_im with gaussian of width sd
134 // Generates gaussian filter of width sd, using (2*half_width+1)
135 // values in the filter. Typically half_width>3sd.
136 // Convolves this with src_im to generate work_im, then applies filter
137 // vertically to generate dest_im.
138 template <class srcT, class destT>
139 inline void vil_gauss_filter_2d(const vil_image_view<srcT>& src_im,
140  vil_image_view<destT>& dest_im,
141  double sd, unsigned half_width,
143 {
144  // Generate filter
145  std::vector<double> filter(2*half_width+1);
146  vil_gauss_filter_gen_ntap(sd,0,filter);
147 
148  // Apply 1D convolution along i direction
149  vil_image_view<destT> work_im;
150  vil_convolve_1d(src_im,work_im,&filter[half_width],-int(half_width),half_width,
151  float(), boundary, boundary);
152 
153  // Apply 1D convolution along j direction by applying filter to transpose
154  dest_im.set_size(src_im.ni(),src_im.nj(),src_im.nplanes());
155  vil_image_view<destT> work_im_t = vil_transpose(work_im);
156  vil_image_view<destT> dest_im_t = vil_transpose(dest_im);
157 
158  vil_convolve_1d(work_im_t,dest_im_t,
159  &filter[half_width],-int(half_width),half_width,
160  float(), boundary, boundary);
161 }
162 
163 
164 //: Smooth a src_im to produce dest_im with gaussian of width sd
165 // Generates two gaussian filters of width sd_i,sd_j, using (2*half_width_i+1)
166 // values in the filter. Typically half_width>3sd.
167 // Convolves this with src_im to generate work_im, then applies filter
168 // vertically to generate dest_im.
169 template <class srcT, class destT>
170 inline void vil_gauss_filter_2d(const vil_image_view<srcT>& src_im,
171  vil_image_view<destT>& dest_im,
172  double sd_i, unsigned half_width_i,
173  double sd_j, unsigned half_width_j,
175 {
176  // Generate filter for i
177  std::vector<double> filter_i(2*half_width_i+1);
178  vil_gauss_filter_gen_ntap(sd_i,0,filter_i);
179 
180  // Apply 1D convolution along i direction
181  vil_image_view<destT> work_im;
182  vil_convolve_1d(src_im,work_im,&filter_i[half_width_i],-int(half_width_i),half_width_i,
183  float(), boundary, boundary);
184 
185  // Apply 1D convolution along j direction by applying filter to transpose
186  dest_im.set_size(src_im.ni(),src_im.nj(),src_im.nplanes());
187  vil_image_view<destT> work_im_t = vil_transpose(work_im);
188  vil_image_view<destT> dest_im_t = vil_transpose(dest_im);
189 
190  // Generate filter for j
191  std::vector<double> filter_j(2*half_width_j+1);
192  vil_gauss_filter_gen_ntap(sd_j,0,filter_j);
193 
194  vil_convolve_1d(work_im_t,dest_im_t,
195  &filter_j[half_width_j],-int(half_width_j),half_width_j,
196  float(), boundary, boundary);
197 }
198 
199 
200 #endif // vil_gauss_filter_h_
double filt1() const
Filter tap value.
vil_gauss_filter_5tap_params(double sigma_)
Set the.
Concrete view of image data of type T held in memory.
Definition: vil_fwd.h:13
double sigma() const
The width of the Gaussian.
void vil_gauss_filter_5tap(const srcT *src_im, std::ptrdiff_t src_ystep, unsigned ni, unsigned nj, destT *dest_im, std::ptrdiff_t dest_ystep, const vil_gauss_filter_5tap_params &params, destT *work)
Smooth a single plane src_im to produce dest_im.
double filt_edge0() const
Filter tap value.
double filt2() const
Filter tap value.
void set_size(unsigned ni, unsigned nj) override
resize current planes to ni x nj.
vil_convolve_boundary_option
Available options for boundary behavior.
unsigned ni() const
Width.
unsigned nj() const
Height.
void vil_gauss_filter_gen_ntap(double sd, unsigned diff, std::vector< double > &filter_dest)
Generate an n-tap FIR filter from a Gaussian function.
double filt_pen_edge0() const
Filter tap value.
double filt_pen_edge2() const
Filter tap value.
double filt_edge1() const
Filter tap value.
double filt0() const
Filter tap value.
A base class reference-counting view of some image data.
double filt_pen_edge1() const
Filter tap value.
double filt_pen_edge_n1() const
Filter tap value.
void vil_convolve_1d(const vil_image_view< srcT > &src_im, vil_image_view< destT > &dest_im, const kernelT *kernel, std::ptrdiff_t k_lo, std::ptrdiff_t k_hi, accumT ac, vil_convolve_boundary_option start_option, vil_convolve_boundary_option end_option)
Convolve kernel[i] (i in [k_lo,k_hi]) with srcT in i-direction.
Zero-extend the input signal beyond the boundary.
void vil_gauss_filter_1d(const vil_image_view< srcT > &src_im, vil_image_view< destT > &dest_im, double sd, unsigned half_width)
Smooth a src_im to produce dest_im with gaussian of width sd.
unsigned nplanes() const
Number of planes.
void vil_gauss_filter_2d(const vil_image_view< srcT > &src_im, vil_image_view< destT > &dest_im, double sd, unsigned half_width, vil_convolve_boundary_option boundary=vil_convolve_zero_extend)
Smooth a src_im to produce dest_im with gaussian of width sd.
double filt_edge2() const
Filter tap value.
1D Convolution with cunning boundary options
vil_image_view< T > vil_transpose(const vil_image_view< T > &v)
Create a view which appears as the transpose of this view.
Definition: vil_transpose.h:16