ldpk
ldpk_lookup_table.h
Go to the documentation of this file.
1 #ifndef ldpk_lookup_table_sdv
2 #define ldpk_lookup_table_sdv
3 
4 #include <vector>
5 #include <iostream>
6 
8 
9 namespace ldpk
10  {
12  template <class VEC2>
14  {
15  public:
19  typedef VEC2 vec2_type;
20  private:
22  struct sample_type
23  {
24  bool done;
25  vec2_type value;
26  sample_type():done(false)
27  { }
28  };
29 
30  typedef typename std::vector<sample_type> samples_type;
31 
32  samples_type _samples;
33  int _nx,_ny;
34  vec2_type _lc_fov;
35 // Index nearest to lc.
36  int _ix_lc,_iy_lc;
37 // Counter for the paint algorithm.
38  int _k;
39 // Current index in paint algorithm.
40  int _ix_current,_iy_current;
41 
42  void clip_index(int& ix,int& iy) const
43  {
44  if(ix < 0) ix = 0;
45  if(ix >= _nx) ix = _nx - 1;
46  if(iy < 0) iy = 0;
47  if(iy >= _ny) iy = _ny - 1;
48  }
49  const sample_type& get_sample(int ix,int iy) const
50  { return _samples.at(ix + _nx * iy); }
51  sample_type& get_sample(int ix,int iy)
52  { return _samples.at(ix + _nx * iy); }
54  void calc_index(const vec2_type& p_fov,int& ix,int& iy) const
55  {
56  vec2_type p_ext = (1.0/1.5) * (p_fov + vec2_type(0.25,0.25));
57  ix = int(floor(p_ext[0] * (_nx - 1) + 0.5));
58  iy = int(floor(p_ext[1] * (_ny - 1) + 0.5));
59  }
61  vec2_type calc_position(int ix,int iy) const
62  {
63  vec2_type p_ext(double(ix) / (_nx - 1),double(iy) / (_ny - 1));
64  return (1.5) * p_ext - vec2_type(0.25,0.25);
65  }
66  public:
68 // @{
69  lookup_table():_nx(0),_ny(0),_lc_fov(.5,.5)
70  { }
72  void init(int nx,int ny)
73  {
74  _nx = nx;
75  _ny = ny;
76  _samples.resize(_nx * _ny);
77  reset();
78  }
82  void set_lens_center_fov(const vec2_type& lc_fov)
83  {
84  _lc_fov = lc_fov;
85  }
86 // @}
87 
96 // @{
98  void reset();
100  bool next();
102  int get_ix_current() const
103  { return _ix_current; }
105  int get_iy_current() const
106  { return _iy_current; }
109  vec2_type get_p_current_fov() const
110  { return calc_position(_ix_current,_iy_current); }
112  vec2_type get_current_initial_value() const;
115  void set_q_current_fov(const vec2_type& q_fov)
116  { _samples.at(_ix_current + _nx * _iy_current).value = q_fov; }
117 // @}
118 
124 // @{
126  const vec2_type& get_value(int ix,int iy) const
127  {
128  return _samples.at(ix + _nx * iy).value;
129  }
133  const vec2_type& get_value(const vec2_type& p_fov) const
134  {
135  int ix,iy;
136  calc_index(p_fov,ix,iy);
137  clip_index(ix,iy);
138  return _samples[ix + _nx * iy].value;
139  }
142  const vec2_type& get_initial_value(const vec2_type& p_fov) const
143  {
144  return get_value(p_fov);
145  }
146 // @}
147 
149 // @{
151  std::ostream& out_state(std::ostream& cout) const
152  {
153  for(int iy = _ny - 1;iy >= 0;--iy)
154  {
155  for(int ix = 0;ix < _nx;++ix)
156  {
157  if((ix == _ix_current) && (iy == _iy_current))
158  {
159  cout << 'o';
160  }
161  else
162  {
163  cout << (get_sample(ix,iy).done ? '*' : '.');
164  }
165  }
166  cout << std::endl;
167  }
168  return cout;
169  }
172  std::ostream& out_gnuplot(std::ostream& cout) const
173  {
174  for(int iy = 0;iy < _ny;++iy)
175  {
176  for(int ix = 0;ix < _nx;++ix)
177  {
178  vec2_type p,q,d;
179  p = calc_position(ix,iy);
180  q = get_value(ix,iy);
181  d = q - p;
182  cout << p[0] << " " << p[1] << " " << d[0] << " " << d[1] << std::endl;
183  }
184  }
185  return cout;
186  }
187 // @}
188  };
189 
190  template <class VEC2>
192  {
193  for(typename samples_type::iterator i = _samples.begin();i != _samples.end();++i)
194  {
195  i->done = false;
196  }
197 // Reset counter
198  _k = 0;
199 // Calculate index of Lens Center
200  calc_index(_lc_fov,_ix_lc,_iy_lc);
201  }
202  template <class VEC2>
204  {
205 // Each position painted
206  if(_k >= _samples.size()) return false;
207 
208  int kx = _k % _nx;
209  if(kx <= _ix_lc)
210  {
211 // going left
212  _ix_current = _ix_lc - kx;
213  }
214  else
215  {
216 // going right
217  _ix_current = _ix_lc + (kx - _ix_lc);
218  }
219  int ky = _k / _nx;
220  if(ky <= _iy_lc)
221  {
222 // going down
223  _iy_current = _iy_lc - ky;
224  }
225  else
226  {
227 // going up
228  _iy_current = _iy_lc + (ky - _iy_lc);
229  }
230  get_sample(_ix_current,_iy_current).done = true;
231  ++_k;
232  return true;
233  }
234  template <class VEC2>
236  {
237  if(_iy_current == _iy_lc)
238  {
239  if(_ix_current == _ix_lc)
240  {
241  return calc_position(_ix_current,_iy_current);
242  }
243  else if(_ix_current < _ix_lc)
244  {
245  return get_value(_ix_current + 1,_iy_current);
246  }
247  else
248  {
249  return get_value(_ix_current - 1,_iy_current);
250  }
251  }
252  else if(_iy_current < _iy_lc)
253  {
254  return get_value(_ix_current,_iy_current + 1);
255  }
256  else
257  {
258  return get_value(_ix_current,_iy_current - 1);
259  }
260  }
261  }
262 
263 #endif
int get_iy_current() const
Current y-position while painting.
Definition: ldpk_lookup_table.h:105
bool next()
False means no value to be generated, loop is done. See example.
Definition: ldpk_lookup_table.h:203
Use your own two-dimensional double-valued vector type as VEC2.
Definition: ldpk_lookup_table.h:13
std::ostream & out_state(std::ostream &cout) const
Visualizing the paint algo for debugging purposes.
Definition: ldpk_lookup_table.h:151
const vec2_type & get_initial_value(const vec2_type &p_fov) const
Currently same as get_value(), but we might add more sophisticated methods to generate an initial val...
Definition: ldpk_lookup_table.h:142
The namespace of (most of the) things related to the Lens Distortion Plugin Kit.
Definition: ldpk.h:180
VEC2 vec2_type
Your two-dimensional double-valued vector type.
Definition: ldpk_lookup_table.h:19
lookup_table< VEC2 > this_type
This class.
Definition: ldpk_lookup_table.h:17
int get_ix_current() const
Current x-position while painting.
Definition: ldpk_lookup_table.h:102
void reset()
Use reset() and next() to build a loop for generating positions. See example.
Definition: ldpk_lookup_table.h:191
const vec2_type & get_value(const vec2_type &p_fov) const
Once you have built the lookup table, use this method to extract an initial value from lookup table f...
Definition: ldpk_lookup_table.h:133
void init(int nx, int ny)
Initialize a grid with nx * ny sample points. Implies reset().
Definition: ldpk_lookup_table.h:72
vec2_type get_current_initial_value() const
Appropriate initial value for calculating warp at current position obtained with get_p_current_fov()...
Definition: ldpk_lookup_table.h:235
const vec2_type & get_value(int ix, int iy) const
Direct access to table data, raises exception if index is out of bounds.
Definition: ldpk_lookup_table.h:126
void set_lens_center_fov(const vec2_type &lc_fov)
Lens Center in normalized FOV-coordinates. LC is the fixed point of all distortion models...
Definition: ldpk_lookup_table.h:82
vec2_type get_p_current_fov() const
Current position in normalized FOV-coordinates. This is the position you want to warp next...
Definition: ldpk_lookup_table.h:109
std::ostream & out_gnuplot(std::ostream &cout) const
Output as a vector field for gnuplot Use command "plot &#39;test.i&#39; with vector" or similar in gnuplot...
Definition: ldpk_lookup_table.h:172
void set_q_current_fov(const vec2_type &q_fov)
Set value for given index pair. Index pairs out of bounds will raise an exception. Use this method to insert the warped position from warping p_current_fov.
Definition: ldpk_lookup_table.h:115