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

vimt_sample_grid_bicub.txx

Go to the documentation of this file.
00001 // This is mul/vimt/vimt_sample_grid_bicub.txx
00002 #ifndef vimt_sample_grid_bicub_txx_
00003 #define vimt_sample_grid_bicub_txx_
00004 //:
00005 // \file
00006 // \brief Grid sampling functions for 2D images
00007 // \author Tim Cootes
00008 
00009 #include "vimt_sample_grid_bicub.h"
00010 #include <vil/vil_sample_grid_bicub.h>
00011 #include <vil/vil_bicub_interp.h>
00012 #include <vnl/vnl_vector.h>
00013 #include <vgl/vgl_vector_2d.h>
00014 
00015 inline bool vimt_grid_corner_in_image(const vgl_point_2d<double>& p,
00016                                       const vil_image_view_base& image)
00017 {
00018   if (p.x()<1) return false;
00019   if (p.x()<1) return false;
00020   if (p.x()+2>image.ni()) return false;
00021   if (p.y()+2>image.nj()) return false;
00022   return true;
00023 }
00024 
00025 //: Sample grid from image, using bicubic interpolation
00026 //  Grid points are p+i.u+j.v where i=[0..n1-1], j=[0..n2-1]
00027 //  Vector vec is resized to n1*n2*np elements, where np=image.nplanes().
00028 //  vec[0]..vec[np-1] are the values from point p0
00029 //  Samples are taken along direction v first, then along u.
00030 //  Points outside image return zero.
00031 // \relates vimt_image_2d_of
00032 template <class imType, class vecType>
00033 void vimt_sample_grid_bicub(vnl_vector<vecType>& vec,
00034                             const vimt_image_2d_of<imType>& image,
00035                             const vgl_point_2d<double>& p0,
00036                             const vgl_vector_2d<double>& u,
00037                             const vgl_vector_2d<double>& v,
00038                             int n1, int n2)
00039 {
00040   vgl_point_2d<double> im_p0 = image.world2im()(p0);
00041   vgl_point_2d<double> im_p1 = image.world2im()(p0+(n1-1)*u);
00042   vgl_point_2d<double> im_p2 = image.world2im()(p0+(n2-1)*v);
00043   int np = image.image().nplanes();
00044   vec.set_size(n1*n2*np);
00045   vecType *vec_data = vec.data_block();
00046 
00047   if (image.world2im().form()!=vimt_transform_2d::Projective)
00048   {
00049     // Can do all work in image co-ordinates under an affine transformation
00050     vgl_vector_2d<double> im_u(0,0);
00051     if (n1>1) im_u = (im_p1-im_p0)/(n1-1);
00052     vgl_vector_2d<double> im_v(0,0);
00053     if (n2>1) im_v = (im_p2-im_p0)/(n2-1);
00054 
00055     vil_sample_grid_bicub(vec_data,image.image(),im_p0.x(),im_p0.y(),
00056                           im_u.x(),im_u.y(),im_v.x(),im_v.y(),n1,n2);
00057     return;
00058   }
00059 
00060   // Otherwise do more fiddly projective calculations
00061 
00062   // Check that all the grid points are within the image.
00063   const vimt_transform_2d& w2i = image.world2im();
00064   bool all_in_image =
00065       vimt_grid_corner_in_image(im_p0,image.image()) &&
00066       vimt_grid_corner_in_image(im_p1,image.image()) &&
00067       vimt_grid_corner_in_image(im_p2,image.image()) &&
00068       vimt_grid_corner_in_image(w2i(p0+(n1-1)*u+(n2-1)*v),image.image());
00069 
00070   vgl_point_2d<double> p1=p0;
00071 
00072   const imType* plane0 = image.image().top_left_ptr();
00073   unsigned ni = image.image().ni();
00074   unsigned nj = image.image().nj();
00075   vcl_ptrdiff_t istep = image.image().istep();
00076   vcl_ptrdiff_t jstep = image.image().jstep();
00077   vcl_ptrdiff_t pstep = image.image().planestep();
00078 
00079   if (all_in_image)
00080   {
00081     if (np==1)
00082     {
00083       for (int i=0;i<n1;++i,p1+=u)
00084       {
00085         vgl_point_2d<double> p=p1;  // Start of j-th row
00086         for (int j=0;j<n2;++j,p+=v,++vec_data)
00087         {
00088           vgl_point_2d<double> im_p = w2i(p);
00089           *vec_data = vil_bicub_interp_raw(im_p.x(),im_p.y(),plane0,istep,jstep);
00090         }
00091       }
00092     }
00093     else
00094     {
00095       for (int i=0;i<n1;++i,p1+=u)
00096       {
00097         vgl_point_2d<double> p=p1;  // Start of j-th row
00098         for (int j=0;j<n2;++j,p+=v)
00099         {
00100           vgl_point_2d<double> im_p = w2i(p);
00101           for (int k=0;k<np;++k,++vec_data)
00102             *vec_data = vil_bicub_interp_raw(im_p.x(),im_p.y(),plane0+k*pstep,istep,jstep);
00103         }
00104       }
00105     }
00106   }
00107   else
00108   {
00109     // Use safe interpolation
00110     if (np==1)
00111     {
00112       for (int i=0;i<n1;++i,p1+=u)
00113       {
00114         vgl_point_2d<double> p=p1;  // Start of j-th row
00115         for (int j=0;j<n2;++j,p+=v,++vec_data)
00116         {
00117           vgl_point_2d<double> im_p = w2i(p);
00118           *vec_data = vil_bicub_interp_safe(im_p.x(),im_p.y(),plane0,ni,nj,istep,jstep);
00119         }
00120       }
00121     }
00122     else
00123     {
00124       for (int i=0;i<n1;++i,p1+=u)
00125       {
00126         vgl_point_2d<double> p=p1;  // Start of j-th row
00127         for (int j=0;j<n2;++j,p+=v)
00128         {
00129           vgl_point_2d<double> im_p = w2i(p);
00130           for (int k=0;k<np;++k,++vec_data)
00131             *vec_data = vil_bicub_interp_safe(im_p.x(),im_p.y(),plane0+k*pstep,ni,nj,istep,jstep);
00132         }
00133       }
00134     }
00135   }
00136 }
00137 
00138 #define VIMT_SAMPLE_GRID_BICUB_INSTANTIATE( imType, vecType ) \
00139 template void vimt_sample_grid_bicub(vnl_vector<vecType >&, \
00140                                      const vimt_image_2d_of<imType >&, \
00141                                      const vgl_point_2d<double >&, \
00142                                      const vgl_vector_2d<double >&, \
00143                                      const vgl_vector_2d<double >&, \
00144                                      int, int)
00145 
00146 #endif // vimt_sample_grid_bicub_txx_

Generated on Thu Jan 10 14:43:58 2008 for contrib/mul/vimt by  doxygen 1.4.4