core/vil/algo/vil_gauss_reduce.h
Go to the documentation of this file.
00001 // This is core/vil/algo/vil_gauss_reduce.h
00002 #ifndef vil_gauss_reduce_h_
00003 #define vil_gauss_reduce_h_
00004 //:
00005 // \file
00006 // \brief Functions to smooth and sub-sample image in one direction
00007 // \author Tim Cootes
00008 // Some of these are not templated because
00009 // - Each type tends to need a slightly different implementation
00010 // - Let's not have too many templates.
00011 //
00012 // Amended by Martin Roberts 15th Sep 2005
00013 // Au contraire, let's have a generic template implementation after all
00014 // The previous specific types one plane functions become template specialisations
00015 
00016 #include <vil/vil_image_view.h>
00017 #include <vxl_config.h> // for vxl_byte
00018 
00019 //: Smooth and subsample src_im to produce dest_im
00020 //  Applies 1-5-8-5-1 smoothing filter in x and y, then samples every other pixel.
00021 //  work_im provides workspace
00022 // \relatesalso vil_image_view
00023 template<class T>
00024 void vil_gauss_reduce(const vil_image_view<T>& src,
00025                       vil_image_view<T>& dest,
00026                       vil_image_view<T>& work_im);
00027 
00028 //: Smooth and subsample src_im to produce dest_im (2/3 size)
00029 //  Applies filter in x and y, then samples every other pixel.
00030 //  work_im provides workspace
00031 // \relatesalso vil_image_view
00032 template<class T>
00033 void vil_gauss_reduce_2_3(const vil_image_view<T>& src_im,
00034                           vil_image_view<T>& dest_im,
00035                           vil_image_view<T>& work_im);
00036 
00037 //: Smooth and subsample src_im to produce dest_im
00038 //  Applies 1-2-1 smoothing filter in x and y, then samples every other pixel.
00039 // \relatesalso vil_image_view
00040 template<class T>
00041 void vil_gauss_reduce_121(const vil_image_view<T>& src,
00042                           vil_image_view<T>& dest);
00043 
00044 class vil_gauss_reduce_params
00045 {
00046   double scale_step_;
00047   double filt2_, filt1_, filt0_;
00048   double filt_edge2_, filt_edge1_, filt_edge0_;
00049   double filt_pen_edge2_, filt_pen_edge1_,
00050          filt_pen_edge0_, filt_pen_edge_n1_;
00051  public:
00052   explicit vil_gauss_reduce_params(double scale_step);
00053   //: the scale step between pyramid levels
00054   double scale_step() const {return scale_step_;}
00055 
00056   //: Filter tap value
00057   // The value of the two outside elements of the 5-tap 1D FIR filter
00058   double filt2() const { return filt2_;}
00059   //: Filter tap value
00060   // The value of elements 2 and 4 of the 5-tap 1D FIR filter
00061   double filt1() const { return filt1_;}
00062   //: Filter tap value
00063   // The value of the central element of the 5-tap 1D FIR filter
00064   double filt0() const { return filt0_;}
00065 
00066   //: Filter tap value
00067   // The value of the first element of the 3 tap 1D FIR filter for use at the edge of the window
00068   // Corresponds to the filt2_ elements in a symmetrical filter
00069   double filt_edge2() const { return filt_edge2_;}
00070   //: Filter tap value
00071   // The value of the second element of the 3 tap 1D FIR filter for use at the edge of the window
00072   // Corresponds to the filt1_ elements in a symmetrical filter
00073   double filt_edge1() const { return filt_edge1_;}
00074   //: Filter tap value
00075   // The value of the third element of the 3 tap 1D FIR filter for use at the edge of the window
00076   // Corresponds to the filt0_ element in a symmetrical filter
00077   double filt_edge0() const { return filt_edge0_;}
00078 
00079   //: Filter tap value
00080   // The value of the first element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
00081   // Corresponds to the filt2_ elements in a symmetrical filter
00082   double filt_pen_edge2() const { return filt_pen_edge2_;}
00083   //: Filter tap value
00084   // The value of the second element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
00085   // Corresponds to the filt1_ elements in a symmetrical filter
00086   double filt_pen_edge1() const { return filt_pen_edge1_;}
00087   //: Filter tap value
00088   // The value of the third element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
00089   // Corresponds to the filt0_ elements in a symmetrical filter
00090   double filt_pen_edge0() const { return filt_pen_edge0_;}
00091   //: Filter tap value
00092   // The value of the fourth element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
00093   // Corresponds to the filt1_ elements in a symmetrical filter
00094   double filt_pen_edge_n1() const { return filt_pen_edge_n1_;}
00095 };
00096 
00097 //: Smooth and subsample src_im by an arbitrary factor to produce dest_im
00098 // \param worka provide workspace to avoid repetitive memory alloc and free
00099 // \param workb provide workspace to avoid repetitive memory alloc and free
00100 template <class T>
00101 void vil_gauss_reduce_general(const vil_image_view<T>& src_im,
00102                               vil_image_view<T>& dest_im,
00103                               vil_image_view<T>& worka,
00104                               vil_image_view<T>& workb,
00105                               const vil_gauss_reduce_params& params);
00106 
00107 //: Smooth and subsample src_im by an arbitrary factor to produce dest_im
00108 // \relatesalso vil_image_view
00109 template <class T>
00110 inline void vil_gauss_reduce_general(const vil_image_view<T>& src_im,
00111                                      vil_image_view<T>& dest_im,
00112                                      const vil_gauss_reduce_params& params)
00113 {
00114   vil_image_view<T> tempA, tempB;
00115   vil_gauss_reduce_general(src_im, dest_im, tempA, tempB, params);
00116 }
00117 
00118 //: Smooth and subsample single plane src_im in x to produce dest_im
00119 //  Applies 1-5-8-5-1 filter in x, then samples
00120 //  every other pixel.  Fills [0,(nx+1)/2-1][0,ny-1] elements of dest
00121 //  Assumes dest_im has sufficient data allocated.
00122 //
00123 //  This is essentially a utility function, used by mil_gauss_pyramid_builder
00124 //
00125 //  By applying twice we can obtain a full gaussian smoothed and
00126 //  sub-sampled 2D image.
00127 template <class T>
00128 void vil_gauss_reduce_1plane(const T* src_im,
00129                              unsigned src_nx, unsigned src_ny,
00130                              vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00131                              T* dest_im,
00132                              vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00133 
00134 //: Smooth and subsample single plane src_im in x to produce dest_im
00135 //  Applies 1-5-8-5-1 filter in x, then samples
00136 //  every other pixel.  Fills [0,(nx+1)/2-1][0,ny-1] elements of dest
00137 //  Assumes dest_im has sufficient data allocated.
00138 //
00139 //  This is essentially a utility function, used by mil_gauss_pyramid_builder
00140 //
00141 //  By applying twice we can obtain a full gaussian smoothed and
00142 //  sub-sampled 2D image
00143 VCL_DEFINE_SPECIALIZATION
00144 void vil_gauss_reduce_1plane(const vxl_byte* src_im,
00145                              unsigned src_nx, unsigned src_ny,
00146                              vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00147                              vxl_byte* dest_im,
00148                              vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00149 
00150 //: Smooth and subsample single plane src_im in x to produce dest_im
00151 //  Applies 1-5-8-5-1 filter in x, then samples
00152 //  every other pixel.  Fills [0,(nx+1)/2-1][0,ny-1] elements of dest
00153 //  Assumes dest_im has sufficient data allocated.
00154 //
00155 //  This is essentially a utility function, used by mil_gauss_pyramid_builder
00156 //
00157 //  By applying twice we can obtain a full gaussian smoothed and
00158 //  sub-sampled 2D image.
00159 VCL_DEFINE_SPECIALIZATION
00160 void vil_gauss_reduce_1plane(const float* src_im,
00161                              unsigned src_nx, unsigned src_ny,
00162                              vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00163                              float* dest_im,
00164                              vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00165 
00166 //: Smooth and subsample single plane src_im in x to produce dest_im
00167 //  Applies 1-5-8-5-1 filter in x, then samples
00168 //  every other pixel.  Fills [0,(nx+1)/2-1][0,ny-1] elements of dest
00169 //  Assumes dest_im has sufficient data allocated.
00170 //
00171 //  This is essentially a utility function, used by mil_gauss_pyramid_builder
00172 //
00173 //  By applying twice we can obtain a full gaussian smoothed and
00174 //  sub-sampled 2D image.
00175 VCL_DEFINE_SPECIALIZATION
00176 void vil_gauss_reduce_1plane(const int* src_im,
00177                              unsigned src_nx, unsigned src_ny,
00178                              vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00179                              int* dest_im,
00180                              vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00181 
00182 VCL_DEFINE_SPECIALIZATION
00183 void vil_gauss_reduce_1plane(const double* src_im,
00184                              unsigned src_nx, unsigned src_ny,
00185                              vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00186                              double* dest_im,
00187                              vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00188 
00189 //: Smooth and subsample single plane src_im in x to produce dest_im
00190 //  Applies 1-5-8-5-1 filter in x, then samples
00191 //  every other pixel.  Fills [0,(nx+1)/2-1][0,ny-1] elements of dest
00192 //  Assumes dest_im has sufficient data allocated.
00193 //
00194 //  This is essentially a utility function, used by mil_gauss_pyramid_builder
00195 //
00196 //  By applying twice we can obtain a full gaussian smoothed and
00197 //  sub-sampled 2D image.
00198 VCL_DEFINE_SPECIALIZATION
00199 void vil_gauss_reduce_1plane(const vxl_int_16* src_im,
00200                              unsigned src_nx, unsigned src_ny,
00201                              vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00202                              vxl_int_16* dest_im,
00203                              vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00204 
00205 //: Smooth and subsample single plane src_im in x to produce dest_im using 121 filter in x and y
00206 //  Smooths with a 3x3 filter and subsamples
00207 template <class T>
00208 void vil_gauss_reduce_121_1plane(const T* src_im,
00209                                  unsigned src_nx, unsigned src_ny,
00210                                  vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00211                                  T* dest_im,
00212                                  vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00213 
00214 //: Smooth and subsample single plane src_im in x to produce dest_im using 121 filter in x and y
00215 //  Smooths with a 3x3 filter and subsamples
00216 VCL_DEFINE_SPECIALIZATION
00217 void vil_gauss_reduce_121_1plane(const vxl_byte* src_im,
00218                                  unsigned src_nx, unsigned src_ny,
00219                                  vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00220                                  vxl_byte* dest_im,
00221                                  vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00222 
00223 //: Smooth and subsample single plane src_im in x to produce dest_im using 121 filter in x and y
00224 //  Smooths with a 3x3 filter and subsamples
00225 VCL_DEFINE_SPECIALIZATION
00226 void vil_gauss_reduce_121_1plane(const float* src_im,
00227                                  unsigned src_nx, unsigned src_ny,
00228                                  vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00229                                  float* dest_im,
00230                                  vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00231 
00232 //: Smooth and subsample single plane src_im in x to produce dest_im using 121 filter in x and y
00233 //  Smooths with a 3x3 filter and subsamples
00234 VCL_DEFINE_SPECIALIZATION
00235 void vil_gauss_reduce_121_1plane(const int* src_im,
00236                                  unsigned src_nx, unsigned src_ny,
00237                                  vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00238                                  int* dest_im,
00239                                  vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00240 VCL_DEFINE_SPECIALIZATION
00241 void vil_gauss_reduce_121_1plane(const double* src_im,
00242                                  unsigned src_nx, unsigned src_ny,
00243                                  vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00244                                  double* dest_im,
00245                                  vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00246 
00247 //: Smooth and subsample single plane src_im in x to produce dest_im using 121 filter in x and y
00248 //  Smooths with a 3x3 filter and subsamples
00249 VCL_DEFINE_SPECIALIZATION
00250 void vil_gauss_reduce_121_1plane(const vxl_int_16* src_im,
00251                                  unsigned src_nx, unsigned src_ny,
00252                                  vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00253                                  vxl_int_16* dest_im,
00254                                  vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00255 //: Smooth and subsample single plane src_im in x, result is 2/3rd size
00256 //  Applies alternate 1-3-1, 1-1 filter in x, then samples
00257 //  every other pixel.  Fills [0,(2*ni+1)/3-1][0,nj-1] elements of dest
00258 //
00259 //  Note, 131 filter only an approximation
00260 template <class T>
00261 void vil_gauss_reduce_2_3_1plane(const T* src_im,
00262                                  unsigned src_ni, unsigned src_nj,
00263                                  vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00264                                  T* dest_im, vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00265 
00266 //: Smooth and subsample single plane src_im in x, result is 2/3rd size
00267 //  Applies alternate 1-3-1, 1-1 filter in x, then samples
00268 //  every other pixel.  Fills [0,(2*ni+1)/3-1][0,nj-1] elements of dest
00269 //
00270 //  Note, 131 filter only an approximation
00271 VCL_DEFINE_SPECIALIZATION
00272 void vil_gauss_reduce_2_3_1plane(const vxl_byte* src_im,
00273                                  unsigned src_ni, unsigned src_nj,
00274                                  vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00275                                  vxl_byte* dest_im, vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00276 
00277 //: Smooth and subsample single plane src_im in x, result is 2/3rd size
00278 //  Applies alternate 1-3-1, 1-1 filter in x, then samples
00279 //  every other pixel.  Fills [0,(2*ni+1)/3-1][0,nj-1] elements of dest
00280 //
00281 //  Note, 131 filter only an approximation
00282 VCL_DEFINE_SPECIALIZATION
00283 void vil_gauss_reduce_2_3_1plane(const int* src_im,
00284                                  unsigned src_ni, unsigned src_nj,
00285                                  vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00286                                  int* dest_im, vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00287 
00288 //: Smooth and subsample single plane src_im in x, result is 2/3rd size
00289 //  Applies alternate 1-3-1, 1-1 filter in x, then samples
00290 //  every other pixel.  Fills [0,(2*ni+1)/3-1][0,nj-1] elements of dest
00291 //
00292 //  Note, 131 filter only an approximation
00293 VCL_DEFINE_SPECIALIZATION
00294 void vil_gauss_reduce_2_3_1plane(const vxl_int_16* src_im,
00295                                  unsigned src_ni, unsigned src_nj,
00296                                  vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00297                                  vxl_int_16* dest_im, vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00298 
00299 //: Smooth and subsample single plane src_im in x, result is 2/3rd size
00300 //  Applies alternate 1-3-1, 1-1 filter in x, then samples
00301 //  every other pixel.  Fills [0,(2*ni+1)/3-1][0,nj-1] elements of dest
00302 //
00303 //  Note, 131 filter only an approximation
00304 VCL_DEFINE_SPECIALIZATION
00305 void vil_gauss_reduce_2_3_1plane(const float* src_im,
00306                                  unsigned src_ni, unsigned src_nj,
00307                                  vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00308                                  float* dest_im, vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00309 
00310 //: Smooth and subsample single plane src_im in x, result is 2/3rd size
00311 //  Applies alternate 1-3-1, 1-1 filter in x, then samples
00312 //  every other pixel.  Fills [0,(2*ni+1)/3-1][0,nj-1] elements of dest
00313 //
00314 //  Note, 131 filter only an approximation
00315 VCL_DEFINE_SPECIALIZATION
00316 void vil_gauss_reduce_2_3_1plane(const double* src_im,
00317                                  unsigned src_ni, unsigned src_nj,
00318                                  vcl_ptrdiff_t s_x_step, vcl_ptrdiff_t s_y_step,
00319                                  double* dest_im, vcl_ptrdiff_t d_x_step, vcl_ptrdiff_t d_y_step);
00320 
00321 #endif // vil_gauss_reduce_h_