vpgl_affine_camera.hxx
Go to the documentation of this file.
1 // This is core/vpgl/vpgl_affine_camera.hxx
2 #ifndef vpgl_affine_camera_hxx_
3 #define vpgl_affine_camera_hxx_
4 //:
5 // \file
6 
7 #include "vpgl_affine_camera.h"
8 #include <vnl/vnl_vector_fixed.h>
9 #include <vnl/vnl_matrix_fixed.h>
11 #include <vgl/vgl_closest_point.h>
12 #include <vgl/vgl_tolerance.h>
13 #include <vgl/vgl_ray_3d.h>
14 #include <cassert>
15 #ifdef _MSC_VER
16 # include <vcl_msvc_warnings.h>
17 #endif
18 
19 //-------------------------------------------
20 template <class T>
22 {
23  vnl_vector_fixed<T, 4> row1((T)1, (T)0, (T)0, (T)0);
24  vnl_vector_fixed<T, 4> row2((T)0, (T)1, (T)0, (T)0);
25  set_rows(row1, row2);
26  view_distance_ = (T)0;
27 }
28 
29 
30 //-------------------------------------------
31 template <class T>
33  const vnl_vector_fixed<T,4>& row2 )
34 {
35  set_rows( row1, row2 );
36  view_distance_ = (T)0;
37 }
38 
39 
40 //------------------------------------------
41 template <class T>
43 {
44  assert( camera_matrix(2,3) != 0 );
45  vnl_matrix_fixed<T,3,4> C( camera_matrix );
46  C = C/C(2,3);
47  C(2,0) = (T)0; C(2,1) = (T)0; C(2,2) = (T)0;
49  view_distance_ = (T)0;
51  ray_dir_.set(cc.x(), cc.y(), cc.z());
52  ray_dir_ = normalize(ray_dir_);
53 }
54 
55 template <class T>
58  vgl_point_3d<T> stare_pt,
59  T u0, T v0, T su, T sv) {
60 
61  vgl_vector_3d<T> uvec = normalized(up), rvec = normalized(ray);
63  if (std::fabs(dot_product<T>(uvec,rvec)-T(1))<1e-5)
64  {
65  T r[] = { 1, 0, 0,
66  0, 1, 0,
67  0, 0, 1 };
68 
70  }
71  else if (std::fabs(dot_product<T>(uvec,rvec)-T(-1))<1e-5)
72  {
73  T r[] = { 1, 0, 0,
74  0, 1, 0,
75  0, 0, -1 };
76 
78  }
79  else
80  {
81  vgl_vector_3d<T> x = cross_product(-uvec,rvec);
82  vgl_vector_3d<T> y = cross_product(rvec,x);
83  normalize(x);
84  normalize(y);
85 
86  T r[] = { x.x(), x.y(), x.z(),
87  y.x(), y.y(), y.z(),
88  rvec.x(), rvec.y(), rvec.z() };
89 
91  }
92 
93  //form affine camera
95  for (unsigned i = 0; i<3; ++i) {
96  r0[i] = su*R[0][i];
97  r1[i] = sv*R[1][i];
98  }
99  r0[3]= 0.0; r1[3]= 0.0;
100  this->set_rows(r0, r1);
101  T u, v;
102  this->project(stare_pt.x(), stare_pt.y(), stare_pt.z(), u, v);
103  T tu = (u0-u);
104  T tv = (v0-v);
105  r0[3]=tu; r1[3]=tv;
106  this->set_rows(r0, r1);
107  view_distance_ = (T)0;
108  ray_dir_.set(rvec.x(), rvec.y(), rvec.z());
109 }
110 
111 
112 //------------------------------------------
113 template <class T>
115  const vnl_vector_fixed<T,4>& row1,
116  const vnl_vector_fixed<T,4>& row2 )
117 {
118  vnl_matrix_fixed<T,3,4> C( (T)0 );
119  for ( unsigned int i = 0; i < 4; ++i ) {
120  C(0,i) = row1(i);
121  C(1,i) = row2(i);
122  }
123  C(2,3) = (T)1;
125 
126  // set ray_dir to match new projection matrix
128  ray_dir_.set(cc.x(), cc.y(), cc.z());
129  ray_dir_ = normalize(ray_dir_);
130 }
131 
132 template <class T>
134 {
135  assert( new_camera_matrix(2,3) != 0 );
136  vnl_matrix_fixed<T,3,4> C( new_camera_matrix );
137  C = C/C(2,3);
138  C(2,0) = (T)0; C(2,1) = (T)0; C(2,2) = (T)0;
140 
142  vgl_vector_3d<T> old_ray_dir = ray_dir_;
143  ray_dir_.set(cc.x(), cc.y(), cc.z());
144  ray_dir_ = normalize(ray_dir_);
145  // assume that new and old ray directions should not differ by more than 90 deg.
146  // if this assumption is false, caller should call orient_ray_direction() afterwards.
147  orient_ray_direction(old_ray_dir);
148  return true;
149 }
150 
151 template <class T>
152 bool vpgl_affine_camera<T>::set_matrix( const T* new_camera_matrix_p )
153 {
154  vnl_matrix_fixed<T,3,4> new_camera_matrix( new_camera_matrix_p );
155  set_matrix( new_camera_matrix );
156  return true;
157 }
158 
159 //: Find the 3d coordinates of the center of the camera. Will be an ideal point with the sense of the ray direction.
160 template <class T>
162 {
163  vgl_homg_point_3d<T> temp(ray_dir_.x(), ray_dir_.y(), ray_dir_.z(), (T)0);
164  return temp;
165 }
166 
167 //: Find the 3d ray that goes through the camera center and the provided image point.
168 template <class T>
170 backproject( const vgl_homg_point_2d<T>& image_point ) const
171 {
173  //get line from projective camera
178  vgl_point_3d<T> cp(cph);
179  vgl_point_3d<T> eye_pt = cp-(view_distance_*ray_dir_);
180  vgl_homg_point_3d<T> pt_fin(eye_pt.x(), eye_pt.y(), eye_pt.z());
181  vgl_homg_point_3d<T> pinf(ray_dir_.x(), ray_dir_.y(), ray_dir_.z(), (T)0);
182  ret = vgl_homg_line_3d_2_points<T>(pt_fin, pinf);
183  }
184  else
185  std::cout << "Warning vpgl_affine_camera::backproject produced line at infinity\n";
186  return ret;
187 }
188 
189 template <class T>
191 backproject_ray( const vgl_homg_point_2d<T>& image_point ) const
192 {
193  vgl_homg_line_3d_2_points<T> line = backproject( image_point );
194  return vgl_ray_3d<T>(vgl_point_3d<T>(line.point_finite()), ray_dir_);
195 }
196 
197 template <class T>
199 {
200  return new vpgl_affine_camera<T>(*this);
201 }
202 
203 
204 //: Find the world plane parallel to the image plane intersecting the camera center.
205 template <class T>
208 {
209  //note that d = view_distance_ not -view_distance_,
210  //since dir points towards the origin
211  vgl_homg_plane_3d<T> ret(ray_dir_.x(), ray_dir_.y(),
212  ray_dir_.z(), view_distance_);
213  return ret;
214 }
215 
216 //: flip the ray direction so that dot product with look_dir is positive
217 template <class T>
219 {
220  if (dot_product(look_dir, ray_dir_) < 0 ) {
221  ray_dir_ = -ray_dir_;
222  }
223 }
224 
225 //: Write vpgl_affine_camera to stream
226 template <class Type>
227 std::ostream& operator<<(std::ostream& s,
228  vpgl_affine_camera<Type> const& c)
229 {
230  s << c.get_matrix() << '\n';
231  return s;
232 }
233 
234 //: Read camera from stream
235 template <class Type>
236 std::istream& operator >>(std::istream& s,
238 {
240  s >> P;
242  return s ;
243 }
244 
245 
246 // Code for easy instantiation.
247 #undef vpgl_AFFINE_CAMERA_INSTANTIATE
248 #define vpgl_AFFINE_CAMERA_INSTANTIATE(T) \
249 template class vpgl_affine_camera<T >; \
250 template std::ostream& operator<<(std::ostream&, const vpgl_affine_camera<T >&); \
251 template std::istream& operator>>(std::istream&, vpgl_affine_camera<T >&)
252 
253 
254 #endif // vpgl_affine_camera_hxx_
A class for the affine camera model.
std::istream & operator >>(std::istream &s, vpgl_affine_camera< Type > &c)
Read camera from stream.
vgl_ray_3d< T > backproject_ray(const vgl_homg_point_2d< T > &image_point) const override
Find the 3d ray that goes through the camera center and the provided image point.
vpgl_affine_camera< T > * clone(void) const override
Clone ‘this’: creation of a new object and initialization.
#define v
vpgl_affine_camera()
Default constructor creates the canonical affine camera.
virtual bool set_matrix(const vnl_matrix_fixed< T, 3, 4 > &new_camera_matrix)
Setters mirror the constructors and return true if the setting was successful.
Type z() const
virtual vgl_homg_line_3d_2_points< T > backproject(const vgl_homg_point_2d< T > &image_point) const
Find the 3d ray that goes through the camera center and the provided image point.
T y() const
virtual vgl_homg_point_3d< T > camera_center() const
Find the 3d coordinates of the center of the camera.
T x() const
std::ostream & operator<<(std::ostream &s, const vpgl_local_rational_camera< T > &p)
Write to stream.
T z() const
vgl_homg_line_3d_2_points< T > backproject(const vgl_homg_point_2d< T > &image_point) const override
Find the 3d ray that goes through the camera center.
vgl_homg_point_3d< T > camera_center() const override
Find the 3d coordinates of the center of the camera. Will be an ideal point with the sense of the ray...
void orient_ray_direction(vgl_vector_3d< T > const &look_dir)
flip the ray direction so that dot product with look_dir is positive.
const vnl_matrix_fixed< T, 3, 4 > & get_matrix() const
Return a copy of the camera matrix.
void set(T vx, T vy, T vz)
void set_rows(const vnl_vector_fixed< T, 4 > &row1, const vnl_vector_fixed< T, 4 > &row2)
Set the top two rows.
T dot_product(v const &a, v const &b)
bool is_ideal(l const &line, T tol=(T) 0)
vgl_homg_plane_3d< T > principal_plane() const override
Find the world plane perpendicular to the camera rays at viewing distance from the origin.
bool set_matrix(const vnl_matrix_fixed< T, 3, 4 > &new_camera_matrix) override
Setters mirror the constructors and return true if the setting was successful.
Type y() const
v & normalize(v &a)
T cross_product(v const &a, v const &b)
vgl_homg_point_3d< Type > point_finite() const
Type x() const
v normalized(v const &a)
vgl_point_2d< T > vgl_closest_point_origin(vgl_line_2d< T > const &l)