core/vil/vil_sample_grid_bilin.txx
Go to the documentation of this file.
00001 // This is core/vil/vil_sample_grid_bilin.txx
00002 #ifndef vil_sample_grid_bilin_txx_
00003 #define vil_sample_grid_bilin_txx_
00004 //:
00005 // \file
00006 // \brief Bilinear profile sampling functions for 2D images
00007 // \author Tim Cootes
00008 //
00009 // The vil bicub source files were derived from the corresponding
00010 // vil bilin files, thus the vil bilin/bicub source files are very
00011 // similar.  If you modify something in this file, there is a
00012 // corresponding bicub file that would likely also benefit from
00013 // the same change.
00014 
00015 #include "vil_sample_grid_bilin.h"
00016 #include <vil/vil_bilin_interp.h>
00017 
00018 //: This function should not be the same in bicub and bilin
00019 inline bool vil_grid_bilin_corner_in_image(double x0, double y0,
00020                                            const vil_image_view_base& image)
00021 {
00022   return x0 >= 1
00023       && y0 >= 1
00024       && x0+2 <= image.ni()
00025       && y0+2 <= image.nj();
00026 }
00027 
00028 //: Sample along profile, using safe bilinear interpolation
00029 //  Profile points are along the line between p0 and p1 (in image co-ordinates).
00030 //  Vector v is resized to n*np elements, where np=image.n_planes().
00031 //  v[0]..v[np-1] are the values from point p
00032 //  Points outside image return zero.
00033 template <class imType, class vecType>
00034 void vil_sample_grid_bilin(vecType* v,
00035                            const vil_image_view<imType>& image,
00036                            double x0, double y0, double dx1, double dy1,
00037                            double dx2, double dy2, int n1, int n2)
00038 {
00039   bool all_in_image =    vil_grid_bilin_corner_in_image(x0,y0,image)
00040                       && vil_grid_bilin_corner_in_image(x0+(n1-1)*dx1,y0+(n1-1)*dy1,image)
00041                       && vil_grid_bilin_corner_in_image(x0+(n2-1)*dx2,y0+(n2-1)*dy2,image)
00042                       && vil_grid_bilin_corner_in_image(x0+(n1-1)*dx1+(n2-1)*dx2,
00043                                                         y0+(n1-1)*dy1+(n2-1)*dy2,image);
00044 
00045   const unsigned ni = image.ni();
00046   const unsigned nj = image.nj();
00047   const unsigned np = image.nplanes();
00048   const vcl_ptrdiff_t istep = image.istep();
00049   const vcl_ptrdiff_t jstep = image.jstep();
00050   const vcl_ptrdiff_t pstep = image.planestep();
00051   double x1=x0;
00052   double y1=y0;
00053   const imType* plane0 = image.top_left_ptr();
00054 
00055   if (all_in_image)
00056   {
00057     if (np==1)
00058     {
00059       for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
00060       {
00061         double x=x1, y=y1;  // Start of j-th row
00062         for (int j=0;j<n2;++j,x+=dx2,y+=dy2,++v)
00063           *v = (vecType) vil_bilin_interp(x,y,plane0,ni,nj,istep,jstep);
00064       }
00065     }
00066     else
00067     {
00068       for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
00069       {
00070         double x=x1, y=y1; // Start of j-th row
00071         for (int j=0;j<n2;++j,x+=dx2,y+=dy2)
00072         {
00073           for (unsigned p=0;p<np;++p,++v)
00074             *v = (vecType) vil_bilin_interp(x,y,plane0+p*pstep,ni,nj,istep,jstep);
00075         }
00076       }
00077     }
00078   }
00079   else
00080   {
00081     // Use safe interpolation
00082     if (np==1)
00083     {
00084       for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
00085       {
00086         double x=x1, y=y1;  // Start of j-th row
00087         for (int j=0;j<n2;++j,x+=dx2,y+=dy2,++v)
00088           *v = (vecType) vil_bilin_interp_safe(x,y,plane0,ni,nj,istep,jstep);
00089       }
00090     }
00091     else
00092     {
00093       for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
00094       {
00095         double x=x1, y=y1; // Start of j-th row
00096         for (int j=0;j<n2;++j,x+=dx2,y+=dy2)
00097         {
00098           for (unsigned p=0;p<np;++p,++v)
00099             *v = (vecType) vil_bilin_interp_safe(x,y,plane0+p*pstep,ni,nj,istep,jstep);
00100         }
00101       }
00102     }
00103   }
00104 }
00105 
00106 
00107 
00108 
00109 //: Sample along profile, using safe bilinear interpolation
00110 //  Profile points are along the line between p0 and p1 (in image co-ordinates).
00111 //  Vector v is resized to n*np elements, where np=image.n_planes().
00112 //  v[0]..v[np-1] are the values from point p
00113 //  Points outside image return NA.
00114 template <class imType, class vecType>
00115 void vil_sample_grid_bilin_edgena(vecType* v,
00116                                   const vil_image_view<imType>& image,
00117                                   double x0, double y0, double dx1, double dy1,
00118                                   double dx2, double dy2, int n1, int n2)
00119 {
00120   bool all_in_image =    vil_grid_bilin_corner_in_image(x0,y0,image)
00121                       && vil_grid_bilin_corner_in_image(x0+(n1-1)*dx1,y0+(n1-1)*dy1,image)
00122                       && vil_grid_bilin_corner_in_image(x0+(n2-1)*dx2,y0+(n2-1)*dy2,image)
00123                       && vil_grid_bilin_corner_in_image(x0+(n1-1)*dx1+(n2-1)*dx2,
00124                                                         y0+(n1-1)*dy1+(n2-1)*dy2,image);
00125 
00126   const unsigned ni = image.ni();
00127   const unsigned nj = image.nj();
00128   const unsigned np = image.nplanes();
00129   const vcl_ptrdiff_t istep = image.istep();
00130   const vcl_ptrdiff_t jstep = image.jstep();
00131   const vcl_ptrdiff_t pstep = image.planestep();
00132   double x1=x0;
00133   double y1=y0;
00134   const imType* plane0 = image.top_left_ptr();
00135 
00136   if (all_in_image)
00137   {
00138     if (np==1)
00139     {
00140       for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
00141       {
00142         double x=x1, y=y1;  // Start of j-th row
00143         for (int j=0;j<n2;++j,x+=dx2,y+=dy2,++v)
00144           *v = (vecType) vil_bilin_interp(x,y,plane0,ni,nj,istep,jstep);
00145       }
00146     }
00147     else
00148     {
00149       for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
00150       {
00151         double x=x1, y=y1; // Start of j-th row
00152         for (int j=0;j<n2;++j,x+=dx2,y+=dy2)
00153         {
00154           for (unsigned p=0;p<np;++p,++v)
00155             *v = (vecType) vil_bilin_interp(x,y,plane0+p*pstep,ni,nj,istep,jstep);
00156         }
00157       }
00158     }
00159   }
00160   else
00161   {
00162     // Use safe interpolation
00163     if (np==1)
00164     {
00165       for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
00166       {
00167         double x=x1, y=y1;  // Start of j-th row
00168         for (int j=0;j<n2;++j,x+=dx2,y+=dy2,++v)
00169           *v = (vecType) vil_bilin_interp_safe_edgena(x,y,plane0,ni,nj,istep,jstep);
00170       }
00171     }
00172     else
00173     {
00174       for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
00175       {
00176         double x=x1, y=y1; // Start of j-th row
00177         for (int j=0;j<n2;++j,x+=dx2,y+=dy2)
00178         {
00179           for (unsigned p=0;p<np;++p,++v)
00180             *v = (vecType) vil_bilin_interp_safe_edgena(x,y,plane0+p*pstep,ni,nj,istep,jstep);
00181         }
00182       }
00183     }
00184   }
00185 }
00186 
00187 #define VIL_SAMPLE_GRID_BILIN_INSTANTIATE( imType, vecType ) \
00188 template void vil_sample_grid_bilin(vecType* v, \
00189                                     const vil_image_view<imType >& image, \
00190                                     double x0, double y0, double dx1, double dy1, \
00191                                     double dx2, double dy2, int n1, int n2); \
00192 template void vil_sample_grid_bilin_edgena(vecType* v, \
00193                                            const vil_image_view<imType >& image, \
00194                                            double x0, double y0, double dx1, double dy1, \
00195                                            double dx2, double dy2, int n1, int n2)
00196 
00197 #endif // vil_sample_grid_bilin_txx_