vil_gauss_reduce.h
Go to the documentation of this file.
1 // This is core/vil/algo/vil_gauss_reduce.h
2 #ifndef vil_gauss_reduce_h_
3 #define vil_gauss_reduce_h_
4 //:
5 // \file
6 // \brief Functions to smooth and sub-sample image in one direction
7 // \author Tim Cootes
8 // Some of these are not templated because
9 // - Each type tends to need a slightly different implementation
10 // - Let's not have too many templates.
11 //
12 // Amended by Martin Roberts 15th Sep 2005
13 // Au contraire, let's have a generic template implementation after all
14 // The previous specific types one plane functions become template specialisations
15 
16 #include <vil/vil_image_view.h>
17 #include <vxl_config.h> // for vxl_byte
18 
19 //: Smooth and subsample src_im to produce dest_im
20 // Applies 1-5-8-5-1 smoothing filter in x and y, then samples every other pixel.
21 // work_im provides workspace
22 // \relatesalso vil_image_view
23 template<class T>
24 void vil_gauss_reduce(const vil_image_view<T>& src,
25  vil_image_view<T>& dest,
26  vil_image_view<T>& work_im);
27 
28 //: Smooth and subsample src_im to produce dest_im (2/3 size)
29 // Applies filter in x and y, then samples every other pixel.
30 // work_im provides workspace
31 // \relatesalso vil_image_view
32 template<class T>
33 void vil_gauss_reduce_2_3(const vil_image_view<T>& src_im,
34  vil_image_view<T>& dest_im,
35  vil_image_view<T>& work_im);
36 
37 //: Smooth and subsample src_im to produce dest_im
38 // Applies 1-2-1 smoothing filter in x and y, then samples every other pixel.
39 // \relatesalso vil_image_view
40 template<class T>
42  vil_image_view<T>& dest);
43 
45 {
46  double scale_step_;
47  double filt2_, filt1_, filt0_;
51  public:
52  explicit vil_gauss_reduce_params(double scale_step);
53  //: the scale step between pyramid levels
54  double scale_step() const {return scale_step_;}
55 
56  //: Filter tap value
57  // The value of the two outside elements of the 5-tap 1D FIR filter
58  double filt2() const { return filt2_;}
59  //: Filter tap value
60  // The value of elements 2 and 4 of the 5-tap 1D FIR filter
61  double filt1() const { return filt1_;}
62  //: Filter tap value
63  // The value of the central element of the 5-tap 1D FIR filter
64  double filt0() const { return filt0_;}
65 
66  //: Filter tap value
67  // The value of the first element of the 3 tap 1D FIR filter for use at the edge of the window
68  // Corresponds to the filt2_ elements in a symmetrical filter
69  double filt_edge2() const { return filt_edge2_;}
70  //: Filter tap value
71  // The value of the second element of the 3 tap 1D FIR filter for use at the edge of the window
72  // Corresponds to the filt1_ elements in a symmetrical filter
73  double filt_edge1() const { return filt_edge1_;}
74  //: Filter tap value
75  // The value of the third element of the 3 tap 1D FIR filter for use at the edge of the window
76  // Corresponds to the filt0_ element in a symmetrical filter
77  double filt_edge0() const { return filt_edge0_;}
78 
79  //: Filter tap value
80  // The value of the first element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
81  // Corresponds to the filt2_ elements in a symmetrical filter
82  double filt_pen_edge2() const { return filt_pen_edge2_;}
83  //: Filter tap value
84  // The value of the second element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
85  // Corresponds to the filt1_ elements in a symmetrical filter
86  double filt_pen_edge1() const { return filt_pen_edge1_;}
87  //: Filter tap value
88  // The value of the third element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
89  // Corresponds to the filt0_ elements in a symmetrical filter
90  double filt_pen_edge0() const { return filt_pen_edge0_;}
91  //: Filter tap value
92  // The value of the fourth element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
93  // Corresponds to the filt1_ elements in a symmetrical filter
94  double filt_pen_edge_n1() const { return filt_pen_edge_n1_;}
95 };
96 
97 //: Smooth and subsample src_im by an arbitrary factor to produce dest_im
98 // \param worka provide workspace to avoid repetitive memory alloc and free
99 // \param workb provide workspace to avoid repetitive memory alloc and free
100 template <class T>
102  vil_image_view<T>& dest_im,
103  vil_image_view<T>& worka,
104  vil_image_view<T>& workb,
105  const vil_gauss_reduce_params& params);
106 
107 //: Smooth and subsample src_im by an arbitrary factor to produce dest_im
108 // \relatesalso vil_image_view
109 template <class T>
110 inline void vil_gauss_reduce_general(const vil_image_view<T>& src_im,
111  vil_image_view<T>& dest_im,
112  const vil_gauss_reduce_params& params)
113 {
114  vil_image_view<T> tempA, tempB;
115  vil_gauss_reduce_general(src_im, dest_im, tempA, tempB, params);
116 }
117 
118 //: Smooth and subsample single plane src_im in x to produce dest_im
119 // Applies 1-5-8-5-1 filter in x, then samples
120 // every other pixel. Fills [0,(nx+1)/2-1][0,ny-1] elements of dest
121 // Assumes dest_im has sufficient data allocated.
122 //
123 // This is essentially a utility function, used by mil_gauss_pyramid_builder
124 //
125 // By applying twice we can obtain a full gaussian smoothed and
126 // sub-sampled 2D image.
127 template <class T>
128 void vil_gauss_reduce_1plane(const T* src_im,
129  unsigned src_nx, unsigned src_ny,
130  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
131  T* dest_im,
132  std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
133 
134 //: Smooth and subsample single plane src_im in x to produce dest_im
135 // Applies 1-5-8-5-1 filter in x, then samples
136 // every other pixel. Fills [0,(nx+1)/2-1][0,ny-1] elements of dest
137 // Assumes dest_im has sufficient data allocated.
138 //
139 // This is essentially a utility function, used by mil_gauss_pyramid_builder
140 //
141 // By applying twice we can obtain a full gaussian smoothed and
142 // sub-sampled 2D image
143 template <>
144 void vil_gauss_reduce_1plane(const vxl_byte* src_im,
145  unsigned src_nx, unsigned src_ny,
146  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
147  vxl_byte* dest_im,
148  std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
149 
150 //: Smooth and subsample single plane src_im in x to produce dest_im
151 // Applies 1-5-8-5-1 filter in x, then samples
152 // every other pixel. Fills [0,(nx+1)/2-1][0,ny-1] elements of dest
153 // Assumes dest_im has sufficient data allocated.
154 //
155 // This is essentially a utility function, used by mil_gauss_pyramid_builder
156 //
157 // By applying twice we can obtain a full gaussian smoothed and
158 // sub-sampled 2D image.
159 template <>
160 void vil_gauss_reduce_1plane(const float* src_im,
161  unsigned src_nx, unsigned src_ny,
162  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
163  float* dest_im,
164  std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
165 
166 //: Smooth and subsample single plane src_im in x to produce dest_im
167 // Applies 1-5-8-5-1 filter in x, then samples
168 // every other pixel. Fills [0,(nx+1)/2-1][0,ny-1] elements of dest
169 // Assumes dest_im has sufficient data allocated.
170 //
171 // This is essentially a utility function, used by mil_gauss_pyramid_builder
172 //
173 // By applying twice we can obtain a full gaussian smoothed and
174 // sub-sampled 2D image.
175 template <>
176 void vil_gauss_reduce_1plane(const int* src_im,
177  unsigned src_nx, unsigned src_ny,
178  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
179  int* dest_im,
180  std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
181 
182 template <>
183 void vil_gauss_reduce_1plane(const double* src_im,
184  unsigned src_nx, unsigned src_ny,
185  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
186  double* dest_im,
187  std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
188 
189 //: Smooth and subsample single plane src_im in x to produce dest_im
190 // Applies 1-5-8-5-1 filter in x, then samples
191 // every other pixel. Fills [0,(nx+1)/2-1][0,ny-1] elements of dest
192 // Assumes dest_im has sufficient data allocated.
193 //
194 // This is essentially a utility function, used by mil_gauss_pyramid_builder
195 //
196 // By applying twice we can obtain a full gaussian smoothed and
197 // sub-sampled 2D image.
198 template <>
199 void vil_gauss_reduce_1plane(const vxl_int_16* src_im,
200  unsigned src_nx, unsigned src_ny,
201  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
202  vxl_int_16* dest_im,
203  std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
204 
205 //: Smooth and subsample single plane src_im in x to produce dest_im using 121 filter in x and y
206 // Smooths with a 3x3 filter and subsamples
207 template <class T>
208 void vil_gauss_reduce_121_1plane(const T* src_im,
209  unsigned src_nx, unsigned src_ny,
210  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
211  T* dest_im,
212  std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
213 
214 //: Smooth and subsample single plane src_im in x to produce dest_im using 121 filter in x and y
215 // Smooths with a 3x3 filter and subsamples
216 template <>
217 void vil_gauss_reduce_121_1plane(const vxl_byte* src_im,
218  unsigned src_nx, unsigned src_ny,
219  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
220  vxl_byte* dest_im,
221  std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
222 
223 //: Smooth and subsample single plane src_im in x to produce dest_im using 121 filter in x and y
224 // Smooths with a 3x3 filter and subsamples
225 template <>
226 void vil_gauss_reduce_121_1plane(const float* src_im,
227  unsigned src_nx, unsigned src_ny,
228  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
229  float* dest_im,
230  std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
231 
232 //: Smooth and subsample single plane src_im in x to produce dest_im using 121 filter in x and y
233 // Smooths with a 3x3 filter and subsamples
234 template <>
235 void vil_gauss_reduce_121_1plane(const int* src_im,
236  unsigned src_nx, unsigned src_ny,
237  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
238  int* dest_im,
239  std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
240 template <>
241 void vil_gauss_reduce_121_1plane(const double* src_im,
242  unsigned src_nx, unsigned src_ny,
243  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
244  double* dest_im,
245  std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
246 
247 //: Smooth and subsample single plane src_im in x to produce dest_im using 121 filter in x and y
248 // Smooths with a 3x3 filter and subsamples
249 template <>
250 void vil_gauss_reduce_121_1plane(const vxl_int_16* src_im,
251  unsigned src_nx, unsigned src_ny,
252  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
253  vxl_int_16* dest_im,
254  std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
255 //: Smooth and subsample single plane src_im in x, result is 2/3rd size
256 // Applies alternate 1-3-1, 1-1 filter in x, then samples
257 // every other pixel. Fills [0,(2*ni+1)/3-1][0,nj-1] elements of dest
258 //
259 // Note, 131 filter only an approximation
260 template <class T>
261 void vil_gauss_reduce_2_3_1plane(const T* src_im,
262  unsigned src_ni, unsigned src_nj,
263  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
264  T* dest_im, std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
265 
266 //: Smooth and subsample single plane src_im in x, result is 2/3rd size
267 // Applies alternate 1-3-1, 1-1 filter in x, then samples
268 // every other pixel. Fills [0,(2*ni+1)/3-1][0,nj-1] elements of dest
269 //
270 // Note, 131 filter only an approximation
271 template <>
272 void vil_gauss_reduce_2_3_1plane(const vxl_byte* src_im,
273  unsigned src_ni, unsigned src_nj,
274  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
275  vxl_byte* dest_im, std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
276 
277 //: Smooth and subsample single plane src_im in x, result is 2/3rd size
278 // Applies alternate 1-3-1, 1-1 filter in x, then samples
279 // every other pixel. Fills [0,(2*ni+1)/3-1][0,nj-1] elements of dest
280 //
281 // Note, 131 filter only an approximation
282 template <>
283 void vil_gauss_reduce_2_3_1plane(const int* src_im,
284  unsigned src_ni, unsigned src_nj,
285  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
286  int* dest_im, std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
287 
288 //: Smooth and subsample single plane src_im in x, result is 2/3rd size
289 // Applies alternate 1-3-1, 1-1 filter in x, then samples
290 // every other pixel. Fills [0,(2*ni+1)/3-1][0,nj-1] elements of dest
291 //
292 // Note, 131 filter only an approximation
293 template <>
294 void vil_gauss_reduce_2_3_1plane(const vxl_int_16* src_im,
295  unsigned src_ni, unsigned src_nj,
296  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
297  vxl_int_16* dest_im, std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
298 
299 //: Smooth and subsample single plane src_im in x, result is 2/3rd size
300 // Applies alternate 1-3-1, 1-1 filter in x, then samples
301 // every other pixel. Fills [0,(2*ni+1)/3-1][0,nj-1] elements of dest
302 //
303 // Note, 131 filter only an approximation
304 template <>
305 void vil_gauss_reduce_2_3_1plane(const float* src_im,
306  unsigned src_ni, unsigned src_nj,
307  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
308  float* dest_im, std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
309 
310 //: Smooth and subsample single plane src_im in x, result is 2/3rd size
311 // Applies alternate 1-3-1, 1-1 filter in x, then samples
312 // every other pixel. Fills [0,(2*ni+1)/3-1][0,nj-1] elements of dest
313 //
314 // Note, 131 filter only an approximation
315 template <>
316 void vil_gauss_reduce_2_3_1plane(const double* src_im,
317  unsigned src_ni, unsigned src_nj,
318  std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step,
319  double* dest_im, std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step);
320 
321 #endif // vil_gauss_reduce_h_
double filt0() const
Filter tap value.
void vil_gauss_reduce_general(const vil_image_view< T > &src_im, vil_image_view< T > &dest_im, const vil_gauss_reduce_params &params)
Smooth and subsample src_im by an arbitrary factor to produce dest_im.
Concrete view of image data of type T held in memory.
Definition: vil_fwd.h:13
double scale_step() const
the scale step between pyramid levels.
void vil_gauss_reduce_1plane(const T *src_im, unsigned src_nx, unsigned src_ny, std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step, T *dest_im, std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step)
Smooth and subsample single plane src_im in x to produce dest_im.
void vil_gauss_reduce_121(const vil_image_view< T > &src, vil_image_view< T > &dest)
Smooth and subsample src_im to produce dest_im.
double filt_pen_edge1() const
Filter tap value.
void vil_gauss_reduce_121_1plane(const T *src_im, unsigned src_nx, unsigned src_ny, std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step, T *dest_im, std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step)
Smooth and subsample single plane src_im in x to produce dest_im using 121 filter in x and y.
double filt_pen_edge0() const
Filter tap value.
void vil_gauss_reduce_2_3(const vil_image_view< T > &src_im, vil_image_view< T > &dest_im, vil_image_view< T > &work_im)
Smooth and subsample src_im to produce dest_im (2/3 size).
double filt_pen_edge_n1() const
Filter tap value.
void vil_gauss_reduce_2_3_1plane(const T *src_im, unsigned src_ni, unsigned src_nj, std::ptrdiff_t s_x_step, std::ptrdiff_t s_y_step, T *dest_im, std::ptrdiff_t d_x_step, std::ptrdiff_t d_y_step)
Smooth and subsample single plane src_im in x, result is 2/3rd size.
double filt1() const
Filter tap value.
A base class reference-counting view of some image data.
void vil_gauss_reduce(const vil_image_view< T > &src, vil_image_view< T > &dest, vil_image_view< T > &work_im)
Smooth and subsample src_im to produce dest_im.
double filt_edge2() const
Filter tap value.
double filt2() const
Filter tap value.
vil_gauss_reduce_params(double scale_step)
double filt_pen_edge2() const
Filter tap value.
double filt_edge1() const
Filter tap value.
double filt_edge0() const
Filter tap value.