core/vil/vil_nearest_interp.h
Go to the documentation of this file.
00001 // This is core/vil/vil_nearest_interp.h
00002 #ifndef vil_nearest_interp_h_
00003 #define vil_nearest_interp_h_
00004 //:
00005 // \file
00006 // \brief nearest neighbour interpolation functions for 2D images
00007 // \author Ian Scott
00008 //
00009 // The vil_nearest_neighbour_interp source files were derived from the corresponding
00010 // vil_bilin_interp files, thus the bilin/nearest_neighbour/bicub source files are very
00011 // similar.  If you modify something in this file, there is a
00012 // corresponding bicub and bilin files that would likely also benefit from
00013 // the same change.
00014 
00015 #include <vcl_cassert.h>
00016 #include <vcl_cstddef.h>
00017 #include <vil/vil_fwd.h>
00018 
00019 //: Compute nearest neighbour interpolation at (x,y), no bound checks. Requires -0.5<x<ni-0.5, -0.5<y<nj-0.5
00020 //  Image is nx * ny array of Ts. x,y element is data[xstep*x+ystep*y]
00021 //  No bound checks are done.
00022 template<class T>
00023 inline T vil_nearest_interp_unsafe(double x, double y, const T* data,
00024                                    int /*nx*/, int /*ny*/,
00025                                    vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00026 {
00027   int ix = int(x + 0.5);
00028   int iy = int(y + 0.5);
00029   return *(data + ix*xstep + iy*ystep);
00030 }
00031 
00032 
00033 //: Compute nearest neighbour interpolation at (x,y), no bound checks. Requires -0.5<=x<ni-0.5, -0.5<=y<nj-0.5
00034 //  No bound checks are done.
00035 //  \relatesalso vil_image_view
00036 template<class T>
00037 inline T vil_nearest_interp_unsafe(const vil_image_view<T>& view, double x, double y, unsigned p=0)
00038 {
00039   return vil_nearest_interp_unsafe(x, y, &view(0,0,p), 0, 0, view.istep(), view.jstep());
00040 }
00041 
00042 //: Compute nearest neighbour interpolation at (x,y), with bound checks
00043 //  If (x,y) is outside interpolatable image region, zero is returned.
00044 //  The safe interpolatable region is [-0.5,view.ni()-0.5)*[0,view.nj()-0.5).
00045 template<class T>
00046 inline T vil_nearest_interp_safe(double x, double y, const T* data,
00047                                  int nx, int ny,
00048                                  vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00049 {
00050   int ix = int(x + 0.5);
00051   int iy = int(y + 0.5);
00052   if (ix >= 0 && ix < nx && iy >= 0 && iy < ny)
00053     return *(data + ix*xstep + iy*ystep);
00054   else
00055     return 0;
00056 }
00057 
00058 
00059 //: Compute nearest neighbour interpolation at (x,y), with bound checks
00060 //  If (x,y) is outside interpolatable image region, zero is returned.
00061 //  The safe interpolatable region is [-0.5,view.ni()-0.5)*[0,view.nj()-0.5).
00062 // \relatesalso vil_image_view
00063 template<class T>
00064 inline T vil_nearest_interp_safe(
00065   const vil_image_view<T> &view, double x, double y, unsigned p=0)
00066 {
00067   return vil_nearest_interp_safe(x, y, &view(0,0,p), view.ni(), view.nj(),
00068                                  view.istep(), view.jstep());
00069 }
00070 
00071 
00072 //: Compute nearest neighbour interpolation at (x,y), with minimal bound checks
00073 //  Image is nx * ny array of Ts. x,y element is data[ystep*y+xstep*x]
00074 //  If (x,y) is outside interpolatable image region and NDEBUG is not defined
00075 //  the code will fail an ASSERT.
00076 //  The safe interpolatable region is [-0.5,view.ni()-0.5)*[0.5,view.nj()-0.5).
00077 template<class T>
00078 inline T vil_nearest_interp(double x, double y, const T* data,
00079                             int nx, int ny,
00080                             vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00081 {
00082   int ix = int(x + 0.5);
00083   int iy = int(y + 0.5);
00084   assert (ix>=0);
00085   assert (iy>=0);
00086   assert (ix<nx);
00087   assert (iy<ny);
00088   return *(data + ix*xstep + iy*ystep);
00089 }
00090 
00091 
00092 //: Compute nearest neighbour interpolation at (x,y), with minimal bound checks
00093 //  If (x,y) is outside interpolatable image region and NDEBUG is not defined
00094 //  the code will fail an ASSERT.
00095 //  The safe interpolatable region is [-0.5,view.ni()-0.5)*[0.5,view.nj()-0.5).
00096 // \relatesalso vil_image_view
00097 template<class T>
00098 inline T vil_nearest_interp(
00099   const vil_image_view<T> &view, double x, double y, unsigned p=0)
00100 {
00101   return vil_nearest_interp(x, y, &view(0,0,p), view.ni(), view.nj(),
00102                             view.istep(), view.jstep());
00103 }
00104 
00105 
00106 //: Compute nearest neighbour interpolation at (x,y), with bound checks
00107 //  Image is nx * ny array of Ts. x,y element is data[ystep*y+xstep*x]
00108 //  If (x,y) is outside safe interpolatable image region, nearest pixel value is returned.
00109 //  The safe interpolatable region is [-0.5,view.ni()-0.5)*[-0.5,view.nj()-0.5).
00110 template<class T>
00111 inline T vil_nearest_interp_safe_extend(double x, double y, const T* data,
00112                                         int nx, int ny,
00113                                         vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00114 {
00115   int ix = int(x + 0.5);
00116   int iy = int(y + 0.5);
00117   if (ix<0)
00118     ix= 0;
00119   else
00120     if (ix>=nx) ix=nx;
00121 
00122   if (iy<0)
00123     iy= 0;
00124   else
00125     if (iy>=ny) iy=ny;
00126 
00127   return *(data + ix*xstep + iy*ystep);
00128 }
00129 
00130 
00131 //: Compute nearest neighbour interpolation at (x,y), with bound checks
00132 //  If (x,y) is outside safe interpolatable image region, nearest pixel value is returned.
00133 //  The safe interpolatable region is [-0.5,view.ni()-0.5)*[-0.5,view.nj()-0.5).
00134 // \relatesalso vil_image_view
00135 template<class T>
00136 inline T vil_nearest_interp_safe_extend(
00137   const vil_image_view<T> &view, double x, double y, unsigned p=0)
00138 {
00139   int ix = int(x + 0.5);
00140   int iy = int(y + 0.5);
00141   if (ix<0)
00142     ix= 0.0;
00143   else
00144     if (ix>=(int)view.ni()) ix=view.ni()-1;
00145 
00146   if (iy<0)
00147     iy= 0.0;
00148   else
00149     if (iy>=(int)view.nj()) iy=view.nj()-1;
00150 
00151   return view(ix, iy, p);
00152 }
00153 
00154 #endif // vil_nearest_interp_h_