vpgl_rational_camera.h
Go to the documentation of this file.
1 // This is core/vpgl/vpgl_rational_camera.h
2 #ifndef vpgl_rational_camera_h_
3 #define vpgl_rational_camera_h_
4 //:
5 // \file
6 // \brief A camera model based on ratios of cubic polynomials
7 // \author Joseph Mundy
8 // \date Oct 2006
9 //
10 //
11 // A camera that projects 3-d world points according to ratios of
12 // cubic polynomials. That is,
13 // \verbatim
14 // neu_u(X,Y,Z) neu_v(X,Y,Z)
15 // u = ------------ v = ------------
16 // den_u(X,Y,Z) den_v(X,Y,X)
17 // \endverbatim
18 // where u is the image column index and v is the image row index.
19 //
20 // neu_u(X,Y,Z),den_u(X,Y,Z), neu_v(X,Y,Z), den_v(X,Y,Z) are
21 // cubic polynomials in three variables and there are 20 coefficients each,
22 // e.g.,
23 //
24 // R(X,Y,Z) = a300 x^3 + a210 x^2y + a201 x^2z + a200 x^2 + ... + a001z + a000
25 //
26 // The normal ordering of multi-variate polynomial coefficients is as
27 // shown above, the highest powers in x followed by highest powers in y,
28 // followed by powers in z. The full monomial sequence is:
29 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
30 // x^3 x^2y x^2z x^2 xy^2 xyz xy xz^2 xz x y^3 y^2z y^2 yz^2 yz y z^3 z^2 z 1
31 // The highest powers are in the lowest index of the coefficient vector.
32 //
33 // Polynomial calculations are often ill-conditioned if the variables are not
34 // normalized. Common practice is to normalize all variables to the
35 // range [-1, 1]. This normalization requires 10 additional offset and scale
36 // parameters for a total of 90 parameters.
37 //
38 // The scale and offset transformation is applied to (X,Y,Z)
39 // before applying the polynomial mapping. The resulting (u,v) is normalized
40 // and must be mapped back (un-normalized) to the image coordinate
41 // system to obtain the actual projection.
42 //
43 // In order to facilitate the scale offset transformation process, a helper
44 // class, scale_offset, is defined to process the forward and reverse
45 // normalizations.
46 //
47 #include <iostream>
48 #include <string>
49 #include <utility>
50 #include <vector>
51 #ifdef _MSC_VER
52 # include <vcl_msvc_warnings.h>
53 #endif
54 #include <vgl/vgl_fwd.h>
55 #include <vnl/vnl_matrix_fixed.h>
56 #include <vnl/vnl_vector_fixed.h>
57 #include <vpgl/vpgl_camera.h>
58 
59 // Represent scale and offset transformations used in normalization
60 //
61 template <class T>
63 {
64  public:
66  scale_(1), offset_(0) {}
67  vpgl_scale_offset(const T scale, const T offset) :
69 
70  //mutators/accessors
71  void set_scale(const T scale) {scale_ = scale;}
72  void set_offset(const T offset) {offset_ = offset;}
73  T scale() const {return scale_;}
74  T offset() const {return offset_;}
75 
76  // normalize a coordinate value
77  T normalize(const T value) const
78  {
79  if (scale_==0)
80  return 0;
81  else
82  return (value-offset_)/scale_;
83  }
84 
85  // un-normalize a coordinate value
86  T un_normalize(const T value) const
87  {
88  T temp = value*scale_;
89  return temp + offset_;
90  }
91  //: Equality test
92  inline bool operator==(vpgl_scale_offset<T> const &that) const
93  { return this == &that ||
94  (this->scale()==that.scale() &&
95  this->offset() == that.offset() );
96  }
97  private:
98  //members
99  T scale_;
101 };
102 
103 //
104 //--------------------=== rational camera ===---------------------------
105 //
106 template <class T>
108 {
109  public:
110  //: enumeration for indexing coordinates
112  //: enumeration for indexing polynomials
114 
115  //: default constructor
117  //: Constructor from 4 coefficient vectors and 5 scale, offset pairs.
118  vpgl_rational_camera(std::vector<T> const& neu_u,
119  std::vector<T> const& den_u,
120  std::vector<T> const& neu_v,
121  std::vector<T> const& den_v,
122  const T x_scale, const T x_off,
123  const T y_scale, const T y_off,
124  const T z_scale, const T z_off,
125  const T u_scale, const T u_off,
126  const T v_scale, const T v_off
127  );
128 
129  //: Constructor from 4 coefficient arrays and 5 scale, offset pairs.
130  vpgl_rational_camera(const double* neu_u,
131  const double* den_u,
132  const double* neu_v,
133  const double* den_v,
134  const T x_scale, const T x_off,
135  const T y_scale, const T y_off,
136  const T z_scale, const T z_off,
137  const T u_scale, const T u_off,
138  const T v_scale, const T v_off
139  );
140 
141 
142  //: Constructor with everything wrapped up in an array and vector.
143  vpgl_rational_camera(std::vector<std::vector<T> > const& rational_coeffs,
144  std::vector<vpgl_scale_offset<T> > const& scale_offsets);
145 
146  //: Constructor with a coefficient matrix
148  std::vector<vpgl_scale_offset<T> > scale_offsets)
149  : rational_coeffs_(rational_coeffs), scale_offsets_(std::move(scale_offsets)) {}
150 
151  ~vpgl_rational_camera() override = default;
152 
153  std::string type_name() const override { return "vpgl_rational_camera"; }
154 
155  //: Clone `this': creation of a new object and initialization
156  // See Prototype pattern
157  virtual vpgl_rational_camera<T>* clone(void) const;
158 
159  //: Equality test
160  inline bool operator==(vpgl_rational_camera<T> const &that) const
161  { return this == &that ||
162  ((this->coefficient_matrix()==that.coefficient_matrix())&&
163  (this->scale_offsets() == that.scale_offsets()) );}
164 
165  // --- Mutators/Accessors ---
166 
167  //: set rational polynomial coefficients
168  void set_coefficients(std::vector<std::vector<T> > const& rational_coeffs);
169  void set_coefficients(vnl_matrix_fixed<T, 4, 20> const& rational_coeffs)
170  {rational_coeffs_ = rational_coeffs;}
171  //: set coordinate scale and offsets
172  void set_scale_offsets(std::vector<vpgl_scale_offset<T> > const& scale_offsets);
173  //: get the rational polynomial coefficients in a vnl matrix
175  {return rational_coeffs_;}
176  //: get the rational polynomial coefficients in a vcl array
177  std::vector<std::vector<T> > coefficients() const;
178  //: get the scale and offsets in a vector
179  std::vector<vpgl_scale_offset<T> > scale_offsets() const
180  {return scale_offsets_;}
181  //:set a specific scale value
182  void set_scale(const coor_index coor_index, const T scale)
183  {scale_offsets_[coor_index].set_scale(scale);}
184  //:set a specific scale value
185  void set_offset(const coor_index coor_index, const T offset)
186  {scale_offsets_[coor_index].set_offset(offset);}
187  //: get a specific scale value
188  T scale(const coor_index coor_index) const
189  {return scale_offsets_[coor_index].scale();}
190  //: get a specific offset value
191  T offset(const coor_index coor_index) const
192  {return scale_offsets_[coor_index].offset();}
193  //: get a specific scale_offset
195  {return scale_offsets_[coor_index];}
196 
197  // --- Often useful for adjusting the camera ---
198 
199  //:set u-v translation offset
200  void set_image_offset(const T u_off, const T v_off)
201  { scale_offsets_[U_INDX].set_offset(u_off);
202  scale_offsets_[V_INDX].set_offset(v_off); }
203 
204  //:get u-v translation offset
205  void image_offset(T& u_off, T& v_off) const
206  {u_off = offset(U_INDX); v_off = offset(V_INDX);}
207 
208  //:set u-v scale
209  void set_image_scale(const T u_scale, const T v_scale)
210  { scale_offsets_[U_INDX].set_scale(u_scale);
211  scale_offsets_[V_INDX].set_scale(v_scale); }
212 
213  //:get u-v scale
214  void image_scale(T& u_scale, T& v_scale)
215  {u_scale = scale(U_INDX); v_scale = scale(V_INDX);}
216  //: The generic camera interface. u represents image column, v image row.
217  void project(const T x, const T y, const T z, T& u, T& v) const override;
218 
219  // --- Interface for vnl ---
220 
221  //: Project a world point onto the image
222  virtual vnl_vector_fixed<T, 2> project(vnl_vector_fixed<T, 3> const& world_point) const;
223 
224  // --- Interface for vgl ---
225 
226  //: Project a world point onto the image
227  virtual vgl_point_2d<T> project(vgl_point_3d<T> world_point) const;
228 
229  //: print the camera parameters
230  virtual void print(std::ostream& s = std::cout) const;
231 
232  virtual bool save(std::string cam_path);
233 
234 
235  protected:
236  // utilities
237  vnl_vector_fixed<T, 20> power_vector(const T x, const T y, const T z) const;
238  // members
240  std::vector<vpgl_scale_offset<T> > scale_offsets_;
241 };
242 
243 //: Write to stream
244 // \relatesalso vpgl_rational_camera
245 template <class T>
246 std::ostream& operator<<(std::ostream& s, const vpgl_rational_camera<T>& p);
247 
248 //: Read from stream
249 // \relatesalso vpgl_rational_camera
250 template <class T>
251 std::istream& operator>>(std::istream& is, vpgl_rational_camera<T>& p);
252 
253 //: Creates a rational camera from a file
254 // \relatesalso vpgl_rational_camera
255 template <class T>
256 vpgl_rational_camera<T>* read_rational_camera(std::string cam_path);
257 
258 //: Creates a rational camera from a stream
259 // \relatesalso vpgl_rational_camera
260 template <class T>
261 vpgl_rational_camera<T>* read_rational_camera(std::istream& istr);
262 
263 //: Creates a rational camera from a txt file
264 // \relatesalso vpgl_rational_camera
265 template <class T>
267 
268 #define VPGL_RATIONAL_CAMERA_INSTANTIATE(T) extern "please include vgl/vpgl_rational_camera.hxx first"
269 
270 
271 #endif // vpgl_rational_camera_h_
poly_index
enumeration for indexing polynomials.
vnl_matrix_fixed< T, 4, 20 > coefficient_matrix() const
get the rational polynomial coefficients in a vnl matrix.
T normalize(const T value) const
std::istream & operator>>(std::istream &is, vpgl_local_rational_camera< T > &p)
Read from stream.
coor_index
enumeration for indexing coordinates.
bool operator==(vpgl_rational_camera< T > const &that) const
Equality test.
vnl_matrix_fixed< T, 4, 20 > rational_coeffs_
void set_coefficients(vnl_matrix_fixed< T, 4, 20 > const &rational_coeffs)
std::string type_name() const override
class identity functions for casting.
vpgl_rational_camera< T > * read_rational_camera(std::string cam_path)
Creates a rational camera from a file.
vpgl_scale_offset< T > scl_off(const coor_index coor_index) const
get a specific scale_offset.
vpgl_rational_camera(vnl_matrix_fixed< T, 4, 20 > const &rational_coeffs, std::vector< vpgl_scale_offset< T > > scale_offsets)
Constructor with a coefficient matrix.
void set_image_scale(const T u_scale, const T v_scale)
set u-v scale.
void set_scale(const coor_index coor_index, const T scale)
set a specific scale value.
virtual bool save(std::string cam_path)
std::vector< vpgl_scale_offset< T > > scale_offsets() const
get the scale and offsets in a vector.
void set_scale_offsets(std::vector< vpgl_scale_offset< T > > const &scale_offsets)
set coordinate scale and offsets.
std::vector< vpgl_scale_offset< T > > scale_offsets_
vnl_vector_fixed< T, 20 > power_vector(const T x, const T y, const T z) const
Create a vector with the standard order of monomial terms.
void set_offset(const T offset)
bool operator==(vpgl_scale_offset< T > const &that) const
Equality test.
void set_image_offset(const T u_off, const T v_off)
set u-v translation offset.
void set_scale(const T scale)
void set_offset(const coor_index coor_index, const T offset)
set a specific scale value.
void image_scale(T &u_scale, T &v_scale)
get u-v scale.
vpgl_rational_camera()
default constructor.
std::vector< std::vector< T > > coefficients() const
get the rational polynomial coefficients in a vcl array.
void image_offset(T &u_off, T &v_off) const
get u-v translation offset.
A general camera class.
std::ostream & operator<<(std::ostream &s, const vpgl_local_rational_camera< T > &p)
Write to stream.
T un_normalize(const T value) const
T scale(const coor_index coor_index) const
get a specific scale value.
virtual vpgl_rational_camera< T > * clone(void) const
Clone ‘this’: creation of a new object and initialization.
virtual void print(std::ostream &s=std::cout) const
print the camera parameters.
void set_coefficients(std::vector< std::vector< T > > const &rational_coeffs)
set rational polynomial coefficients.
~vpgl_rational_camera() override=default
T offset(const coor_index coor_index) const
get a specific offset value.
vpgl_rational_camera< T > * read_rational_camera_from_txt(std::string cam_path)
Creates a rational camera from a txt file.
void project(const T x, const T y, const T z, T &u, T &v) const override
The generic camera interface. u represents image column, v image row.
vpgl_scale_offset(const T scale, const T offset)