vil_nearest_interp.h
Go to the documentation of this file.
1 // This is core/vil/vil_nearest_interp.h
2 #ifndef vil_nearest_interp_h_
3 #define vil_nearest_interp_h_
4 //:
5 // \file
6 // \brief nearest neighbour interpolation functions for 2D images
7 // \author Ian Scott
8 //
9 // The vil_nearest_neighbour_interp source files were derived from the corresponding
10 // vil_bilin_interp files, thus the bilin/nearest_neighbour/bicub source files are very
11 // similar. If you modify something in this file, there is a
12 // corresponding bicub and bilin files that would likely also benefit from
13 // the same change.
14 
15 #include <cstddef>
16 #include <cassert>
17 #ifdef _MSC_VER
18 # include <vcl_msvc_warnings.h>
19 #endif
20 #include <vil/vil_fwd.h>
21 
22 //: Compute nearest neighbour interpolation at (x,y), no bound checks. Requires -0.5<x<ni-0.5, -0.5<y<nj-0.5
23 // Image is nx * ny array of Ts. x,y element is data[xstep*x+ystep*y]
24 // No bound checks are done.
25 template<class T>
26 inline T vil_nearest_interp_unsafe(double x, double y, const T* data,
27  int /*nx*/, int /*ny*/,
28  std::ptrdiff_t xstep, std::ptrdiff_t ystep)
29 {
30  int ix = int(x + 0.5);
31  int iy = int(y + 0.5);
32  return *(data + ix*xstep + iy*ystep);
33 }
34 
35 
36 //: Compute nearest neighbour interpolation at (x,y), no bound checks. Requires -0.5<=x<ni-0.5, -0.5<=y<nj-0.5
37 // No bound checks are done.
38 // \relatesalso vil_image_view
39 template<class T>
40 inline T vil_nearest_interp_unsafe(const vil_image_view<T>& view, double x, double y, unsigned p=0)
41 {
42  return vil_nearest_interp_unsafe(x, y, &view(0,0,p), 0, 0, view.istep(), view.jstep());
43 }
44 
45 //: Compute nearest neighbour interpolation at (x,y), with bound checks
46 // If (x,y) is outside interpolatable image region, zero is returned.
47 // The safe interpolatable region is [-0.5,view.ni()-0.5)*[0,view.nj()-0.5).
48 template<class T>
49 inline T vil_nearest_interp_safe(double x, double y, const T* data,
50  int nx, int ny,
51  std::ptrdiff_t xstep, std::ptrdiff_t ystep)
52 {
53  int ix = int(x + 0.5);
54  int iy = int(y + 0.5);
55  if (ix >= 0 && ix < nx && iy >= 0 && iy < ny)
56  return *(data + ix*xstep + iy*ystep);
57  else
58  return 0;
59 }
60 
61 
62 //: Compute nearest neighbour interpolation at (x,y), with bound checks
63 // If (x,y) is outside interpolatable image region, zero is returned.
64 // The safe interpolatable region is [-0.5,view.ni()-0.5)*[0,view.nj()-0.5).
65 // \relatesalso vil_image_view
66 template<class T>
68  const vil_image_view<T> &view, double x, double y, unsigned p=0)
69 {
70  return vil_nearest_interp_safe(x, y, &view(0,0,p), view.ni(), view.nj(),
71  view.istep(), view.jstep());
72 }
73 
74 
75 //: Compute nearest neighbour interpolation at (x,y), with minimal bound checks
76 // Image is nx * ny array of Ts. x,y element is data[ystep*y+xstep*x]
77 // If (x,y) is outside interpolatable image region and NDEBUG is not defined
78 // the code will fail an ASSERT.
79 // The safe interpolatable region is [-0.5,view.ni()-0.5)*[0.5,view.nj()-0.5).
80 template<class T>
81 inline T vil_nearest_interp(double x, double y, const T* data,
82  int nx, int ny,
83  std::ptrdiff_t xstep, std::ptrdiff_t ystep)
84 {
85  int ix = int(x + 0.5);
86  int iy = int(y + 0.5);
87  assert (ix>=0);
88  assert (iy>=0);
89  assert (ix<nx);
90  assert (iy<ny);
91  return *(data + ix*xstep + iy*ystep);
92 }
93 
94 
95 //: Compute nearest neighbour interpolation at (x,y), with minimal bound checks
96 // If (x,y) is outside interpolatable image region and NDEBUG is not defined
97 // the code will fail an ASSERT.
98 // The safe interpolatable region is [-0.5,view.ni()-0.5)*[0.5,view.nj()-0.5).
99 // \relatesalso vil_image_view
100 template<class T>
102  const vil_image_view<T> &view, double x, double y, unsigned p=0)
103 {
104  return vil_nearest_interp(x, y, &view(0,0,p), view.ni(), view.nj(),
105  view.istep(), view.jstep());
106 }
107 
108 
109 //: Compute nearest neighbour interpolation at (x,y), with bound checks
110 // Image is nx * ny array of Ts. x,y element is data[ystep*y+xstep*x]
111 // If (x,y) is outside safe interpolatable image region, nearest pixel value is returned.
112 // The safe interpolatable region is [-0.5,view.ni()-0.5)*[-0.5,view.nj()-0.5).
113 template<class T>
114 inline T vil_nearest_interp_safe_extend(double x, double y, const T* data,
115  int nx, int ny,
116  std::ptrdiff_t xstep, std::ptrdiff_t ystep)
117 {
118  int ix = int(x + 0.5);
119  int iy = int(y + 0.5);
120  if (ix<0)
121  ix= 0;
122  else
123  if (ix>=nx) ix=nx;
124 
125  if (iy<0)
126  iy= 0;
127  else
128  if (iy>=ny) iy=ny;
129 
130  return *(data + ix*xstep + iy*ystep);
131 }
132 
133 
134 //: Compute nearest neighbour interpolation at (x,y), with bound checks
135 // If (x,y) is outside safe interpolatable image region, nearest pixel value is returned.
136 // The safe interpolatable region is [-0.5,view.ni()-0.5)*[-0.5,view.nj()-0.5).
137 // \relatesalso vil_image_view
138 template<class T>
140  const vil_image_view<T> &view, double x, double y, unsigned p=0)
141 {
142  int ix = int(x + 0.5);
143  int iy = int(y + 0.5);
144  if (ix<0)
145  ix= 0.0;
146  else
147  if (ix>=(int)view.ni()) ix=view.ni()-1;
148 
149  if (iy<0)
150  iy= 0.0;
151  else
152  if (iy>=(int)view.nj()) iy=view.nj()-1;
153 
154  return view(ix, iy, p);
155 }
156 
157 #endif // vil_nearest_interp_h_
Concrete view of image data of type T held in memory.
Definition: vil_fwd.h:13
T vil_nearest_interp_unsafe(const vil_image_view< T > &view, double x, double y, unsigned p=0)
Compute nearest neighbour interpolation at (x,y), no bound checks. Requires -0.5<=x<ni-0....
std::ptrdiff_t jstep() const
Add this to your pixel pointer to get next j pixel.
unsigned ni() const
Width.
unsigned nj() const
Height.
T vil_nearest_interp_safe_extend(const vil_image_view< T > &view, double x, double y, unsigned p=0)
Compute nearest neighbour interpolation at (x,y), with bound checks.
T vil_nearest_interp(const vil_image_view< T > &view, double x, double y, unsigned p=0)
Compute nearest neighbour interpolation at (x,y), with minimal bound checks.
T vil_nearest_interp_safe(const vil_image_view< T > &view, double x, double y, unsigned p=0)
Compute nearest neighbour interpolation at (x,y), with bound checks.
std::ptrdiff_t istep() const
Add this to your pixel pointer to get next i pixel.