vil_bilin_interp.h
Go to the documentation of this file.
1 // This is core/vil/vil_bilin_interp.h
2 #ifndef vil_bilin_interp_h_
3 #define vil_bilin_interp_h_
4 //:
5 // \file
6 // \brief Bilinear interpolation functions for 2D images
7 // \author Tim Cootes
8 //
9 // The vil bicub source files were derived from the corresponding
10 // vil bilin files, thus the vil bilin/bicub source files are very
11 // similar. If you modify something in this file, there is a
12 // corresponding bicub file 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_image_view.h>
21 #include <vil/vil_na.h>
22 
23 //: Compute bilinear interpolation at (x,y), no bound checks. Requires 0<x<ni-2, 0<y<nj-2
24 // Image is nx * ny array of Ts. x,y element is data[xstep*x+ystep*y]
25 // No bound checks are done.
26 template<class T>
27 inline double vil_bilin_interp_unsafe(double x, double y, const T* data,
28  std::ptrdiff_t xstep, std::ptrdiff_t ystep)
29 {
30  int p1x=int(x);
31  double normx = x-p1x;
32  int p1y=int(y);
33  double normy = y-p1y;
34 
35  const T* pix1 = data + p1y*ystep + p1x*xstep;
36 
37  double i1 = pix1[0 ]+(pix1[ ystep]-pix1[0 ])*normy;
38  double i2 = pix1[xstep]+(pix1[xstep+ystep]-pix1[xstep])*normy;
39 
40  return i1+(i2-i1)*normx;
41 }
42 
43 
44 //: Compute bilinear interpolation at (x,y), no bound checks. Requires 0<x<ni-2, 0<y<nj-2
45 // Image is nx * ny array of Ts. x,y element is data[xstep*x+ystep*y]
46 // No bound checks are done.
47 // This is a version of vil_bilin_interp_unsafe with the same function
48 // signature as vil_bilin_interp_safe.
49 template<class T>
50 inline double vil_bilin_interp_unsafe(double x, double y, const T* data,
51  int /*nx*/, int /*ny*/,
52  std::ptrdiff_t xstep, std::ptrdiff_t ystep)
53 {
54  return vil_bilin_interp_unsafe(x, y, data, xstep, ystep);
55 }
56 
57 //: Compute bilinear interpolation at (x,y), no bound checks
58 // Image is nx * ny array of Ts. x,y element is data[xstep*x+ystep*y]
59 // No bound checks are done.
60 template<class T>
61 inline double vil_bilin_interp_raw(double x, double y, const T* data,
62  std::ptrdiff_t xstep, std::ptrdiff_t ystep)
63 {
64  int p1x=int(x);
65  double normx = x-p1x;
66  int p1y=int(y);
67  double normy = y-p1y;
68 
69  const T* pix1 = data + p1y*ystep + p1x*xstep;
70 
71  // special boundary cases can be handled more quickly first;
72  // also avoids accessing an invalid pix1[t] which is going to have weight 0.
73  if (normx == 0 && normy == 0) return pix1[0];
74  if (normx == 0) return pix1[0]+(pix1[ystep]-pix1[0])*normy;
75  if (normy == 0) return pix1[0]+(pix1[xstep]-pix1[0])*normx;
76 
77  double i1 = pix1[0 ]+(pix1[ ystep]-pix1[0 ])*normy;
78  double i2 = pix1[xstep]+(pix1[xstep+ystep]-pix1[xstep])*normy;
79 
80  return i1+(i2-i1)*normx;
81 }
82 
83 //: Compute bilinear interpolation at (x,y), no bound checks.
84 // Image is nx * ny array of Ts. x,y element is data[xstep*x+ystep*y]
85 // No bound checks are done.
86 // This is a version of vil_bilin_interp_raw with the same function
87 // signature as vil_bilin_interp_safe.
88 template<class T>
89 inline double vil_bilin_interp_raw(double x, double y, const T* data,
90  int /*nx*/, int /*ny*/,
91  std::ptrdiff_t xstep, std::ptrdiff_t ystep)
92 {
93  return vil_bilin_interp_raw(x, y, data, xstep, ystep);
94 }
95 
96 //: Compute bilinear interpolation at (x,y), with bound checks
97 // Image is nx * ny array of Ts. x,y element is data[xstep*x+ystep*y]
98 // If (x,y) is outside interpolatable image region, zero is returned.
99 // The safe interpolatable region is [0,nx-1]*[0,ny-1].
100 template<class T>
101 inline double vil_bilin_interp_safe(double x, double y, const T* data,
102  int nx, int ny,
103  std::ptrdiff_t xstep, std::ptrdiff_t ystep)
104 {
105  if (x<0) return 0.0;
106  if (y<0) return 0.0;
107  if (x>nx-1) return 0.0;
108  if (y>ny-1) return 0.0;
109  return vil_bilin_interp_raw(x,y,data,xstep,ystep);
110 }
111 
112 
113 //: Compute bilinear interpolation at (x,y), with bound checks
114 // Image is nx * ny array of Ts. x,y element is data[xstep*x+ystep*y]
115 // If (x,y) is outside interpolatable image region, NA is returned.
116 // The safe interpolatable region is [0,nx-1]*[0,ny-1].
117 template<class T>
118 inline double vil_bilin_interp_safe_edgena(double x, double y, const T* data,
119  int nx, int ny,
120  std::ptrdiff_t xstep, std::ptrdiff_t ystep)
121 {
122  if (x<0 || y<0 || x>nx-1 || y>ny-1) return vil_na(double());
123  return vil_bilin_interp_raw(x,y,data,xstep,ystep);
124 }
125 
126 //: Compute bilinear interpolation at (x,y), with bound checks
127 // If (x,y) is outside interpolatable image region, zero is returned.
128 // The safe interpolatable region is [0,view.ni()-1]*[0,view.nj()-1].
129 // \relatesalso vil_image_view
130 template<class T>
131 inline double vil_bilin_interp_safe(const vil_image_view<T> &view,
132  double x, double y, unsigned p=0)
133 {
134  return vil_bilin_interp_safe(x, y, &view(0,0,p),
135  view.ni(), view.nj(),
136  view.istep(), view.jstep());
137 }
138 
139 
140 //: Compute bilinear interpolation at (x,y), with bound checks
141 // If (x,y) is outside interpolatable image region, NA is returned.
142 // The safe interpolatable region is [0,view.ni()-1]*[0,view.nj()-1].
143 // \relatesalso vil_image_view
144 template<class T>
146  double x, double y, unsigned p=0)
147 {
148  return vil_bilin_interp_safe_edgena(x, y, &view(0,0,p),
149  view.ni(), view.nj(),
150  view.istep(), view.jstep());
151 }
152 
153 //: Compute bilinear interpolation at (x,y), with minimal bound checks
154 // Image is nx * ny array of Ts. x,y element is data[ystep*y+xstep*x]
155 // If (x,y) is outside interpolatable image region and NDEBUG is not defined
156 // the code will fail an ASSERT.
157 // The safe interpolatable region is [0,nx-1]*[0,ny-1].
158 template<class T>
159 inline double vil_bilin_interp(double x, double y, const T* data,
160  int nx, int ny,
161  std::ptrdiff_t xstep, std::ptrdiff_t ystep)
162 {
163  assert (x>=0);
164  assert (y>=0);
165  assert (x<=nx-1);
166  assert (y<=ny-1);
167  return vil_bilin_interp_raw(x,y,data,xstep,ystep);
168 }
169 
170 //: Compute bilinear interpolation at (x,y), with minimal bound checks
171 // If (x,y) is outside interpolatable image region and NDEBUG is not defined
172 // the code will fail an ASSERT.
173 // The safe interpolatable region is [0,view.ni()-1]*[0,view.nj()-1].
174 // \relatesalso vil_image_view
175 template<class T>
176 inline double vil_bilin_interp(const vil_image_view<T> &view,
177  double x, double y, unsigned p=0)
178 {
179  return vil_bilin_interp(x, y, &view(0,0,p),
180  view.ni(), view.nj(),
181  view.istep(), view.jstep());
182 }
183 
184 
185 //: Compute bilinear interpolation at (x,y), with bound checks
186 // Image is nx * ny array of Ts. x,y element is data[nx*y+x]
187 // If (x,y) is outside safe interpolatable image region, nearest pixel value is returned.
188 // The safe interpolatable region is [0,nx-1]*[0,ny-1].
189 template<class T>
190 inline double vil_bilin_interp_safe_extend(double x, double y, const T* data,
191  int nx, int ny,
192  std::ptrdiff_t xstep, std::ptrdiff_t ystep)
193 {
194  if (x<0) x= 0.0;
195  if (y<0) y= 0.0;
196  if (x>nx-1) x=nx-1.0;
197  if (y>ny-1) y=ny-1.0;
198  return vil_bilin_interp_raw(x,y,data,xstep,ystep);
199 }
200 
201 //: Compute bilinear interpolation at (x,y), with bound checks
202 // If (x,y) is outside safe interpolatable image region, nearest pixel value is returned.
203 // The safe interpolatable region is [0,view.ni()-1]*[0,view.nj()-1].
204 // \relatesalso vil_image_view
205 template<class T>
207  double x, double y, unsigned p=0)
208 {
209  return vil_bilin_interp_safe_extend(x, y, &view(0,0,p),
210  view.ni(), view.nj(),
211  view.istep(), view.jstep());
212 }
213 
214 #endif // vil_bilin_interp_h_
double vil_bilin_interp(const vil_image_view< T > &view, double x, double y, unsigned p=0)
Compute bilinear interpolation at (x,y), with minimal bound checks.
Concrete view of image data of type T held in memory.
Definition: vil_fwd.h:13
double vil_na(double)
A particular qNaN to indicate not available.
Definition: vil_na.cxx:18
double vil_bilin_interp_safe(const vil_image_view< T > &view, double x, double y, unsigned p=0)
Compute bilinear interpolation at (x,y), with bound checks.
double vil_bilin_interp_safe_edgena(const vil_image_view< T > &view, double x, double y, unsigned p=0)
Compute bilinear interpolation at (x,y), with bound checks.
NA (Not Available) is a particular double NaN to represent missing data.
std::ptrdiff_t jstep() const
Add this to your pixel pointer to get next j pixel.
unsigned ni() const
Width.
unsigned nj() const
Height.
double vil_bilin_interp_safe_extend(const vil_image_view< T > &view, double x, double y, unsigned p=0)
Compute bilinear interpolation at (x,y), with bound checks.
A base class reference-counting view of some image data.
double vil_bilin_interp_raw(double x, double y, const T *data, std::ptrdiff_t xstep, std::ptrdiff_t ystep)
Compute bilinear interpolation at (x,y), no bound checks.
double vil_bilin_interp_unsafe(double x, double y, const T *data, std::ptrdiff_t xstep, std::ptrdiff_t ystep)
Compute bilinear interpolation at (x,y), no bound checks. Requires 0<x<ni-2, 0<y<nj-2.
std::ptrdiff_t istep() const
Add this to your pixel pointer to get next i pixel.