Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

vil_gauss_filter.h

Go to the documentation of this file.
00001 // This is core/vil/algo/vil_gauss_filter.h
00002 #ifndef vil_gauss_filter_h_
00003 #define vil_gauss_filter_h_
00004 //:
00005 // \file
00006 // \brief Smoothes images.
00007 // \author Ian Scott
00008 
00009 //=======================================================================
00010 // inclusions
00011 
00012 #include <vcl_vector.h>
00013 #include <vil/vil_image_view.h>
00014 #include <vil/algo/vil_convolve_1d.h>
00015 #include <vil/vil_transpose.h>
00016 
00017 class vil_gauss_filter_5tap_params
00018 {
00019   double sigma_;
00020   double filt2_, filt1_, filt0_;
00021   double filt_edge2_, filt_edge1_, filt_edge0_;
00022   double filt_pen_edge2_, filt_pen_edge1_,
00023          filt_pen_edge0_, filt_pen_edge_n1_;
00024  public:
00025   //: Set the
00026   explicit vil_gauss_filter_5tap_params(double sigma_);
00027   //: The width of the Gaussian
00028   double sigma() const {return sigma_;}
00029 
00030   //: Filter tap value
00031   // The value of the two outside elements of the 5-tap 1D FIR filter
00032   double filt2() const { return filt2_;}
00033   //: Filter tap value
00034   // The value of elements 2 and 4 of the 5-tap 1D FIR filter
00035   double filt1() const { return filt1_;}
00036   //: Filter tap value
00037   // The value of the central element of the 5-tap 1D FIR filter
00038   double filt0() const { return filt0_;}
00039 
00040   //: Filter tap value
00041   // The value of the first element of the 3 tap 1D FIR filter for use at the edge of the window
00042   // Corresponds to the filt2_ elements in a symmetrical filter
00043   double filt_edge2() const { return filt_edge2_;}
00044   //: Filter tap value
00045   // The value of the second element of the 3 tap 1D FIR filter for use at the edge of the window
00046   // Corresponds to the filt1_ elements in a symmetrical filter
00047   double filt_edge1() const { return filt_edge1_;}
00048   //: Filter tap value
00049   // The value of the third element of the 3 tap 1D FIR filter for use at the edge of the window
00050   // Corresponds to the filt0_ element in a symmetrical filter
00051   double filt_edge0() const { return filt_edge0_;}
00052 
00053   //: Filter tap value
00054   // The value of the first element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
00055   // Corresponds to the filt2_ elements in a symmetrical filter
00056   double filt_pen_edge2() const { return filt_pen_edge2_;}
00057   //: Filter tap value
00058   // The value of the second element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
00059   // Corresponds to the filt1_ elements in a symmetrical filter
00060   double filt_pen_edge1() const { return filt_pen_edge1_;}
00061   //: Filter tap value
00062   // The value of the third element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
00063   // Corresponds to the filt0_ elements in a symmetrical filter
00064   double filt_pen_edge0() const { return filt_pen_edge0_;}
00065   //: Filter tap value
00066   // The value of the fourth element of the 4 tap 1D FIR filter for use 1 pixel away the edge of the window
00067   // Corresponds to the filt1_ elements in a symmetrical filter
00068   double filt_pen_edge_n1() const { return filt_pen_edge_n1_;}
00069 };
00070 
00071 
00072 //: Smooth a single plane src_im to produce dest_im
00073 //  Applies 5 element FIR filter in x and y.
00074 //  Assumes dest_im has sufficient data allocated.
00075 template <class srcT, class destT>
00076 void vil_gauss_filter_5tap(const srcT* src_im, vcl_ptrdiff_t src_ystep,
00077                            unsigned ni, unsigned nj,
00078                            destT* dest_im, vcl_ptrdiff_t dest_ystep,
00079                            const vil_gauss_filter_5tap_params& params,
00080                            destT* work);
00081 
00082 //: Smooth a src_im to produce dest_im
00083 //  Applies 5 element FIR filter in x and y.
00084 template <class srcT, class destT>
00085 void vil_gauss_filter_5tap(const vil_image_view<srcT>& src_im,
00086                            vil_image_view<destT>& dest_im,
00087                            const vil_gauss_filter_5tap_params &params,
00088                            vil_image_view<destT> &work);
00089 
00090 
00091 //: Smooth a src_im to produce dest_im
00092 //  Applies 5 element FIR filter in x and y.
00093 template <class srcT, class destT>
00094 inline void vil_gauss_filter_5tap(const vil_image_view<srcT>& src_im,
00095                                   vil_image_view<destT>& dest_im,
00096                                   const vil_gauss_filter_5tap_params &params)
00097 {
00098   vil_image_view<destT> work;
00099   vil_gauss_filter_5tap(src_im, dest_im, params, work);
00100 }
00101 
00102 
00103 //: Generate an n-tap FIR filter from a Gaussian function.
00104 // The filter uses the equation $k D^d \exp -\frac{x^2}{2\sigma^2} $,
00105 // where D is the differential operator, and k is a normalising constant.
00106 // \param diff The number of differential operators to apply to the filter.
00107 // If you want just a normal gaussian, set diff to 0.
00108 // \param sd The width of the gaussian.
00109 //
00110 // The taps will be calculated using the itegeral of the above equation over
00111 // the pixel width. However, aliasing will reduce the meaningfulness of
00112 // your filter when sd << (diff+1). In most applications you will
00113 // want filter.size() ~= sd*7, which will avoid significant truncation,
00114 // without wasting the outer taps on near-zero values.
00115 void vil_gauss_filter_gen_ntap(double sd, unsigned diff,
00116                                vcl_vector<double> &filter_dest);
00117 
00118 //: Smooth a src_im to produce dest_im with gaussian of width sd
00119 //  Generates gaussian filter of width sd, using (2*half_width+1)
00120 //  values in the filter.  Typically half_width>3sd.
00121 //  Convolves this with src_im to generate dest_im.
00122 template <class srcT, class destT>
00123 inline void vil_gauss_filter_1d(const vil_image_view<srcT>& src_im,
00124                                 vil_image_view<destT>& dest_im,
00125                                 double sd, unsigned half_width)
00126 {
00127   vcl_vector<double> filter(2*half_width+1);
00128   vil_gauss_filter_gen_ntap(sd,0,filter);
00129   vil_convolve_1d(src_im,dest_im,&filter[half_width],-int(half_width),half_width,
00130                   float(),vil_convolve_zero_extend,vil_convolve_zero_extend);
00131 }
00132 
00133 //: Smooth a src_im to produce dest_im with gaussian of width sd
00134 //  Generates gaussian filter of width sd, using (2*half_width+1)
00135 //  values in the filter.  Typically half_width>3sd.
00136 //  Convolves this with src_im to generate work_im, then applies filter
00137 //  vertically to generate dest_im.
00138 template <class srcT, class destT>
00139 inline void vil_gauss_filter_2d(const vil_image_view<srcT>& src_im,
00140                                 vil_image_view<destT>& dest_im,
00141                                 double sd, unsigned half_width,
00142                                 vil_convolve_boundary_option boundary = vil_convolve_zero_extend)
00143 {
00144   // Generate filter
00145   vcl_vector<double> filter(2*half_width+1);
00146   vil_gauss_filter_gen_ntap(sd,0,filter);
00147 
00148   // Apply 1D convolution along i direction
00149   vil_image_view<destT> work_im;
00150   vil_convolve_1d(src_im,work_im,&filter[half_width],-int(half_width),half_width,
00151                   float(), boundary, boundary);
00152 
00153   // Apply 1D convolution along j direction by applying filter to transpose
00154   dest_im.set_size(src_im.ni(),src_im.nj(),src_im.nplanes());
00155   vil_image_view<destT> work_im_t = vil_transpose(work_im);
00156   vil_image_view<destT> dest_im_t = vil_transpose(dest_im);
00157 
00158   vil_convolve_1d(work_im_t,dest_im_t,
00159                   &filter[half_width],-int(half_width),half_width,
00160                   float(), boundary, boundary);
00161 }
00162 
00163 #endif // vil_gauss_filter_h_

Generated on Thu Jan 10 14:39:59 2008 for core/vil by  doxygen 1.4.4