2 #ifndef vgl_h_matrix_3d_hxx_ 3 #define vgl_h_matrix_3d_hxx_ 12 #include <vcl_compiler_detection.h> 14 # include <vcl_msvc_warnings.h> 17 #include <vnl/vnl_inverse.h> 18 #include <vnl/vnl_numeric_traits.h> 19 #include <vnl/vnl_vector_fixed.h> 20 #include <vnl/vnl_quaternion.h> 21 #include <vnl/algo/vnl_svd.h> 22 # include <vcl_deprecated.h> 29 assert(points1.size() == points2.size());
30 unsigned int numpoints = static_cast<int>( points1.size());
33 std::cerr <<
"\nvhl_h_matrix_3d - minimum of 5 points required\n";
37 W.set_size(3*numpoints, 16);
39 for (
unsigned int i = 0; i < numpoints; i++)
41 T x1 = points1[i].x(), y1 = points1[i].y(), z1 = points1[i].z(), w1 = points1[i].w();
42 T x2 = points2[i].x(), y2 = points2[i].y(), z2 = points2[i].z(), w2 = points2[i].w();
44 W[i*3][0]=x1*w2; W[i*3][1]=y1*w2; W[i*3][2]=z1*w2; W[i*3][3]=w1*w2;
45 W[i*3][4]=0.0; W[i*3][5]=0.0; W[i*3][6]=0.0; W[i*3][7]=0.0;
46 W[i*3][8]=0.0; W[i*3][9]=0.0; W[i*3][10]=0.0; W[i*3][11]=0.0;
47 W[i*3][12]=-x1*x2; W[i*3][13]=-y1*x2; W[i*3][14]=-z1*x2; W[i*3][15]=-w1*x2;
49 W[i*3+1][0]=0.0; W[i*3+1][1]=0.0; W[i*3+1][2]=0.0; W[i*3+1][3]=0.0;
50 W[i*3+1][4]=x1*w2; W[i*3+1][5]=y1*w2; W[i*3+1][6]=z1*w2; W[i*3+1][7]=w1*w2;
51 W[i*3+1][8]=0.0; W[i*3+1][9]=0.0; W[i*3+1][10]=0.0; W[i*3+1][11]=0.0;
52 W[i*3+1][12]=-x1*y2; W[i*3+1][13]=-y1*y2; W[i*3+1][14]=-z1*y2; W[i*3+1][15]=-w1*y2;
54 W[i*3+2][0]=0.0; W[i*3+2][1]=0.0; W[i*3+2][2]=0.0; W[i*3+2][3]=0.0;
55 W[i*3+2][4]=0.0; W[i*3+2][5]=0.0; W[i*3+2][6]=0.0; W[i*3+2][7]=0.0;
56 W[i*3+2][8]=x1*w2; W[i*3+2][9]=y1*w2; W[i*3+2][10]=z1*w2; W[i*3+2][11]=w1*w2;
57 W[i*3+2][12]=-x1*z2; W[i*3+2][13]=-y1*z2; W[i*3+2][14]=-z1*z2; W[i*3+2][15]=-w1*z2;
61 t12_matrix_ = vnl_matrix_fixed<T,4,4>(SVD.nullvector().data_block());
67 t12_matrix_.read_ascii(s);
73 std::ifstream f(filename);
75 std::cerr <<
"vgl_h_matrix_3d::read: Error opening " << filename << std::endl;
77 t12_matrix_.read_ascii(f);
82 vnl_vector_fixed<T,3>
const& m)
84 for (
int r = 0; r < 3; ++r) {
85 for (
int c = 0; c < 3; ++c)
86 (t12_matrix_)(r, c) = M(r,c);
87 (t12_matrix_)(r, 3) = m(r);
89 for (
int c = 0; c < 3; ++c)
90 (t12_matrix_)(3,c) = 0;
91 (t12_matrix_)(3,3) = 1;
102 vnl_vector_fixed<T,4> v2 = t12_matrix_ * vnl_vector_fixed<T,4>(p.
x(), p.
y(), p.
z(), p.
w());
110 unsigned np = ptset.
npts();
111 std::vector<vgl_point_3d<T> > pts;
112 std::vector<vgl_vector_3d<T> > normals;
113 for(
unsigned i =0; i<np; ++i){
121 normals.push_back(hv);
136 vnl_vector_fixed<T,4> v2 = t12_matrix_ * vnl_vector_fixed<T,4>(p.
x(), p.
y(), p.
z(), p.
w());
144 vnl_vector_fixed<T,4> v2 = t12_matrix_.transpose() * vnl_vector_fixed<T,4>(
l.a(),
l.b(),
l.c(),
l.d());
152 vnl_vector_fixed<T,4> v2 = t12_matrix_ * vnl_vector_fixed<T,4>(
l.a(),
l.b(),
l.c(),
l.d());
160 vnl_vector_fixed<T,4>
v = vnl_inverse(t12_matrix_) * vnl_vector_fixed<T,4>(p.
x(), p.
y(), p.
z(), p.
w());
173 vnl_vector_fixed<T,4>
v = vnl_inverse_transpose(t12_matrix_) * vnl_vector_fixed<T,4>(
l.a(),
l.b(),
l.c(),
l.d());
186 t12_matrix_.read_ascii(s);
187 return s.good() || s.eof();
193 std::ifstream f(filename);
195 std::cerr <<
"vgl_h_matrix_3d::read: Error opening " << filename << std::endl;
204 return t12_matrix_.get(row_index, col_index);
210 for (T
const* iter = t12_matrix_.begin(); iter < t12_matrix_.end(); ++iter)
223 VXL_DEPRECATED_MACRO(
"vgl_h_matrix_3d<T>::get(vnl_matrix<T>*) const");
224 *H = t12_matrix_.as_ref();
238 for (T* iter = t12_matrix_.begin(); iter < t12_matrix_.end(); ++iter)
254 std::cerr <<
"vgl_h_matrix_3d<T>::projective_basis(5pts) not yet implemented\n";
261 std::cerr <<
"vgl_h_matrix_3d<T>::projective_basis(5planes) not yet implemented\n";
277 t12_matrix_(0, 3) = tx;
278 t12_matrix_(1, 3) = ty;
279 t12_matrix_(2, 3) = tz;
287 for (
unsigned r = 0; r<3; ++r)
288 for (
unsigned c = 0; c<4; ++c)
289 t12_matrix_[r][c]*=scale;
297 for (
unsigned r = 0; r<3; ++r)
298 for (
unsigned c = 0; c<4; ++c)
299 t12_matrix_[r][c] = M34[r][c];
300 t12_matrix_[3][0] = t12_matrix_[3][1] = t12_matrix_[3][2] = T(0); t12_matrix_[3][3] = T(1);
308 vnl_quaternion<T> q(axis,
angle);
310 vnl_matrix_fixed<T,3,3> R = q.rotation_matrix_transpose();
312 for (
int c = 0; c<3; c++)
313 for (
int r = 0; r<3; r++)
314 t12_matrix_[r][c]=R[c][r];
322 typedef typename vnl_numeric_traits<T>::real_t real_t;
323 real_t ax = yaw/2, ay = pitch/2, az = roll/2;
325 vnl_quaternion<T> qx((T)std::sin(ax),0,0,(T)std::cos(ax));
326 vnl_quaternion<T> qy(0,(T)std::sin(ay),0,(T)std::cos(ay));
327 vnl_quaternion<T> qz(0,0,(T)std::sin(az),(T)std::cos(az));
328 vnl_quaternion<T> q = qz*qy*qx;
330 vnl_matrix_fixed<T,3,3> R = q.rotation_matrix_transpose();
332 for (
int c = 0; c<3; c++)
333 for (
int r = 0; r<3; r++)
334 t12_matrix_[r][c]=R[c][r];
342 typedef typename vnl_numeric_traits<T>::real_t real_t;
343 real_t az1 = rz1/2, ay = ry/2, az2 = rz2/2;
345 vnl_quaternion<T> qz1(0,0,T(std::sin(az1)),T(std::cos(az1)));
346 vnl_quaternion<T> qy(0,T(std::sin(ay)),0,T(std::cos(ay)));
347 vnl_quaternion<T> qz2(0,0,T(std::sin(az2)),T(std::cos(az2)));
348 vnl_quaternion<T> q = qz2*qy*qz1;
350 vnl_matrix_fixed<T,3,3> R = q.rotation_matrix_transpose();
352 for (
int c = 0; c<3; c++)
353 for (
int r = 0; r<3; r++)
354 t12_matrix_[r][c]=R[c][r];
362 for (
unsigned r = 0; r<3; ++r)
363 for (
unsigned c = 0; c<3; ++c)
364 t12_matrix_[r][c] = R[r][c];
373 t12_matrix_.fill(T(0));
374 t12_matrix_(0,0) = T(
l.nx()*
l.nx());
375 t12_matrix_(1,1) = T(
l.ny()*
l.ny());
376 t12_matrix_(2,2) = T(
l.nz()*
l.nz());
377 t12_matrix_(0,1) = t12_matrix_(1,0) = T(
l.nx()*
l.ny());
378 t12_matrix_(0,2) = t12_matrix_(2,0) = T(
l.nx()*
l.nz());
379 t12_matrix_(1,2) = t12_matrix_(2,1) = T(
l.ny()*
l.nz());
380 t12_matrix_(0,3) = T(
l.nx()*
l.d());
381 t12_matrix_(1,3) = T(
l.ny()*
l.d());
382 t12_matrix_(2,3) = T(
l.nz()*
l.d());
383 t12_matrix_ *= -2/(t12_matrix_(0,0)+t12_matrix_(1,1)+t12_matrix_(2,2));
384 t12_matrix_(0,0) += (T)1;
385 t12_matrix_(1,1) += (T)1;
386 t12_matrix_(2,2) += (T)1;
387 t12_matrix_(3,3) += (T)1;
394 return t12_matrix_.get(0,3) == (T)0
395 && t12_matrix_.get(1,3) == (T)0
396 && t12_matrix_.get(2,3) == (T)0
397 && this->is_euclidean();
404 T eps = 10*std::numeric_limits<T>::epsilon();
405 if ( t12_matrix_.get(3,0) != (T)0 ||
406 t12_matrix_.get(3,1) != (T)0 ||
407 t12_matrix_.get(3,2) != (T)0 ||
408 std::fabs(t12_matrix_.get(3,3)-T(1)) > eps)
412 vnl_matrix_fixed<T,3,3> R = get_upper_3x3_matrix();
417 return R.absolute_value_max() <= eps;
422 if ( t12_matrix_.get(3,0) != (T)0 ||
423 t12_matrix_.get(3,1) != (T)0 ||
424 t12_matrix_.get(3,2) != (T)0 ||
425 std::fabs(t12_matrix_.get(3,3)) > 10*std::numeric_limits<T>::epsilon())
427 return !(this->is_euclidean());
433 return t12_matrix_.is_identity();
442 T d = t12_matrix_[3][3];
443 assert(d<-1e-9 || d>1e-9);
444 vnl_matrix_fixed<T,4,4> m(0.0);
445 for (
unsigned r = 0; r<3; r++)
446 for (
unsigned c = 0; c<3; c++)
447 m[r][c] = t12_matrix_[r][c]/d;
453 vnl_matrix_fixed<T,3,3>
456 vnl_matrix_fixed<T,3,3> R;
458 for (
unsigned r = 0; r<3; r++)
459 for (
unsigned c = 0; c<3; c++)
460 R[r][c] = m.
get(r,c);
465 vnl_matrix_fixed<T, 3, 3> up = this->get_upper_3x3_matrix();
468 vnl_matrix<T> U = svd.U();
469 vnl_matrix<T> W = svd.W();
470 vnl_matrix<T> V = svd.V();
471 R = vnl_matrix_fixed<T, 3, 3> ( U*V.transpose());
472 S = vnl_matrix_fixed<T, 3, 3> (V*W*V.transpose());
481 T d = t12_matrix_[3][3];
482 assert(d<-1e-9 || d>1e-9);
490 vnl_vector_fixed<T,3>
494 return vnl_vector_fixed<T,3>(p.
x(), p.
y(), p.
z());
498 #undef VGL_H_MATRIX_3D_INSTANTIATE 499 #define VGL_H_MATRIX_3D_INSTANTIATE(T) \ 500 template class vgl_h_matrix_3d<T >; \ 501 template std::ostream& operator<<(std::ostream&, vgl_h_matrix_3d<T > const& ); \ 502 template std::istream& operator>>(std::istream&, vgl_h_matrix_3d<T >& ) 504 #endif // vgl_h_matrix_3d_hxx_ vgl_h_matrix_3d & set_rotation_roll_pitch_yaw(T yaw, T pitch, T roll)
Set to roll, pitch and yaw specified rotation.
bool read(std::istream &s)
Load H from ASCII file.
vgl_h_matrix_3d get_inverse() const
Return the inverse homography.
std::istream & read(std::istream &is)
Read from stream, possibly with formatting.
vgl_h_matrix_3d & set_scale(T scale)
compose the current transform with a uniform scaling transformation, S.
vgl_h_matrix_3d & set_translation(T tx, T ty, T tz)
set H[0][3] = tx, H[1][3] = ty, and H[2][3] = tz, other elements unaltered.
vgl_point_3d< Type > p(unsigned i) const
vgl_h_matrix_3d & set_affine(vnl_matrix_fixed< T, 3, 4 > const &M34)
set the transform to a general affine transform matrix.
vgl_h_matrix_3d & set(unsigned int row_index, unsigned int col_index, T value)
Set an element of the 4x4 homography matrix.
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
vgl_h_matrix_3d & set_rotation_euler(T rz1, T ry, T rz2)
Set to rotation specified by Euler angles.
Represents a homogeneous 3D point.
vgl_h_matrix_3d()=default
vnl_matrix_fixed< T, 3, 3 > get_upper_3x3_matrix() const
vgl_homg_point_3d< T > operator()(vgl_homg_point_3d< T > const &p) const
Return the transformed point given by $q = {\tt H} p$.
bool projective_basis(std::vector< vgl_homg_point_3d< T > > const &five_points)
Compute transform to projective basis given five points, no 4 of which coplanar.
vgl_homg_plane_3d< T > correlation(vgl_homg_point_3d< T > const &p) const
vgl_homg_plane_3d< T > preimage(vgl_homg_plane_3d< T > const &l) const
Return the preimage of a transformed plane: $m = {\tt H} l$.
void get(vnl_matrix_fixed< T, 4, 4 > *M) const
Fill M with contents of the 4x4 homography matrix.
bool has_normals() const
accessors.
vgl_h_matrix_3d & set_rotation_matrix(vnl_matrix_fixed< T, 3, 3 > const &R)
Just the upper 3x3 part of the matrix is replaced by a rotation matrix.
vnl_vector_fixed< T, 3 > get_translation_vector() const
A class to hold a 3-d projective transformation matrix and to perform common operations using it e....
Represents a Euclidean 3D plane.
vgl_h_matrix_3d & set_identity()
initialize the transformation to identity.
void set_points(std::vector< vgl_point_3d< Type > > const &points)
Direction vector in Euclidean 3D space, templated by type of element.
vnl_matrix_fixed< T, 4, 4 > const & get_matrix() const
Return the 4x4 homography matrix.
vgl_homg_point_3d< T > get_translation() const
corresponds to translation for affine transformations.
double angle(v const &a, v const &b)
smallest angle between two vectors (in radians, between 0 and Pi).
a plane in 3D nonhomogeneous space
void polar_decomposition(vnl_matrix_fixed< T, 3, 3 > &S, vnl_matrix_fixed< T, 3, 3 > &R) const
polar decomposition of the upper 3x3 matrix, M = S*R, where S is a symmetric matrix and R is an ortho...
void set_reflection_plane(vgl_plane_3d< double > const &p)
set the transformation to a reflection about a plane.
void set_points_with_normals(std::vector< vgl_point_3d< Type > > const &points, std::vector< vgl_vector_3d< Type > > const &normals)
bool is_euclidean() const
4x4 3D-to-3D projectivity
vgl_h_matrix_3d< T > get_upper_3x3() const
corresponds to rotation for Euclidean transformations.
vgl_h_matrix_3d & set_rotation_about_axis(vnl_vector_fixed< T, 3 > const &axis, T theta)
Set to rotation about an axis.
vgl_vector_3d< Type > n(unsigned i) const