vil_sample_grid_bilin.hxx
Go to the documentation of this file.
1 // This is core/vil/vil_sample_grid_bilin.hxx
2 #ifndef vil_sample_grid_bilin_hxx_
3 #define vil_sample_grid_bilin_hxx_
4 //:
5 // \file
6 // \brief Bilinear profile sampling 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 "vil_sample_grid_bilin.h"
16 #include <vil/vil_bilin_interp.h>
17 
18 //: This function should not be the same in bicub and bilin
19 inline bool vil_grid_bilin_corner_in_image(double x0, double y0,
20  const vil_image_view_base& image)
21 {
22  return x0 >= 1
23  && y0 >= 1
24  && x0+2 <= image.ni()
25  && y0+2 <= image.nj();
26 }
27 
28 //: Sample along profile, using safe bilinear interpolation
29 // Profile points are along the line between p0 and p1 (in image co-ordinates).
30 // Vector v is resized to n*np elements, where np=image.n_planes().
31 // v[0]..v[np-1] are the values from point p
32 // Points outside image return zero.
33 template <class imType, class vecType>
34 void vil_sample_grid_bilin(vecType* v,
35  const vil_image_view<imType>& image,
36  double x0, double y0, double dx1, double dy1,
37  double dx2, double dy2, int n1, int n2)
38 {
39  bool all_in_image = vil_grid_bilin_corner_in_image(x0,y0,image)
40  && vil_grid_bilin_corner_in_image(x0+(n1-1)*dx1,y0+(n1-1)*dy1,image)
41  && vil_grid_bilin_corner_in_image(x0+(n2-1)*dx2,y0+(n2-1)*dy2,image)
42  && vil_grid_bilin_corner_in_image(x0+(n1-1)*dx1+(n2-1)*dx2,
43  y0+(n1-1)*dy1+(n2-1)*dy2,image);
44 
45  const unsigned ni = image.ni();
46  const unsigned nj = image.nj();
47  const unsigned np = image.nplanes();
48  const std::ptrdiff_t istep = image.istep();
49  const std::ptrdiff_t jstep = image.jstep();
50  const std::ptrdiff_t pstep = image.planestep();
51  double x1=x0;
52  double y1=y0;
53  const imType* plane0 = image.top_left_ptr();
54 
55  if (all_in_image)
56  {
57  if (np==1)
58  {
59  for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
60  {
61  double x=x1, y=y1; // Start of j-th row
62  for (int j=0;j<n2;++j,x+=dx2,y+=dy2,++v)
63  *v = (vecType) vil_bilin_interp(x,y,plane0,ni,nj,istep,jstep);
64  }
65  }
66  else
67  {
68  for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
69  {
70  double x=x1, y=y1; // Start of j-th row
71  for (int j=0;j<n2;++j,x+=dx2,y+=dy2)
72  {
73  for (unsigned p=0;p<np;++p,++v)
74  *v = (vecType) vil_bilin_interp(x,y,plane0+p*pstep,ni,nj,istep,jstep);
75  }
76  }
77  }
78  }
79  else
80  {
81  // Use safe interpolation
82  if (np==1)
83  {
84  for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
85  {
86  double x=x1, y=y1; // Start of j-th row
87  for (int j=0;j<n2;++j,x+=dx2,y+=dy2,++v)
88  *v = (vecType) vil_bilin_interp_safe(x,y,plane0,ni,nj,istep,jstep);
89  }
90  }
91  else
92  {
93  for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
94  {
95  double x=x1, y=y1; // Start of j-th row
96  for (int j=0;j<n2;++j,x+=dx2,y+=dy2)
97  {
98  for (unsigned p=0;p<np;++p,++v)
99  *v = (vecType) vil_bilin_interp_safe(x,y,plane0+p*pstep,ni,nj,istep,jstep);
100  }
101  }
102  }
103  }
104 }
105 
106 
107 
108 
109 //: Sample along profile, using safe bilinear interpolation
110 // Profile points are along the line between p0 and p1 (in image co-ordinates).
111 // Vector v is resized to n*np elements, where np=image.n_planes().
112 // v[0]..v[np-1] are the values from point p
113 // Points outside image return NA.
114 template <class imType, class vecType>
116  const vil_image_view<imType>& image,
117  double x0, double y0, double dx1, double dy1,
118  double dx2, double dy2, int n1, int n2)
119 {
120  bool all_in_image = vil_grid_bilin_corner_in_image(x0,y0,image)
121  && vil_grid_bilin_corner_in_image(x0+(n1-1)*dx1,y0+(n1-1)*dy1,image)
122  && vil_grid_bilin_corner_in_image(x0+(n2-1)*dx2,y0+(n2-1)*dy2,image)
123  && vil_grid_bilin_corner_in_image(x0+(n1-1)*dx1+(n2-1)*dx2,
124  y0+(n1-1)*dy1+(n2-1)*dy2,image);
125 
126  const unsigned ni = image.ni();
127  const unsigned nj = image.nj();
128  const unsigned np = image.nplanes();
129  const std::ptrdiff_t istep = image.istep();
130  const std::ptrdiff_t jstep = image.jstep();
131  const std::ptrdiff_t pstep = image.planestep();
132  double x1=x0;
133  double y1=y0;
134  const imType* plane0 = image.top_left_ptr();
135 
136  if (all_in_image)
137  {
138  if (np==1)
139  {
140  for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
141  {
142  double x=x1, y=y1; // Start of j-th row
143  for (int j=0;j<n2;++j,x+=dx2,y+=dy2,++v)
144  *v = (vecType) vil_bilin_interp(x,y,plane0,ni,nj,istep,jstep);
145  }
146  }
147  else
148  {
149  for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
150  {
151  double x=x1, y=y1; // Start of j-th row
152  for (int j=0;j<n2;++j,x+=dx2,y+=dy2)
153  {
154  for (unsigned p=0;p<np;++p,++v)
155  *v = (vecType) vil_bilin_interp(x,y,plane0+p*pstep,ni,nj,istep,jstep);
156  }
157  }
158  }
159  }
160  else
161  {
162  // Use safe interpolation
163  if (np==1)
164  {
165  for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
166  {
167  double x=x1, y=y1; // Start of j-th row
168  for (int j=0;j<n2;++j,x+=dx2,y+=dy2,++v)
169  *v = (vecType) vil_bilin_interp_safe_edgena(x,y,plane0,ni,nj,istep,jstep);
170  }
171  }
172  else
173  {
174  for (int i=0;i<n1;++i,x1+=dx1,y1+=dy1)
175  {
176  double x=x1, y=y1; // Start of j-th row
177  for (int j=0;j<n2;++j,x+=dx2,y+=dy2)
178  {
179  for (unsigned p=0;p<np;++p,++v)
180  *v = (vecType) vil_bilin_interp_safe_edgena(x,y,plane0+p*pstep,ni,nj,istep,jstep);
181  }
182  }
183  }
184  }
185 }
186 
187 #define VIL_SAMPLE_GRID_BILIN_INSTANTIATE( imType, vecType ) \
188 template void vil_sample_grid_bilin(vecType* v, \
189  const vil_image_view<imType >& image, \
190  double x0, double y0, double dx1, double dy1, \
191  double dx2, double dy2, int n1, int n2); \
192 template void vil_sample_grid_bilin_edgena(vecType* v, \
193  const vil_image_view<imType >& image, \
194  double x0, double y0, double dx1, double dy1, \
195  double dx2, double dy2, int n1, int n2)
196 
197 #endif // vil_sample_grid_bilin_hxx_
An abstract base class of smart pointers to actual image data in memory.
Bilinear grid sampling function for 2D images.
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
bool vil_grid_bilin_corner_in_image(double x0, double y0, const vil_image_view_base &image)
This function should not be the same in bicub and bilin.
void vil_sample_grid_bilin(vecType *v, const vil_image_view< imType > &image, double x0, double y0, double dx1, double dy1, double dx2, double dy2, int n1, int n2)
Sample grid from image, using bilinear interpolation.
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.
std::ptrdiff_t jstep() const
Add this to your pixel pointer to get next j pixel.
unsigned ni() const
Width.
unsigned nj() const
Height.
#define v
std::ptrdiff_t planestep() const
Add this to your pixel pointer to get pixel on next plane.
T * top_left_ptr()
Pointer to the first (top left in plane 0) pixel.
void vil_sample_grid_bilin_edgena(vecType *v, const vil_image_view< imType > &image, double x0, double y0, double dx1, double dy1, double dx2, double dy2, int n1, int n2)
Sample grid from image, using bilinear interpolation.
unsigned nplanes() const
Number of planes.
std::ptrdiff_t istep() const
Add this to your pixel pointer to get next i pixel.
Bilinear interpolation functions for 2D images.