core/vil/vil_resample_bicub.txx
Go to the documentation of this file.
00001 // This is core/vil/vil_resample_bicub.txx
00002 #ifndef vil_resample_bicub_txx_
00003 #define vil_resample_bicub_txx_
00004 //:
00005 // \file
00006 // \brief Sample grid of points with bicubic interpolation in one image and place in another
00007 //
00008 // The vil bicub source files were derived from the corresponding
00009 // vil bilin files, thus the vil bilin/bicub source files are very
00010 // similar.  If you modify something in this file, there is a
00011 // corresponding bilin file that would likely also benefit from
00012 // the same change.
00013 
00014 #include "vil_resample_bicub.h"
00015 #include <vil/vil_bicub_interp.h>
00016 
00017 //: This function should not be the same in bicub and bilin
00018 inline bool vil_resample_bicub_corner_in_image(double x0, double y0,
00019                                                const vil_image_view_base& image)
00020 {
00021   return x0 >= 1
00022       && y0 >= 1
00023       && x0+2 <= image.ni()
00024       && y0+2 <= image.nj();
00025 }
00026 
00027 //: Sample grid of points in one image and place in another, using bicubic interpolation.
00028 //  dest_image(i,j,p) is sampled from the src_image at
00029 //  (x0+i.dx1+j.dx2,y0+i.dy1+j.dy2), where i=[0..n1-1], j=[0..n2-1]
00030 //  dest_image resized to (n1,n2,src_image.nplanes())
00031 //  Points outside image return zero.
00032 // \relatesalso vil_image_view
00033 template <class sType, class dType>
00034 void vil_resample_bicub(const vil_image_view<sType>& src_image,
00035                         vil_image_view<dType>& dest_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_resample_bicub_corner_in_image(x0,y0,src_image)
00040                       && vil_resample_bicub_corner_in_image(x0+(n1-1)*dx1,y0+(n1-1)*dy1,src_image)
00041                       && vil_resample_bicub_corner_in_image(x0+(n2-1)*dx2,y0+(n2-1)*dy2,src_image)
00042                       && vil_resample_bicub_corner_in_image(x0+(n1-1)*dx1+(n2-1)*dx2,
00043                                                             y0+(n1-1)*dy1+(n2-1)*dy2,src_image);
00044 
00045   const unsigned ni = src_image.ni();
00046   const unsigned nj = src_image.nj();
00047   const unsigned np = src_image.nplanes();
00048   const vcl_ptrdiff_t istep = src_image.istep();
00049   const vcl_ptrdiff_t jstep = src_image.jstep();
00050   const vcl_ptrdiff_t pstep = src_image.planestep();
00051   const sType* plane0 = src_image.top_left_ptr();
00052 
00053   dest_image.set_size(n1,n2,np);
00054   const vcl_ptrdiff_t d_istep = dest_image.istep();
00055   const vcl_ptrdiff_t d_jstep = dest_image.jstep();
00056   const vcl_ptrdiff_t d_pstep = dest_image.planestep();
00057   dType* d_plane0 = dest_image.top_left_ptr();
00058 
00059   double x1=x0;
00060   double y1=y0;
00061 
00062   if (all_in_image)
00063   {
00064     if (np==1)
00065     {
00066       dType *row = d_plane0;
00067       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00068       {
00069         double x=x1, y=y1;  // Start of j-th row
00070         dType *dpt = row;
00071         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00072           *dpt = (dType) vil_bicub_interp_raw(x,y,plane0,ni,nj,istep,jstep);
00073       }
00074     }
00075     else
00076     {
00077       dType *row = d_plane0;
00078       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00079       {
00080         double x=x1, y=y1; // Start of j-th row
00081         dType *dpt = row;
00082         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00083         {
00084           for (unsigned int p=0;p<np;++p)
00085             dpt[p*d_pstep] = (dType) vil_bicub_interp_raw(x,y,plane0+p*pstep,ni,nj,istep,jstep);
00086         }
00087       }
00088     }
00089   }
00090   else
00091   {
00092     // Use safe interpolation
00093     if (np==1)
00094     {
00095       dType *row = d_plane0;
00096       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00097       {
00098         double x=x1, y=y1;  // Start of j-th row
00099         dType *dpt = row;
00100         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00101           *dpt = (dType) vil_bicub_interp_safe(x,y,plane0,
00102                                                ni,nj,istep,jstep);
00103       }
00104     }
00105     else
00106     {
00107       dType *row = d_plane0;
00108       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00109       {
00110         double x=x1, y=y1; // Start of j-th row
00111         dType *dpt = row;
00112         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00113         {
00114           for (unsigned int p=0;p<np;++p)
00115             dpt[p*d_pstep] = (dType) vil_bicub_interp_safe(x,y,plane0+p*pstep,
00116                                                             ni,nj,istep,jstep);
00117         }
00118       }
00119     }
00120   }
00121 }
00122 
00123 
00124 //: Sample grid of points in one image and place in another, using bicubic interpolation.
00125 //  dest_image(i,j,p) is sampled from the src_image at
00126 //  (x0+i.dx1+j.dx2,y0+i.dy1+j.dy2), where i=[0..n1-1], j=[0..n2-1]
00127 //  dest_image resized to (n1,n2,src_image.nplanes())
00128 //  Points outside image return zero.
00129 // \relatesalso vil_image_view
00130 template <class sType, class dType>
00131 void vil_resample_bicub_edge_extend(const vil_image_view<sType>& src_image,
00132                                     vil_image_view<dType>& dest_image,
00133                                     double x0, double y0, double dx1, double dy1,
00134                                     double dx2, double dy2, int n1, int n2)
00135 {
00136   bool all_in_image =    vil_resample_bicub_corner_in_image(x0,y0,src_image)
00137                       && vil_resample_bicub_corner_in_image(x0+(n1-1)*dx1,y0+(n1-1)*dy1,src_image)
00138                       && vil_resample_bicub_corner_in_image(x0+(n2-1)*dx2,y0+(n2-1)*dy2,src_image)
00139                       && vil_resample_bicub_corner_in_image(x0+(n1-1)*dx1+(n2-1)*dx2,
00140                                                             y0+(n1-1)*dy1+(n2-1)*dy2,src_image);
00141 
00142   const unsigned ni = src_image.ni();
00143   const unsigned nj = src_image.nj();
00144   const unsigned np = src_image.nplanes();
00145   const vcl_ptrdiff_t istep = src_image.istep();
00146   const vcl_ptrdiff_t jstep = src_image.jstep();
00147   const vcl_ptrdiff_t pstep = src_image.planestep();
00148   const sType* plane0 = src_image.top_left_ptr();
00149 
00150   dest_image.set_size(n1,n2,np);
00151   const vcl_ptrdiff_t d_istep = dest_image.istep();
00152   const vcl_ptrdiff_t d_jstep = dest_image.jstep();
00153   const vcl_ptrdiff_t d_pstep = dest_image.planestep();
00154   dType* d_plane0 = dest_image.top_left_ptr();
00155 
00156   double x1=x0;
00157   double y1=y0;
00158 
00159   if (all_in_image)
00160   {
00161     if (np==1)
00162     {
00163       dType *row = d_plane0;
00164       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00165       {
00166         double x=x1, y=y1;  // Start of j-th row
00167         dType *dpt = row;
00168         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00169           *dpt = (dType) vil_bicub_interp_raw(x,y,plane0,ni,nj,istep,jstep);
00170       }
00171     }
00172     else
00173     {
00174       dType *row = d_plane0;
00175       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00176       {
00177         double x=x1, y=y1; // Start of j-th row
00178         dType *dpt = row;
00179         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00180         {
00181           for (unsigned int p=0;p<np;++p)
00182             dpt[p*d_pstep] = (dType) vil_bicub_interp_raw(x,y,plane0+p*pstep,ni,nj,istep,jstep);
00183         }
00184       }
00185     }
00186   }
00187   else
00188   {
00189     // Use safe interpolation
00190     if (np==1)
00191     {
00192       dType *row = d_plane0;
00193       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00194       {
00195         double x=x1, y=y1;  // Start of j-th row
00196         dType *dpt = row;
00197         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00198           *dpt = (dType) vil_bicub_interp_safe_extend(x,y,plane0,
00199                                                       ni,nj,istep,jstep);
00200       }
00201     }
00202     else
00203     {
00204       dType *row = d_plane0;
00205       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00206       {
00207         double x=x1, y=y1; // Start of j-th row
00208         dType *dpt = row;
00209         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00210         {
00211           for (unsigned int p=0;p<np;++p)
00212             dpt[p*d_pstep] = (dType) vil_bicub_interp_safe_extend(x,y,plane0+p*pstep,
00213                                                                   ni,nj,istep,jstep);
00214         }
00215       }
00216     }
00217   }
00218 }
00219 
00220 
00221 //: Resample image to a specified width (n1) and height (n2)
00222 template <class sType, class dType>
00223 void vil_resample_bicub(const vil_image_view<sType>& src_image,
00224                         vil_image_view<dType>& dest_image,
00225                         int n1, int n2)
00226 {
00227   double f= 1.0; // so sampler doesn't go off edge of image
00228   double x0=0;
00229   double y0=0;
00230   double dx1=f*(src_image.ni()-1)*1.0/(n1-1);
00231   double dy1=0;
00232   double dx2=0;
00233   double dy2=f*(src_image.nj()-1)*1.0/(n2-1);
00234   vil_resample_bicub( src_image, dest_image, x0, y0, dx1, dy1, dx2, dy2, n1, n2 );
00235 }
00236 
00237 //: Resample image to a specified width (n1) and height (n2)
00238 template <class sType, class dType>
00239 void vil_resample_bicub_edge_extend(const vil_image_view<sType>& src_image,
00240                                     vil_image_view<dType>& dest_image,
00241                                     int n1, int n2)
00242 {
00243   double f= 1.0; // so sampler doesn't go off edge of image
00244   double x0=0;
00245   double y0=0;
00246   double dx1=f*(src_image.ni()-1)*1.0/(n1-1);
00247   double dy1=0;
00248   double dx2=0;
00249   double dy2=f*(src_image.nj()-1)*1.0/(n2-1);
00250   vil_resample_bicub_edge_extend( src_image, dest_image, x0, y0, dx1, dy1, dx2, dy2, n1, n2 );
00251 }
00252 
00253 #define VIL_RESAMPLE_BICUB_INSTANTIATE( sType, dType ) \
00254 template void vil_resample_bicub(const vil_image_view<sType >& src_image, \
00255                                  vil_image_view<dType >& dest_image, \
00256                                  double x0, double y0, double dx1, double dy1, \
00257                                  double dx2, double dy2, int n1, int n2); \
00258 template void vil_resample_bicub(const vil_image_view<sType >& src_image, \
00259                                  vil_image_view<dType >& dest_image, \
00260                                  int n1, int n2); \
00261 template void vil_resample_bicub_edge_extend(const vil_image_view<sType >& src_image, \
00262                                              vil_image_view<dType >& dest_image, \
00263                                              double x0, double y0, double dx1, double dy1, \
00264                                              double dx2, double dy2, int n1, int n2); \
00265 template void vil_resample_bicub_edge_extend(const vil_image_view<sType >& src_image, \
00266                                              vil_image_view<dType >& dest_image, \
00267                                              int n1, int n2)
00268 
00269 #endif // vil_resample_bicub_txx_