2 #ifndef vgl_p_matrix_hxx_ 3 #define vgl_p_matrix_hxx_ 13 # include <vcl_msvc_warnings.h> 16 #include <vnl/vnl_matrix.h> 17 #include <vnl/vnl_inverse.h> 18 #include <vnl/algo/vnl_svd.h> 19 #include <vnl/algo/vnl_determinant.h> 29 for (
int row_index = 0; row_index < 3; row_index++)
30 for (
int col_index = 0; col_index < 4; col_index++)
31 if (row_index == col_index)
50 p_matrix_(pmatrix), svd_(nullptr)
58 p_matrix_(c_matrix), svd_(nullptr)
67 p_matrix_(that.get_matrix()), svd_(nullptr)
86 delete svd_; svd_ =
nullptr;
115 vnl_vector_fixed<T,4> p = svd()->solve(vnl_vector_fixed<T,3>(x.
x(),x.
y(),x.
w()).as_ref());
132 return p_matrix_.transpose() *
l;
150 static inline bool ok(std::istream& f) {
return f.good() || f.eof(); }
155 vnl_matrix_ref<T> ref = this->p_matrix_.as_ref();
160 std::cerr <<
"vgl_p_matrix::read_ascii: Failed to load P matrix\n";
170 std::ifstream f(filename);
172 std::cerr <<
"vgl_p_matrix::read: Failed to open P matrix file " << filename << std::endl;
178 std::cerr <<
"vgl_p_matrix::read: Failed to read P matrix file " << filename << std::endl;
198 if (svd_ ==
nullptr) {
199 svd_ =
new vnl_svd<T>(p_matrix_.as_ref());
207 delete svd_; svd_ =
nullptr;
215 if (svd()->singularities() > 1) {
216 std::cerr <<
"vgl_p_matrix::get_focal:\n" 217 <<
" Nullspace dimension is " << svd()->singularities()
218 <<
"\n Returning an invalid point (a vector of zeros)\n";
222 vnl_matrix<T> ns = svd()->nullspace();
230 vnl_matrix_fixed<T,3,3> A;
231 vnl_vector_fixed<T,3> a;
239 for (
int r = 0; r < 3; ++r)
240 for (
int c = 0; c < 4; ++c) {
241 T d = r==c ? p_matrix_(r,c)-1 : p_matrix_(r,c);
242 if (std::fabs(d) > tol)
262 return p_matrix_. get(row_index, col_index);
270 for (
int row_index = 0; row_index < 3; row_index++)
271 for (
int col_index = 0; col_index < 4; col_index++)
272 *c_matrix++ = p_matrix_. get(row_index, col_index);
281 A->put(0,0, p_matrix_(0,0));
282 A->put(1,0, p_matrix_(1,0));
283 A->put(2,0, p_matrix_(2,0));
285 A->put(0,1, p_matrix_(0,1));
286 A->put(1,1, p_matrix_(1,1));
287 A->put(2,1, p_matrix_(2,1));
289 A->put(0,2, p_matrix_(0,2));
290 A->put(1,2, p_matrix_(1,2));
291 A->put(2,2, p_matrix_(2,2));
293 a->put(0, p_matrix_(0,3));
294 a->put(1, p_matrix_(1,3));
295 a->put(2, p_matrix_(2,3));
304 A->put(0,0, p_matrix_(0,0));
305 A->put(1,0, p_matrix_(1,0));
306 A->put(2,0, p_matrix_(2,0));
308 A->put(0,1, p_matrix_(0,1));
309 A->put(1,1, p_matrix_(1,1));
310 A->put(2,1, p_matrix_(2,1));
312 A->put(0,2, p_matrix_(0,2));
313 A->put(1,2, p_matrix_(1,2));
314 A->put(2,2, p_matrix_(2,2));
316 a->put(0, p_matrix_(0,3));
317 a->put(1, p_matrix_(1,3));
318 a->put(2, p_matrix_(2,3));
327 if (a->size() < 4) a->set_size(4);
328 a->put(0, p_matrix_(0, 0));
329 a->put(1, p_matrix_(0, 1));
330 a->put(2, p_matrix_(0, 2));
331 a->put(3, p_matrix_(0, 3));
333 if (b->size() < 4) b->set_size(4);
334 b->put(0, p_matrix_(1, 0));
335 b->put(1, p_matrix_(1, 1));
336 b->put(2, p_matrix_(1, 2));
337 b->put(3, p_matrix_(1, 3));
339 if (c->size() < 4) c->set_size(4);
340 c->put(0, p_matrix_(2, 0));
341 c->put(1, p_matrix_(2, 1));
342 c->put(2, p_matrix_(2, 2));
343 c->put(3, p_matrix_(2, 3));
351 vnl_vector_fixed<T,4>* b,
352 vnl_vector_fixed<T,4>* c)
const 354 a->put(0, p_matrix_(0, 0));
355 a->put(1, p_matrix_(0, 1));
356 a->put(2, p_matrix_(0, 2));
357 a->put(3, p_matrix_(0, 3));
359 b->put(0, p_matrix_(1, 0));
360 b->put(1, p_matrix_(1, 1));
361 b->put(2, p_matrix_(1, 2));
362 b->put(3, p_matrix_(1, 3));
364 c->put(0, p_matrix_(2, 0));
365 c->put(1, p_matrix_(2, 1));
366 c->put(2, p_matrix_(2, 2));
367 c->put(3, p_matrix_(2, 3));
376 p_matrix_.put(0, 0, a(0));
377 p_matrix_.put(0, 1, a(1));
378 p_matrix_.put(0, 2, a(2));
379 p_matrix_.put(0, 3, a(3));
381 p_matrix_.put(1, 0, b(0));
382 p_matrix_.put(1, 1, b(1));
383 p_matrix_.put(1, 2, b(2));
384 p_matrix_.put(1, 3, b(3));
386 p_matrix_.put(2, 0, c(0));
387 p_matrix_.put(2, 1, c(1));
388 p_matrix_.put(2, 2, c(2));
389 p_matrix_.put(2, 3, c(3));
400 for (
int row_index = 0; row_index < 3; row_index++)
401 for (
int col_index = 0; col_index < 4; col_index++)
402 p_matrix_. put(row_index, col_index, p_matrix [row_index][col_index]);
413 for (
int row_index = 0; row_index < 3; row_index++)
414 for (
int col_index = 0; col_index < 4; col_index++)
415 p_matrix_. put(row_index, col_index, *p++);
427 p_matrix_(0,0) = A(0,0);
428 p_matrix_(1,0) = A(1,0);
429 p_matrix_(2,0) = A(2,0);
431 p_matrix_(0,1) = A(0,1);
432 p_matrix_(1,1) = A(1,1);
433 p_matrix_(2,1) = A(2,1);
435 p_matrix_(0,2) = A(0,2);
436 p_matrix_(1,2) = A(1,2);
437 p_matrix_(2,2) = A(2,2);
439 p_matrix_(0,3) = a[0];
440 p_matrix_(1,3) = a[1];
441 p_matrix_(2,3) = a[2];
452 p_matrix_(0,0) = A(0,0);
453 p_matrix_(1,0) = A(1,0);
454 p_matrix_(2,0) = A(2,0);
456 p_matrix_(0,1) = A(0,1);
457 p_matrix_(1,1) = A(1,1);
458 p_matrix_(2,1) = A(2,1);
460 p_matrix_(0,2) = A(0,2);
461 p_matrix_(1,2) = A(1,2);
462 p_matrix_(2,2) = A(2,2);
464 p_matrix_(0,3) = a[0];
465 p_matrix_(1,3) = a[1];
466 p_matrix_(2,3) = a[2];
484 vnl_matrix_fixed<T,3,3> A;
485 vnl_vector_fixed<T,3> a;
487 T det = vnl_determinant(A);
490 #if 0 // Used to scale by 1/det, but it's a bad idea if det is small 491 if (std::fabs(det - 1) > 1e-8) {
492 std::cerr <<
"vgl_p_matrix::fix_cheirality: Flipping, determinant is " << det << std::endl;
510 vnl_vector_fixed<T,4> p = p_matrix_.get_row(2);
511 T
dot = hX.
x()*p[0]+hX.
y()*p[1]+hX.
z()*p[2]+hX.
w()*p[3];
530 T cond = svd()->W(0) / svd()->W(2);
532 std::cerr <<
"vgl_p_matrix::looks_conditioned: cond = " << cond <<
'\n';
551 #undef VGL_P_MATRIX_INSTANTIATE 552 #define VGL_P_MATRIX_INSTANTIATE(T) \ 553 template class vgl_p_matrix<T >; \ 554 template vgl_p_matrix<T > operator*(const vgl_p_matrix<T >& P, const vgl_h_matrix_3d<T >& H); \ 555 template std::ostream& operator<<(std::ostream& s, const vgl_p_matrix<T >& h); \ 556 template std::istream& operator>>(std::istream& s, vgl_p_matrix<T >& h) 558 #endif // vgl_p_matrix_hxx_
homogeneous plane in 3D projective space
const vnl_matrix_fixed< T, 3, 4 > & get_matrix() const
General 3x4 perspective projection matrix.
vgl_point_3d< Type > point1() const
vgl_p_matrix & flip_sign()
Change the overall sign of the P matrix.
Represents a homogeneous 2D line.
bool is_behind_camera(vgl_homg_point_3d< T > const &)
Return true if the 3D point X is behind the camera represented by this P.
vgl_point_3d< Type > point2() const
void get(vnl_matrix_fixed< T, 3, 3 > *A, vnl_vector_fixed< T, 3 > *a) const
Return the 3x3 matrix and 3x1 column vector of P = [A a].
bool read_ascii(std::istream &f)
Load from file.
vgl_homg_point_3d< T > get_focal() const
Return the 3D point representing the focal point of the camera.
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
vgl_h_matrix_3d< T > get_canonical_H() const
Return the 3D H-matrix s.t. P * H = [I 0].
bool is_canonical(T tol=0) const
Return true iff P is [I 0].
Represents a homogeneous 3D point.
void clear_svd() const
Discredit the cached svd.
static vgl_p_matrix read(const char *filename)
Load from file.
a point in 3D nonhomogeneous space
vnl_matrix_fixed< T, 3, 4 > p_matrix_
A class to hold a 3-d projective transformation matrix and to perform common operations using it e....
vgl_p_matrix & operator=(const vgl_p_matrix &)
Represents a 3D line segment using two points.
vgl_p_matrix()
Constructor. Set up a canonical P matrix.
vgl_p_matrix & set_identity()
Set the camera to an identity projection. X->u, Y->v.
vgl_p_matrix & set(vnl_matrix_fixed< T, 3, 4 > const &p_matrix)
Set the internal matrix using the 3x4 p_matrix.
vgl_homg_line_3d_2_points< T > backproject(vgl_homg_point_2d< T > const &x) const
Return the 3D line which is the backprojection of the specified image point, x.
vgl_p_matrix & set_rows(const vnl_vector_fixed< T, 4 > &a, const vnl_vector_fixed< T, 4 > &b, const vnl_vector_fixed< T, 4 > &c)
Set P = [a b c]' from its rows a, b, c.
vnl_matrix_fixed< T, 4, 4 > const & get_matrix() const
Return the 4x4 homography matrix.
std::istream & operator>>(std::istream &is, vgl_orient_box_3d< Type > &p)
Read box from stream.
vgl_homg_point_3d< T > backproject_pseudoinverse(vgl_homg_point_2d< T > const &x) const
Return the 3D point $\vec X$ which is $\vec X = P^+ \vec x$.
vgl_homg_point_1d< T > operator *(vnl_matrix_fixed< T, 2, 2 > const &m, vgl_homg_point_1d< T > const &p)
Transform a point through a 2x2 projective transformation matrix.
Represents a homogeneous 2D point.
vgl_p_matrix< T > postmultiply(vnl_matrix_fixed< T, 4, 4 > const &H) const
post-multiply this projection matrix with a 3-d projective transform.
vgl_homg_point_3d< Type > point_finite() const
Finite point (Could be an ideal point, if the whole line is at infinity.).
bool looks_conditioned()
Splendid hack that tries to detect if the P is an image-coords P or a normalized P.
void get_rows(vnl_vector< T > *a, vnl_vector< T > *b, vnl_vector< T > *c) const
Return the rows of P = [a b c]'.
vgl_p_matrix & fix_cheirality()
Scale P so determinant of first 3x3 is 1.
vgl_homg_point_2d< T > operator()(vgl_homg_point_3d< T > const &X) const
Return the image point which is the projection of the specified 3D point X.
vgl_p_matrix< T > premultiply(vnl_matrix_fixed< T, 3, 3 > const &H) const
pre-multiply this projection matrix with a 2-d projective transform.
vgl_homg_point_3d< Type > point_infinite() const
Infinite point: the intersection of the line with the plane at infinity.
Represents a homogeneous 3D line using two points.
vnl_svd< T > * svd() const
Compute the svd of this P and cache it, so that future operations that require it need not recompute ...