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 <vil/vil_fwd.h>
00017 
00018 //: Compute nearest neighbour interpolation at (x,y), no bound checks. Requires -0.5<x<ni-0.5, -0.5<y<nj-0.5
00019 //  Image is nx * ny array of Ts. x,y element is data[xstep*x+ystep*y]
00020 //  No bound checks are done.
00021 template<class T>
00022 inline T vil_nearest_interp_unsafe(double x, double y, const T* data,
00023                                    int /*nx*/, int /*ny*/,
00024                                    vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00025 {
00026   int ix = int(x + 0.5);
00027   int iy = int(y + 0.5);
00028   return *(data + ix*xstep + iy*ystep);
00029 }
00030 
00031 
00032 //: Compute nearest neighbour interpolation at (x,y), no bound checks. Requires -0.5<=x<ni-0.5, -0.5<=y<nj-0.5
00033 //  No bound checks are done.
00034 //  \relatesalso vil_image_view
00035 template<class T>
00036 inline T vil_nearest_interp_unsafe(const vil_image_view<T>& view, double x, double y, unsigned p=0)
00037 {
00038   return vil_nearest_interp_unsafe(x, y, &view(0,0,p), 0, 0, view.istep(), view.jstep());
00039 }
00040 
00041 //: Compute nearest neighbour interpolation at (x,y), with bound checks
00042 //  If (x,y) is outside interpolatable image region, zero is returned.
00043 //  The safe interpolatable region is [-0.5,view.ni()-0.5)*[0,view.nj()-0.5).
00044 template<class T>
00045 inline T vil_nearest_interp_safe(double x, double y, const T* data,
00046                                  int nx, int ny,
00047                                  vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00048 {
00049   int ix = int(x + 0.5);
00050   int iy = int(y + 0.5);
00051   if (ix >= 0 && ix < nx && iy >= 0 && iy < ny)
00052     return *(data + ix*xstep + iy*ystep);
00053   else
00054     return 0;
00055 }
00056 
00057 
00058 //: Compute nearest neighbour interpolation at (x,y), with bound checks
00059 //  If (x,y) is outside interpolatable image region, zero is returned.
00060 //  The safe interpolatable region is [-0.5,view.ni()-0.5)*[0,view.nj()-0.5).
00061 // \relatesalso vil_image_view
00062 template<class T>
00063 inline T vil_nearest_interp_safe(
00064   const vil_image_view<T> &view, double x, double y, unsigned p=0)
00065 {
00066   return vil_nearest_interp_safe(x, y, &view(0,0,p), view.ni(), view.nj(),
00067                                  view.istep(), view.jstep());
00068 }
00069 
00070 
00071 //: Compute nearest neighbour interpolation at (x,y), with minimal bound checks
00072 //  Image is nx * ny array of Ts. x,y element is data[ystep*y+xstep*x]
00073 //  If (x,y) is outside interpolatable image region and NDEBUG is not defined
00074 //  the code will fail an ASSERT.
00075 //  The safe interpolatable region is [-0.5,view.ni()-0.5)*[0.5,view.nj()-0.5).
00076 template<class T>
00077 inline T vil_nearest_interp(double x, double y, const T* data,
00078                             int nx, int ny,
00079                             vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00080 {
00081   int ix = int(x + 0.5);
00082   int iy = int(y + 0.5);
00083   assert (ix>=0);
00084   assert (iy>=0);
00085   assert (ix<nx);
00086   assert (iy<ny);
00087   return *(data + ix*xstep + iy*ystep);
00088 }
00089 
00090 
00091 //: Compute nearest neighbour interpolation at (x,y), with minimal bound checks
00092 //  If (x,y) is outside interpolatable image region and NDEBUG is not defined
00093 //  the code will fail an ASSERT.
00094 //  The safe interpolatable region is [-0.5,view.ni()-0.5)*[0.5,view.nj()-0.5).
00095 // \relatesalso vil_image_view
00096 template<class T>
00097 inline T vil_nearest_interp(
00098   const vil_image_view<T> &view, double x, double y, unsigned p=0)
00099 {
00100   return vil_nearest_interp(x, y, &view(0,0,p), view.ni(), view.nj(),
00101                             view.istep(), view.jstep());
00102 }
00103 
00104 
00105 //: Compute nearest_neighbourear interpolation at (x,y), with bound checks
00106 //  Image is nx * ny array of Ts. x,y element is data[ystep*y+xstep*x]
00107 //  If (x,y) is outside safe interpolatable image region, nearest pixel value is returned.
00108 //  The safe interpolatable region is [-0.5,view.ni()-0.5)*[-0.5,view.nj()-0.5).
00109 template<class T>
00110 inline T vil_nearest_interp_safe_extend(double x, double y, const T* data,
00111                                         int nx, int ny,
00112                                         vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00113 {
00114   int ix = int(x + 0.5);
00115   int iy = int(y + 0.5);
00116   if (ix<0)
00117     ix= 0;
00118   else
00119     if (ix>=nx) ix=nx;
00120 
00121   if (iy<0)
00122     iy= 0;
00123   else
00124     if (iy>=ny) iy=ny;
00125 
00126   return *(data + ix*xstep + iy*ystep);
00127 }
00128 
00129 
00130 //: Compute nearest_neighbourear interpolation at (x,y), with bound checks
00131 //  If (x,y) is outside safe interpolatable image region, nearest pixel value is returned.
00132 //  The safe interpolatable region is [-0.5,view.ni()-0.5)*[-0.5,view.nj()-0.5).
00133 // \relatesalso vil_image_view
00134 template<class T>
00135 inline T vil_nearest_interp_safe_extend(
00136   const vil_image_view<T> &view, double x, double y, unsigned p=0)
00137 {
00138   int ix = int(x + 0.5);
00139   int iy = int(y + 0.5);
00140   if (ix<0)
00141     ix= 0.0;
00142   else
00143     if (ix>=(int)view.ni()) ix=view.ni()-1;
00144 
00145   if (iy<0)
00146     iy= 0.0;
00147   else
00148     if (iy>=(int)view.nj()) iy=view.nj()-1;
00149 
00150   return view(ix, iy, p);
00151 }
00152 
00153 #endif // vil_nearest_interp_h_