core/vil/vil_sample_profile_bilin.txx
Go to the documentation of this file.
00001 // This is core/vil/vil_sample_profile_bilin.txx
00002 #ifndef vil_sample_profile_bilin_txx_
00003 #define vil_sample_profile_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_profile_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_profile_bilin_in_image(double x0, double y0,
00020                                        double x1, double y1,
00021                                        const vil_image_view_base& image)
00022 {
00023   return x0 >= 1
00024       && y0 >= 1
00025       && x1 >= 1
00026       && y1 >= 1
00027       && x0+2 <= image.ni()
00028       && y0+2 <= image.nj()
00029       && x1+2 <= image.ni()
00030       && y1+2 <= image.nj();
00031 }
00032 
00033 //: Sample along profile, using safe bilinear interpolation
00034 //  Profile points are along the line between p0 and p1 (in image co-ordinates).
00035 //  Vector v is resized to n*np elements, where np=image.n_planes().
00036 //  v[0]..v[np-1] are the values from point p
00037 //  Points outside image return zero.
00038 template <class imType, class vecType>
00039 void vil_sample_profile_bilin(vecType* v,
00040                               const vil_image_view<imType>& image,
00041                               double x0, double y0, double dx, double dy,
00042                               int n)
00043 {
00044   bool all_in_image = vil_profile_bilin_in_image(x0,y0,x0+(n-1)*dx,y0+(n-1)*dy,image);
00045 
00046   const unsigned ni = image.ni();
00047   const unsigned nj = image.nj();
00048   const unsigned np = image.nplanes();
00049   const vcl_ptrdiff_t istep = image.istep();
00050   const vcl_ptrdiff_t jstep = image.jstep();
00051   const vcl_ptrdiff_t pstep = image.planestep();
00052   double x=x0;
00053   double y=y0;
00054   const imType* plane0 = image.top_left_ptr();
00055 
00056   if (all_in_image)
00057   {
00058     if (np==1)
00059     {
00060       for (int k=0;k<n;++k,x+=dx,y+=dy)
00061       v[k] = vil_bilin_interp(x,y,plane0,ni,nj,istep,jstep);
00062     }
00063     else
00064     {
00065       for (int k=0;k<n;++k,x+=dx,y+=dy)
00066       {
00067         for (unsigned int p=0;p<np;++p,++v)
00068           *v = vil_bilin_interp(x,y,plane0+p*pstep,ni,nj,istep,jstep);
00069       }
00070     }
00071   }
00072   else
00073   {
00074     // Use safe interpolation
00075     if (np==1)
00076     {
00077       for (int k=0;k<n;++k,x+=dx,y+=dy)
00078       v[k] = vil_bilin_interp_safe(x,y,plane0,ni,nj,istep,jstep);
00079     }
00080     else
00081     {
00082       for (int k=0;k<n;++k,x+=dx,y+=dy)
00083       {
00084         for (unsigned int p=0;p<np;++p,++v)
00085           *v = vil_bilin_interp_safe(x,y,plane0+p*pstep,ni,nj,istep,jstep);
00086       }
00087     }
00088   }
00089 }
00090 
00091 //: Sample along profile, using bilinear interpolation
00092 //  Profile points are along the line between p0 and p1 (in image co-ordinates).
00093 //  Vector v is resized to n*np elements, where np=image.n_planes().
00094 //  v[0]..v[np-1] are the values from point p
00095 //  Points outside image return NA.
00096 template <class imType, class vecType>
00097 void vil_sample_profile_bilin_edgena(vecType* v,
00098                                      const vil_image_view<imType>& image,
00099                                      double x0, double y0, double dx, double dy,
00100                                      int n)
00101 {
00102   bool all_in_image = vil_profile_bilin_in_image(x0,y0,x0+(n-1)*dx,y0+(n-1)*dy,image);
00103 
00104   const unsigned ni = image.ni();
00105   const unsigned nj = image.nj();
00106   const unsigned np = image.nplanes();
00107   const vcl_ptrdiff_t istep = image.istep();
00108   const vcl_ptrdiff_t jstep = image.jstep();
00109   const vcl_ptrdiff_t pstep = image.planestep();
00110   double x=x0;
00111   double y=y0;
00112   const imType* plane0 = image.top_left_ptr();
00113 
00114   if (all_in_image)
00115   {
00116     if (np==1)
00117     {
00118       for (int k=0;k<n;++k,x+=dx,y+=dy)
00119       v[k] = vil_bilin_interp(x,y,plane0,ni,nj,istep,jstep);
00120     }
00121     else
00122     {
00123       for (int k=0;k<n;++k,x+=dx,y+=dy)
00124       {
00125         for (unsigned int p=0;p<np;++p,++v)
00126           *v = vil_bilin_interp(x,y,plane0+p*pstep,ni,nj,istep,jstep);
00127       }
00128     }
00129   }
00130   else
00131   {
00132     // Use safe interpolation
00133     if (np==1)
00134     {
00135       for (int k=0;k<n;++k,x+=dx,y+=dy)
00136         v[k] = vil_bilin_interp_safe_edgena(x,y,plane0,ni,nj,istep,jstep);
00137     }
00138     else
00139     {
00140       for (int k=0;k<n;++k,x+=dx,y+=dy)
00141       {
00142         for (unsigned int p=0;p<np;++p,++v)
00143           *v = vil_bilin_interp_safe_edgena(x,y,plane0+p*pstep,ni,nj,istep,jstep);
00144       }
00145     }
00146   }
00147 }
00148 
00149 #define VIL_SAMPLE_PROFILE_BILIN_INSTANTIATE( imType, vecType ) \
00150 template void vil_sample_profile_bilin(vecType* v, \
00151                                        const vil_image_view<imType >& image, \
00152                                        double x0, double y0, \
00153                                        double dx, double dy, \
00154                                        int n); \
00155 template void vil_sample_profile_bilin_edgena(vecType* v, \
00156                                               const vil_image_view<imType >& image, \
00157                                               double x0, double y0, \
00158                                               double dx, double dy, \
00159                                               int n)
00160 #endif // vil_sample_profile_bilin_txx_