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  ix = int(floor(p_fov[0] * (_nx - 1) + 0.5));
57  iy = int(floor(p_fov[1] * (_ny - 1) + 0.5));
58  }
60  vec2_type calc_position(int ix,int iy) const
61  {
62  return vec2_type(double(ix) / (_nx - 1),double(iy) / (_ny - 1));
63  }
64  public:
66 // @{
67  lookup_table():_nx(0),_ny(0),_lc_fov(.5,.5)
68  { }
70  void init(int nx,int ny)
71  {
72  _nx = nx;
73  _ny = ny;
74  _samples.resize(_nx * _ny);
75  reset();
76  }
80  void set_lens_center_fov(const vec2_type& lc_fov)
81  {
82  _lc_fov = lc_fov;
83  }
84 // @}
85 
94 // @{
96  void reset();
98  bool next();
100  int get_ix_current() const
101  { return _ix_current; }
103  int get_iy_current() const
104  { return _iy_current; }
107  vec2_type get_p_current_fov() const
108  { return calc_position(_ix_current,_iy_current); }
110  vec2_type get_current_initial_value() const;
113  void set_q_current_fov(const vec2_type& q_fov)
114  { _samples.at(_ix_current + _nx * _iy_current).value = q_fov; }
115 // @}
116 
122 // @{
124  const vec2_type& get_value(int ix,int iy) const
125  {
126  return _samples.at(ix + _nx * iy).value;
127  }
131  const vec2_type& get_value(const vec2_type& p_fov) const
132  {
133  int ix,iy;
134  calc_index(p_fov,ix,iy);
135  clip_index(ix,iy);
136  return _samples[ix + _nx * iy].value;
137  }
140  const vec2_type& get_initial_value(const vec2_type& p_fov) const
141  {
142  return get_value(p_fov);
143  }
144 // @}
145 
147 // @{
149  std::ostream& out_state(std::ostream& cout) const
150  {
151  for(int iy = _ny - 1;iy >= 0;--iy)
152  {
153  for(int ix = 0;ix < _nx;++ix)
154  {
155  if((ix == _ix_current) && (iy == _iy_current))
156  {
157  cout << 'o';
158  }
159  else
160  {
161  cout << (get_sample(ix,iy).done ? '*' : '.');
162  }
163  }
164  cout << std::endl;
165  }
166  return cout;
167  }
170  std::ostream& out_gnuplot(std::ostream& cout) const
171  {
172  for(int iy = 0;iy < _ny;++iy)
173  {
174  for(int ix = 0;ix < _nx;++ix)
175  {
176  vec2_type p,q,d;
177  p = calc_position(ix,iy);
178  q = get_value(ix,iy);
179  d = q - p;
180  cout << p[0] << " " << p[1] << " " << d[0] << " " << d[1] << std::endl;
181  }
182  }
183  return cout;
184  }
185 // @}
186  };
187 
188  template <class VEC2>
190  {
191  for(typename samples_type::iterator i = _samples.begin();i != _samples.end();++i)
192  {
193  i->done = false;
194  }
195 // Reset counter
196  _k = 0;
197 // Calculate index of Lens Center
198  calc_index(_lc_fov,_ix_lc,_iy_lc);
199  }
200  template <class VEC2>
202  {
203 // Each position painted
204  if(_k >= _samples.size()) return false;
205 
206  int kx = _k % _nx;
207  if(kx <= _ix_lc)
208  {
209 // going left
210  _ix_current = _ix_lc - kx;
211  }
212  else
213  {
214 // going right
215  _ix_current = _ix_lc + (kx - _ix_lc);
216  }
217  int ky = _k / _nx;
218  if(ky <= _iy_lc)
219  {
220 // going down
221  _iy_current = _iy_lc - ky;
222  }
223  else
224  {
225 // going up
226  _iy_current = _iy_lc + (ky - _iy_lc);
227  }
228  get_sample(_ix_current,_iy_current).done = true;
229  ++_k;
230  return true;
231  }
232  template <class VEC2>
234  {
235  if(_iy_current == _iy_lc)
236  {
237  if(_ix_current == _ix_lc)
238  {
239  return calc_position(_ix_current,_iy_current);
240  }
241  else if(_ix_current < _ix_lc)
242  {
243  return get_value(_ix_current + 1,_iy_current);
244  }
245  else
246  {
247  return get_value(_ix_current - 1,_iy_current);
248  }
249  }
250  else if(_iy_current < _iy_lc)
251  {
252  return get_value(_ix_current,_iy_current + 1);
253  }
254  else
255  {
256  return get_value(_ix_current,_iy_current - 1);
257  }
258  }
259  }
260 
261 #endif
int get_iy_current() const
Current y-position while painting.
Definition: ldpk_lookup_table.h:103
bool next()
False means no value to be generated, loop is done. See example.
Definition: ldpk_lookup_table.h:201
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:149
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:140
The namespace of (most of the) things related to the Lens Distortion Plugin Kit.
Definition: ldpk.h:169
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:100
void reset()
Use reset() and next() to build a loop for generating positions. See example.
Definition: ldpk_lookup_table.h:189
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:131
void init(int nx, int ny)
Initialize a grid with nx * ny sample points. Implies reset().
Definition: ldpk_lookup_table.h:70
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:233
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:124
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:80
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:107
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:170
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:113