contrib/brl/bseg/brip/brip_vil_ops.h
Go to the documentation of this file.
00001 // This is brl/bseg/brip/brip_vil_ops.h
00002 #ifndef brip_vil_ops_h_
00003 #define brip_vil_ops_h_
00004 //:
00005 // \file
00006 // \brief This file contains templated, vil1 versions code provided by brip_float_ops
00007 // \author Matt Leotta, (mleotta@lems.brown.edu)
00008 // \date Nov 12 2003
00009 //
00010 // This file contains several useful image operations originally defined in
00011 // brip_float_ops for vil1 floating point images.  Some of the original operations
00012 // are covered in the new vil library, these are use when possible and not duplicated here.
00013 //
00014 // \verbatim
00015 //  Modifications
00016 // \endverbatim
00017 
00018 #include <vcl_cmath.h>
00019 #include <vcl_cassert.h>
00020 #include <vil/vil_image_view.h>
00021 #include <vil/vil_math.h>
00022 #include <vil/vil_fill.h>
00023 #include <vil/vil_transpose.h>
00024 #include <vil/algo/vil_sobel_3x3.h>
00025 #include <vil/algo/vil_convolve_1d.h>
00026 
00027 //: computes the conditioning of the 2n+1 x 2n+1 gradient neighborhood
00028 template<class T>
00029 inline void
00030 brip_sqrt_grad_singular_values(const vil_image_view<T>& input, vil_image_view<T>& output, unsigned n)
00031 {
00032   unsigned N = (2*n+1)*(2*n+1);
00033   vil_image_view<T> grad_i, grad_j;
00034   vil_sobel_3x3(input, grad_i, grad_j);
00035 
00036   unsigned ni = input.ni();
00037   unsigned nj = input.nj();
00038   unsigned np = input.nplanes();
00039   output.set_size(ni, nj, np);
00040   vil_fill(output,(T)1);
00041 
00042   for (unsigned p=0; p<np; ++p){
00043     for (unsigned j=n; j+n<nj; ++j){
00044       for (unsigned i=n; i+n<ni; ++i){
00045         T IxIx=(T)0, IxIy=(T)0, IyIy=(T)0;
00046         for (int x = -(int)n; x<=(int)n; ++x){
00047           for (int y = -(int)n; y<=(int)n; ++y){
00048             T gx = grad_i(i+x, j+y,p), gy = grad_j(i+x, j+y,p);
00049             IxIx += gx*gx;
00050             IxIy += gx*gy;
00051             IyIy += gy*gy;
00052           }
00053         }
00054         // calculate the absolute value of the determinate (should work of all types)
00055         T IxIxIyIy = IxIx*IyIy;
00056         T IxIy2 = IxIy*IxIy;
00057         T abs_det = (IxIxIyIy>IxIy2?(IxIxIyIy-IxIy2):(IxIy2-IxIxIyIy))/(T)N;
00058         vil_math_sqrt_functor vil_sqrt;
00059         output(i,j,p)=vil_sqrt(abs_det);
00060       }
00061     }
00062   }
00063 
00064   // fill in the boundary with zeros
00065   for (unsigned c=0; c<n; ++c){
00066     vil_fill_row(output, c, (T)0);
00067     vil_fill_row(output, nj-c-1, (T)0);
00068     vil_fill_col(output, c, (T)0);
00069     vil_fill_col(output, ni-c-1, (T)0);
00070   }
00071 }
00072 
00073 
00074 //: Filter an image with a gaussian kernel
00075 // This is an ntap alternative to vil_gauss_filter_5tap
00076 // The kernel is generated using vcl_exp instead of vnl_erf
00077 // \param sigma The width of the gaussian
00078 // \param k_size The number of elements in the 1D filter
00079 // \param option The boundary option applied at all boundaries (see vil_convolve_1d)
00080 template <class srcT, class destT>
00081 inline void brip_gauss_filter( const vil_image_view<srcT>& src_im,
00082                                vil_image_view<destT>& dest_im,
00083                                double sigma,
00084                                unsigned int k_size,
00085                                vil_convolve_boundary_option option )
00086 {
00087   unsigned ni = src_im.ni();
00088   unsigned nj = src_im.nj();
00089   unsigned n_planes = src_im.nplanes();
00090   dest_im.set_size(ni, nj, n_planes);
00091   assert (k_size>1 && k_size<ni && k_size<nj);
00092 
00093   // compute the kernel
00094   double *kernel = new double[k_size];
00095   for (unsigned int i=0; i<k_size; ++i){
00096     double val = ((double(i)+0.5)-double(k_size)/2.0);
00097     kernel[i] = vcl_exp(-(val*val)/(2.0*sigma*sigma));
00098   }
00099   double sum = 0.0;
00100   for (unsigned int i=0; i<k_size; ++i) sum += kernel[i];
00101   for (unsigned int i=0; i<k_size; ++i) kernel[i] /= sum;
00102 
00103   vil_image_view<destT> work(ni, nj, n_planes);
00104 
00105   // filter horizontal
00106   vil_convolve_1d(src_im, work, kernel+int(k_size)/2,
00107                   -int(k_size)/2, int(k_size-1)/2,
00108                   destT(0), option, option);
00109 
00110   // filter vertical
00111   vil_image_view<destT> work_t = vil_transpose(work);
00112   vil_image_view<destT> dest_t = vil_transpose(dest_im);
00113   vil_convolve_1d(work_t, dest_t, kernel+int(k_size)/2,
00114                   -int(k_size)/2, int(k_size-1)/2,
00115                   destT(0), option, option);
00116 
00117   delete [] kernel;
00118 }
00119 
00120 #endif // brip_vil_ops_h_