core/vil/vil_resample_bilin.txx
Go to the documentation of this file.
00001 // This is core/vil/vil_resample_bilin.txx
00002 #ifndef vil_resample_bilin_txx_
00003 #define vil_resample_bilin_txx_
00004 //:
00005 // \file
00006 // \brief Sample grid of points with bilinear interpolation in one image and place in another
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_resample_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_resample_bilin_corner_in_image(double x0, double y0,
00020                                                const vil_image_view_base& image)
00021 {
00022   return x0 >= 0.0
00023       && y0 >= 0.0
00024       && x0+1 <= image.ni()
00025       && y0+1 <= image.nj();
00026 }
00027 
00028 //: Sample grid of points in one image and place in another, using bilinear interpolation.
00029 //  dest_image(i,j,p) is sampled from the src_image at
00030 //  (x0+i.dx1+j.dx2,y0+i.dy1+j.dy2), where i=[0..n1-1], j=[0..n2-1]
00031 //  dest_image resized to (n1,n2,src_image.nplanes())
00032 //  Points outside image return zero.
00033 // \relatesalso vil_image_view
00034 template <class sType, class dType>
00035 void vil_resample_bilin(const vil_image_view<sType>& src_image,
00036                         vil_image_view<dType>& dest_image,
00037                         double x0, double y0, double dx1, double dy1,
00038                         double dx2, double dy2, int n1, int n2)
00039 {
00040   bool all_in_image =    vil_resample_bilin_corner_in_image(x0,y0,src_image)
00041                       && vil_resample_bilin_corner_in_image(x0+(n1-1)*dx1,y0+(n1-1)*dy1,src_image)
00042                       && vil_resample_bilin_corner_in_image(x0+(n2-1)*dx2,y0+(n2-1)*dy2,src_image)
00043                       && vil_resample_bilin_corner_in_image(x0+(n1-1)*dx1+(n2-1)*dx2,
00044                                                             y0+(n1-1)*dy1+(n2-1)*dy2,src_image);
00045 #ifdef DEBUG
00046   // corners
00047   vcl_cout<<"src_image= "<<src_image<<vcl_endl
00048           <<"x0="<<x0<<vcl_endl
00049           <<"y0="<<y0<<vcl_endl
00050           <<"x0+(n1-1)*dx1+(n2-1)*dx2="<<x0+(n1-1)*dx1+(n2-1)*dx2<<vcl_endl
00051           <<"y0+(n1-1)*dy1+(n2-1)*dy2="<<y0+(n1-1)*dy1+(n2-1)*dy2<<vcl_endl;
00052 #endif
00053 
00054   const unsigned ni = src_image.ni();
00055   const unsigned nj = src_image.nj();
00056   const unsigned np = src_image.nplanes();
00057   const vcl_ptrdiff_t istep = src_image.istep();
00058   const vcl_ptrdiff_t jstep = src_image.jstep();
00059   const vcl_ptrdiff_t pstep = src_image.planestep();
00060   const sType* plane0 = src_image.top_left_ptr();
00061 
00062   dest_image.set_size(n1,n2,np);
00063   const vcl_ptrdiff_t d_istep = dest_image.istep();
00064   const vcl_ptrdiff_t d_jstep = dest_image.jstep();
00065   const vcl_ptrdiff_t d_pstep = dest_image.planestep();
00066   dType* d_plane0 = dest_image.top_left_ptr();
00067 
00068   double x1=x0;
00069   double y1=y0;
00070 
00071   if (all_in_image)
00072   {
00073     if (np==1)
00074     {
00075       dType *row = d_plane0;
00076       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00077       {
00078         double x=x1, y=y1;  // Start of j-th row
00079         dType *dpt = row;
00080         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00081           *dpt = (dType) vil_bilin_interp_raw(x,y,plane0,ni,nj,istep,jstep);
00082       }
00083     }
00084     else
00085     {
00086       dType *row = d_plane0;
00087       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00088       {
00089         double x=x1, y=y1; // Start of j-th row
00090         dType *dpt = row;
00091         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00092         {
00093           for (unsigned int p=0;p<np;++p)
00094             dpt[p*d_pstep] = (dType) vil_bilin_interp_raw(x,y,plane0+p*pstep,ni,nj,istep,jstep);
00095         }
00096       }
00097     }
00098   }
00099   else
00100   {
00101     // Use safe interpolation
00102     if (np==1)
00103     {
00104       dType *row = d_plane0;
00105       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00106       {
00107         double x=x1, y=y1;  // Start of j-th row
00108         dType *dpt = row;
00109         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00110           *dpt = (dType) vil_bilin_interp_safe(x,y,plane0,
00111                                                ni,nj,istep,jstep);
00112       }
00113     }
00114     else
00115     {
00116       dType *row = d_plane0;
00117       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00118       {
00119         double x=x1, y=y1; // Start of j-th row
00120         dType *dpt = row;
00121         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00122         {
00123           for (unsigned int p=0;p<np;++p)
00124             dpt[p*d_pstep] = (dType) vil_bilin_interp_safe(x,y,plane0+p*pstep,
00125                                                            ni,nj,istep,jstep);
00126         }
00127       }
00128     }
00129   }
00130 }
00131 
00132 
00133 //: Resample image to a specified width (n1) and height (n2)
00134 template <class sType, class dType>
00135 void vil_resample_bilin(const vil_image_view<sType>& src_image,
00136                         vil_image_view<dType>& dest_image,
00137                         int n1, int n2)
00138 {
00139   double f= 0.9999999; // so sampler doesn't go off edge of image
00140   double x0=0;
00141   double y0=0;
00142   double dx1=f*(src_image.ni()-1)*1.0/(n1-1);
00143   double dy1=0;
00144   double dx2=0;
00145   double dy2=f*(src_image.nj()-1)*1.0/(n2-1);
00146   vil_resample_bilin( src_image, dest_image, x0, y0, dx1, dy1, dx2, dy2, n1, n2 );
00147 }
00148 
00149 
00150 //: Sample grid of points in one image and place in another, using bilinear interpolation.
00151 //  dest_image(i,j,p) is sampled from the src_image at
00152 //  (x0+i.dx1+j.dx2,y0+i.dy1+j.dy2), where i=[0..n1-1], j=[0..n2-1]
00153 //  dest_image resized to (n1,n2,src_image.nplanes())
00154 //  Points outside image return zero.
00155 // \relatesalso vil_image_view
00156 template <class sType, class dType>
00157 void vil_resample_bilin_edge_extend(
00158   const vil_image_view<sType>& src_image,
00159   vil_image_view<dType>& dest_image,
00160   double x0, double y0, double dx1, double dy1,
00161   double dx2, double dy2, int n1, int n2)
00162 {
00163   bool all_in_image =    vil_resample_bilin_corner_in_image(x0,y0,src_image)
00164                       && vil_resample_bilin_corner_in_image(x0+(n1-1)*dx1,y0+(n1-1)*dy1,src_image)
00165                       && vil_resample_bilin_corner_in_image(x0+(n2-1)*dx2,y0+(n2-1)*dy2,src_image)
00166                       && vil_resample_bilin_corner_in_image(x0+(n1-1)*dx1+(n2-1)*dx2,
00167                                                             y0+(n1-1)*dy1+(n2-1)*dy2,src_image);
00168 #ifdef DEBUG
00169   // corners
00170   vcl_cout<<"src_image= "<<src_image<<vcl_endl
00171           <<"x0="<<x0<<vcl_endl
00172           <<"y0="<<y0<<vcl_endl
00173           <<"x0+(n1-1)*dx1+(n2-1)*dx2="<<x0+(n1-1)*dx1+(n2-1)*dx2<<vcl_endl
00174           <<"y0+(n1-1)*dy1+(n2-1)*dy2="<<y0+(n1-1)*dy1+(n2-1)*dy2<<vcl_endl;
00175 #endif
00176 
00177   const unsigned ni = src_image.ni();
00178   const unsigned nj = src_image.nj();
00179   const unsigned np = src_image.nplanes();
00180   const vcl_ptrdiff_t istep = src_image.istep();
00181   const vcl_ptrdiff_t jstep = src_image.jstep();
00182   const vcl_ptrdiff_t pstep = src_image.planestep();
00183   const sType* plane0 = src_image.top_left_ptr();
00184 
00185   dest_image.set_size(n1,n2,np);
00186   const vcl_ptrdiff_t d_istep = dest_image.istep();
00187   const vcl_ptrdiff_t d_jstep = dest_image.jstep();
00188   const vcl_ptrdiff_t d_pstep = dest_image.planestep();
00189   dType* d_plane0 = dest_image.top_left_ptr();
00190 
00191   double x1=x0;
00192   double y1=y0;
00193 
00194   if (all_in_image)
00195   {
00196     if (np==1)
00197     {
00198       dType *row = d_plane0;
00199       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00200       {
00201         double x=x1, y=y1;  // Start of j-th row
00202         dType *dpt = row;
00203         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00204           *dpt = (dType) vil_bilin_interp_raw(x,y,plane0,ni,nj,istep,jstep);
00205       }
00206     }
00207     else
00208     {
00209       dType *row = d_plane0;
00210       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00211       {
00212         double x=x1, y=y1; // Start of j-th row
00213         dType *dpt = row;
00214         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00215         {
00216           for (unsigned int p=0;p<np;++p)
00217             dpt[p*d_pstep] = (dType) vil_bilin_interp_raw(x,y,plane0+p*pstep,ni,nj,istep,jstep);
00218         }
00219       }
00220     }
00221   }
00222   else
00223   {
00224     // Use safe interpolation
00225     if (np==1)
00226     {
00227       dType *row = d_plane0;
00228       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00229       {
00230         double x=x1, y=y1;  // Start of j-th row
00231         dType *dpt = row;
00232         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00233           *dpt = (dType) vil_bilin_interp_safe_extend(
00234             x,y,plane0,ni,nj,istep,jstep);
00235       }
00236     }
00237     else
00238     {
00239       dType *row = d_plane0;
00240       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00241       {
00242         double x=x1, y=y1; // Start of j-th row
00243         dType *dpt = row;
00244         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00245         {
00246           for (unsigned int p=0;p<np;++p)
00247             dpt[p*d_pstep] = (dType) vil_bilin_interp_safe_extend(
00248               x,y,plane0+p*pstep,ni,nj,istep,jstep);
00249         }
00250       }
00251     }
00252   }
00253 }
00254 
00255 
00256 //: Resample image to a specified width (n1) and height (n2)
00257 template <class sType, class dType>
00258 void vil_resample_bilin_edge_extend(const vil_image_view<sType>& src_image,
00259                                     vil_image_view<dType>& dest_image,
00260                                     int n1, int n2)
00261 {
00262   double f= 0.9999999; // so sampler doesn't go off edge of image
00263   double x0=0;
00264   double y0=0;
00265   double dx1=f*(src_image.ni()-1)*1.0/(n1-1);
00266   double dy1=0;
00267   double dx2=0;
00268   double dy2=f*(src_image.nj()-1)*1.0/(n2-1);
00269   vil_resample_bilin_edge_extend(
00270     src_image, dest_image, x0, y0, dx1, dy1, dx2, dy2, n1, n2 );
00271 }
00272 #define VIL_RESAMPLE_BILIN_INSTANTIATE( sType, dType ) \
00273 template void vil_resample_bilin(const vil_image_view<sType >& src_image, \
00274                                  vil_image_view<dType >& dest_image, \
00275                                  double x0, double y0, double dx1, double dy1, \
00276                                  double dx2, double dy2, int n1, int n2); \
00277 template void vil_resample_bilin(const vil_image_view<sType >& src_image, \
00278                                  vil_image_view<dType >& dest_image, \
00279                                  int n1, int n2); \
00280 template void vil_resample_bilin_edge_extend(const vil_image_view<sType >& src_image, \
00281                                              vil_image_view<dType >& dest_image, \
00282                                              double x0, double y0, double dx1, double dy1, \
00283                                              double dx2, double dy2, int n1, int n2); \
00284 template void vil_resample_bilin_edge_extend(const vil_image_view<sType >& src_image, \
00285                                              vil_image_view<dType >& dest_image, \
00286                                              int n1, int n2)
00287 
00288 #endif // vil_resample_bilin_txx_