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 inline bool vil_grid_corner_plus1_in_image(double x0, double y0,
00018                                            const vil_image_view_base& image)
00019 {
00020   return x0 >= 1
00021       && y0 >= 1
00022       && x0+2 <= image.ni()
00023       && y0+2 <= image.nj();
00024 }
00025 
00026 //: Sample grid of points in one image and place in another, using bicubic interpolation.
00027 //  dest_image(i,j,p) is sampled from the src_image at
00028 //  (x0+i.dx1+j.dx2,y0+i.dy1+j.dy2), where i=[0..n1-1], j=[0..n2-1]
00029 //  dest_image resized to (n1,n2,src_image.nplanes())
00030 //  Points outside image return zero.
00031 // \relatesalso vil_image_view
00032 template <class sType, class dType>
00033 void vil_resample_bicub(const vil_image_view<sType>& src_image,
00034                         vil_image_view<dType>& dest_image,
00035                         double x0, double y0, double dx1, double dy1,
00036                         double dx2, double dy2, int n1, int n2)
00037 {
00038   bool all_in_image =    vil_grid_corner_plus1_in_image(x0,y0,src_image)
00039                       && vil_grid_corner_plus1_in_image(x0+(n1-1)*dx1,y0+(n1-1)*dy1,src_image)
00040                       && vil_grid_corner_plus1_in_image(x0+(n2-1)*dx2,y0+(n2-1)*dy2,src_image)
00041                       && vil_grid_corner_plus1_in_image(x0+(n1-1)*dx1+(n2-1)*dx2,
00042                                                         y0+(n1-1)*dy1+(n2-1)*dy2,src_image);
00043 
00044   const unsigned ni = src_image.ni();
00045   const unsigned nj = src_image.nj();
00046   const unsigned np = src_image.nplanes();
00047   const vcl_ptrdiff_t istep = src_image.istep();
00048   const vcl_ptrdiff_t jstep = src_image.jstep();
00049   const vcl_ptrdiff_t pstep = src_image.planestep();
00050   const sType* plane0 = src_image.top_left_ptr();
00051 
00052   dest_image.set_size(n1,n2,np);
00053   const vcl_ptrdiff_t d_istep = dest_image.istep();
00054   const vcl_ptrdiff_t d_jstep = dest_image.jstep();
00055   const vcl_ptrdiff_t d_pstep = dest_image.planestep();
00056   dType* d_plane0 = dest_image.top_left_ptr();
00057 
00058   double x1=x0;
00059   double y1=y0;
00060 
00061   if (all_in_image)
00062   {
00063     if (np==1)
00064     {
00065       dType *row = d_plane0;
00066       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00067       {
00068         double x=x1, y=y1;  // Start of j-th row
00069         dType *dpt = row;
00070         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00071           *dpt = (dType) vil_bicub_interp_raw(x,y,plane0,ni,nj,istep,jstep);
00072       }
00073     }
00074     else
00075     {
00076       dType *row = d_plane0;
00077       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00078       {
00079         double x=x1, y=y1; // Start of j-th row
00080         dType *dpt = row;
00081         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00082         {
00083           for (unsigned int p=0;p<np;++p)
00084             dpt[p*d_pstep] = (dType) vil_bicub_interp_raw(x,y,plane0+p*pstep,ni,nj,istep,jstep);
00085         }
00086       }
00087     }
00088   }
00089   else
00090   {
00091     // Use safe interpolation
00092     if (np==1)
00093     {
00094       dType *row = d_plane0;
00095       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00096       {
00097         double x=x1, y=y1;  // Start of j-th row
00098         dType *dpt = row;
00099         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00100           *dpt = (dType) vil_bicub_interp_safe(x,y,plane0,
00101                                                ni,nj,istep,jstep);
00102       }
00103     }
00104     else
00105     {
00106       dType *row = d_plane0;
00107       for (int j=0;j<n2;++j,x1+=dx2,y1+=dy2,row+=d_jstep)
00108       {
00109         double x=x1, y=y1; // Start of j-th row
00110         dType *dpt = row;
00111         for (int i=0;i<n1;++i,x+=dx1,y+=dy1,dpt+=d_istep)
00112         {
00113           for (unsigned int p=0;p<np;++p)
00114             dpt[p*d_pstep] = (dType) vil_bicub_interp_safe(x,y,plane0+p*pstep,
00115                                                             ni,nj,istep,jstep);
00116         }
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_grid_corner_plus1_in_image(x0,y0,src_image)
00137                       && vil_grid_corner_plus1_in_image(x0+(n1-1)*dx1,y0+(n1-1)*dy1,src_image)
00138                       && vil_grid_corner_plus1_in_image(x0+(n2-1)*dx2,y0+(n2-1)*dy2,src_image)
00139                       && vil_grid_corner_plus1_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 
00222 //: Resample image to a specified width (n1) and height (n2)
00223 template <class sType, class dType>
00224 void vil_resample_bicub(const vil_image_view<sType>& src_image,
00225                         vil_image_view<dType>& dest_image,
00226                         int n1, int n2)
00227 {
00228   double f= 1.0; // so sampler doesn't go off edge of image
00229   double x0=0;
00230   double y0=0;
00231   double dx1=f*(src_image.ni()-1)*1.0/(n1-1);
00232   double dy1=0;
00233   double dx2=0;
00234   double dy2=f*(src_image.nj()-1)*1.0/(n2-1);
00235   vil_resample_bicub( src_image, dest_image, x0, y0, dx1, dy1, dx2, dy2, n1, n2 );
00236 }
00237 
00238 //: Resample image to a specified width (n1) and height (n2)
00239 template <class sType, class dType>
00240 void vil_resample_bicub_edge_extend(const vil_image_view<sType>& src_image,
00241                                     vil_image_view<dType>& dest_image,
00242                                     int n1, int n2)
00243 {
00244   double f= 1.0; // so sampler doesn't go off edge of image
00245   double x0=0;
00246   double y0=0;
00247   double dx1=f*(src_image.ni()-1)*1.0/(n1-1);
00248   double dy1=0;
00249   double dx2=0;
00250   double dy2=f*(src_image.nj()-1)*1.0/(n2-1);
00251   vil_resample_bicub_edge_extend( src_image, dest_image, x0, y0, dx1, dy1, dx2, dy2, n1, n2 );
00252 }
00253 
00254 #define VIL_RESAMPLE_BICUB_INSTANTIATE( sType, dType ) \
00255 template void vil_resample_bicub(const vil_image_view<sType >& src_image, \
00256                                  vil_image_view<dType >& dest_image, \
00257                                  double x0, double y0, double dx1, double dy1, \
00258                                  double dx2, double dy2, int n1, int n2); \
00259 template void vil_resample_bicub(const vil_image_view<sType >& src_image, \
00260                                  vil_image_view<dType >& dest_image, \
00261                                  int n1, int n2); \
00262 template void vil_resample_bicub_edge_extend(const vil_image_view<sType >& src_image, \
00263                                  vil_image_view<dType >& dest_image, \
00264                                  double x0, double y0, double dx1, double dy1, \
00265                                  double dx2, double dy2, int n1, int n2); \
00266 template void vil_resample_bicub_edge_extend(const vil_image_view<sType >& src_image, \
00267                                  vil_image_view<dType >& dest_image, \
00268                                  int n1, int n2)
00269 
00270 #endif // vil_resample_bicub_txx_