contrib/mul/vimt/vimt_sample_profile_bilin.txx
Go to the documentation of this file.
00001 // This is mul/vimt/vimt_sample_profile_bilin.txx
00002 #ifndef vimt_sample_profile_bilin_txx_
00003 #define vimt_sample_profile_bilin_txx_
00004 //:
00005 //  \file
00006 //  \brief Profile sampling functions for 2D images
00007 //  \author Tim Cootes
00008 
00009 #include "vimt_sample_profile_bilin.h"
00010 #include <vil/vil_sample_profile_bilin.h>
00011 #include <vil/vil_bilin_interp.h>
00012 #include <vnl/vnl_vector.h>
00013 #include <vgl/vgl_point_2d.h>
00014 #include <vgl/vgl_vector_2d.h>
00015 
00016 inline bool vimt_profile_in_image(const vgl_point_2d<double>& p0,
00017                                   const vgl_point_2d<double>& p1,
00018                                   const vil_image_view_base& image)
00019 {
00020   return p0.x()>=0 && p0.x()<=image.ni()-1 &&
00021          p0.y()>=0 && p0.y()<=image.nj()-1 &&
00022          p1.x()>=0 && p1.x()<=image.ni()-1 &&
00023          p1.y()>=0 && p1.y()<=image.nj()-1;
00024 }
00025 
00026 //: Sample along profile, using bilinear interpolation.
00027 //  Profile points are p+i*u, where i=[0..n-1].
00028 //  Vector v is resized to n*np elements, where np=image.n_planes().
00029 //  v[0]..v[np-1] are the values from point p
00030 template <class imType, class vecType>
00031 void vimt_sample_profile_bilin(vnl_vector<vecType>& vec,
00032                                const vimt_image_2d_of<imType>& image,
00033                                const vgl_point_2d<double>& p0,
00034                                const vgl_vector_2d<double>& u,
00035                                int n)
00036 {
00037   // Check that all the profile points are within the image.
00038   vgl_point_2d<double> im_p0 = image.world2im()(p0);
00039   vgl_point_2d<double> im_p1 = image.world2im()(p0+(n-1)*u);
00040   int np = image.image().nplanes();
00041   vec.set_size(n*np);
00042   vecType *v = vec.data_block();
00043 
00044   if (image.world2im().form()!=vimt_transform_2d::Projective)
00045   {
00046     // Can do all work in image co-ordinates under an affine transformation
00047     double dx = (im_p1.x()-im_p0.x())/(n-1);
00048     double dy = (im_p1.y()-im_p0.y())/(n-1);
00049 
00050     // Sample along profile between im_p0 and im_p1
00051     vil_sample_profile_bilin(v,image.image(),im_p0.x(),im_p0.y(),dx,dy,n);
00052     return;
00053   }
00054 
00055   // Otherwise do more fiddly projective calculations
00056 
00057   vgl_point_2d<double> im_p, p=p0;
00058   const vimt_transform_2d& w2i = image.world2im();
00059 
00060   if (vimt_profile_in_image(im_p0,im_p1,image.image_base()))
00061   {
00062     if (np==1)
00063     {
00064       for (int i=0;i<n;++i,p+=u)
00065       {
00066         im_p = w2i(p);
00067         v[i] = vil_bilin_interp(image.image(),im_p.x(),im_p.y());
00068       }
00069     }
00070     else
00071     {
00072       for (int i=0;i<n;++i,p+=u)
00073       {
00074         im_p = w2i(p);
00075         for (int plane=0;plane<np;++plane,++v)
00076           *v = vil_bilin_interp(image.image(),im_p.x(),im_p.y(),plane);
00077       }
00078     }
00079   }
00080   else // Use safe interpolation, setting v to zero if outside the image:
00081   {
00082     if (np==1)
00083     {
00084       for (int i=0;i<n;++i,p+=u)
00085       {
00086         im_p = w2i(p);
00087         v[i] = vil_bilin_interp_safe(image.image(),im_p.x(),im_p.y());
00088       }
00089     }
00090     else
00091     {
00092       for (int i=0;i<n;++i,p+=u)
00093       {
00094         im_p = w2i(p);
00095         for (int plane=0;plane<np;++plane,++v)
00096           *v = vil_bilin_interp_safe(image.image(),im_p.x(),im_p.y(),plane);
00097       }
00098     }
00099   }
00100 }
00101 
00102 
00103 //: Sample along profile, using bilinear interpolation.
00104 //  Profile points are p+i*u, where i=[0..n-1].
00105 //  Vector v is resized to n*np elements, where np=image.n_planes().
00106 //  v[0]..v[np-1] are the values from point p
00107 //  Values outside image are set to NA
00108 template <class imType, class vecType>
00109 void vimt_sample_profile_bilin_edgena(vnl_vector<vecType>& vec,
00110                                      const vimt_image_2d_of<imType>& image,
00111                                      const vgl_point_2d<double>& p0,
00112                                      const vgl_vector_2d<double>& u,
00113                                      int n)
00114 {
00115   // Check that all the profile points are within the image.
00116   vgl_point_2d<double> im_p0 = image.world2im()(p0);
00117   vgl_point_2d<double> im_p1 = image.world2im()(p0+(n-1)*u);
00118   int np = image.image().nplanes();
00119   vec.set_size(n*np);
00120   vecType *v = vec.data_block();
00121 
00122   if (image.world2im().form()!=vimt_transform_2d::Projective)
00123   {
00124     // Can do all work in image co-ordinates under an affine transformation
00125     double dx = (im_p1.x()-im_p0.x())/(n-1);
00126     double dy = (im_p1.y()-im_p0.y())/(n-1);
00127 
00128     // Sample along profile between im_p0 and im_p1
00129     vil_sample_profile_bilin_edgena(v,image.image(),im_p0.x(),im_p0.y(),dx,dy,n);
00130     return;
00131   }
00132 
00133   // Otherwise do more fiddly projective calculations
00134 
00135   vgl_point_2d<double> im_p, p=p0;
00136   const vimt_transform_2d& w2i = image.world2im();
00137 
00138   if (vimt_profile_in_image(im_p0,im_p1,image.image_base()))
00139   {
00140     if (np==1)
00141     {
00142       for (int i=0;i<n;++i,p+=u)
00143       {
00144         im_p = w2i(p);
00145         v[i] = vil_bilin_interp(image.image(),im_p.x(),im_p.y());
00146       }
00147     }
00148     else
00149     {
00150       for (int i=0;i<n;++i,p+=u)
00151       {
00152         im_p = w2i(p);
00153         for (int plane=0;plane<np;++plane,++v)
00154           *v = vil_bilin_interp(image.image(),im_p.x(),im_p.y(),plane);
00155       }
00156     }
00157   }
00158   else // Use safe interpolation, setting v to NA if outside the image:
00159   {
00160     if (np==1)
00161     {
00162       for (int i=0;i<n;++i,p+=u)
00163       {
00164         im_p = w2i(p);
00165         v[i] = vil_bilin_interp_safe_edgena(image.image(),im_p.x(),im_p.y());
00166       }
00167     }
00168     else
00169     {
00170       for (int i=0;i<n;++i,p+=u)
00171       {
00172         im_p = w2i(p);
00173         for (int plane=0;plane<np;++plane,++v)
00174           *v = vil_bilin_interp_safe_edgena(image.image(),im_p.x(),im_p.y(),plane);
00175       }
00176     }
00177   }
00178 }
00179 
00180 
00181 #define VIMT_SAMPLE_PROFILE_BILIN_INSTANTIATE( imType, vecType ) \
00182 template void vimt_sample_profile_bilin(vnl_vector<vecType >& v, \
00183                                         const vimt_image_2d_of<imType >& image, \
00184                                         const vgl_point_2d<double >& p, \
00185                                         const vgl_vector_2d<double >& u, \
00186                                         int n); \
00187 template void vimt_sample_profile_bilin_edgena(vnl_vector<vecType >& v, \
00188                                                const vimt_image_2d_of<imType >& image, \
00189                                                const vgl_point_2d<double >& p, \
00190                                                const vgl_vector_2d<double >& u, \
00191                                                int n)
00192 
00193 #endif // vimt_sample_profile_bilin_txx_