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