Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpHomography.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * Homography transformation.
32 */
33
39
40#include <stdio.h>
41
42#include <visp3/core/vpDebug.h>
43#include <visp3/core/vpMatrix.h>
44#include <visp3/core/vpRobust.h>
45#include <visp3/vision/vpHomography.h>
46
47// Exception
48#include <visp3/core/vpException.h>
49#include <visp3/core/vpMatrixException.h>
50
52
53vpHomography::vpHomography() : vpArray2D<double>(3, 3), m_aMb(), m_bP() { eye(); }
54
55vpHomography::vpHomography(const vpHomography &H) : vpArray2D<double>(3, 3), m_aMb(), m_bP() { *this = H; }
56
57vpHomography::vpHomography(const vpHomogeneousMatrix &aMb, const vpPlane &bP) : vpArray2D<double>(3, 3), m_aMb(), m_bP()
58{
59 buildFrom(aMb, bP);
60}
61
63 : vpArray2D<double>(3, 3), m_aMb(), m_bP()
64{
65 buildFrom(tu, atb, p);
66}
67
69 : vpArray2D<double>(3, 3), m_aMb(), m_bP()
70{
71 buildFrom(aRb, atb, p);
72}
73
74vpHomography::vpHomography(const vpPoseVector &arb, const vpPlane &p) : vpArray2D<double>(3, 3), m_aMb(), m_bP()
75{
76 buildFrom(arb, p);
77}
78
80{
81 insert(aMb);
82 insert(bP);
83 build();
84 return *this;
85}
86
88{
89 insert(tu);
90 insert(atb);
91 insert(p);
92 build();
93 return *this;
94}
95
97{
98 insert(aRb);
99 insert(atb);
100 insert(p);
101 build();
102 return *this;
103}
104
106{
107 double tx = arb[0], ty = arb[1], tz = arb[2], tux = arb[3], tuy = arb[4], tuz = arb[5];
108 m_aMb.buildFrom(tx, ty, tz, tux, tuy, tuz);
109 insert(p);
110 build();
111 return *this;
112}
113
114/*********************************************************************/
115
116void vpHomography::insert(const vpRotationMatrix &aRb) { m_aMb.insert(aRb); }
117
118void vpHomography::insert(const vpHomogeneousMatrix &M) { m_aMb = M; }
119
120void vpHomography::insert(const vpThetaUVector &tu)
121{
122 vpRotationMatrix aRb(tu);
123 m_aMb.insert(aRb);
124}
125
126void vpHomography::insert(const vpTranslationVector &atb) { m_aMb.insert(atb); }
127
128void vpHomography::insert(const vpPlane &bP) { m_bP = bP; }
129
130vpHomography vpHomography::inverse(double sv_threshold, unsigned int *rank) const
131{
132 vpMatrix M = (*this).convert();
133 vpMatrix Minv;
134 unsigned int r = M.pseudoInverse(Minv, sv_threshold);
135 if (rank != nullptr) {
136 *rank = r;
137 }
138
139 vpHomography H;
140 unsigned int nbRows = H.getRows();
141 unsigned int nbCols = H.getCols();
142 for (unsigned int i = 0; i < nbRows; ++i) {
143 for (unsigned int j = 0; j < nbCols; ++j) {
144 H[i][j] = Minv[i][j];
145 }
146 }
147 return H;
148}
149
150void vpHomography::inverse(vpHomography &bHa) const { bHa = inverse(); }
151
152void vpHomography::save(std::ofstream &f) const
153{
154 if (!f.fail()) {
155 f << *this;
156 }
157 else {
158 throw(vpException(vpException::ioError, "Cannot write the homography to the output stream"));
159 }
160}
161
163{
164 vpHomography Hp;
165 const unsigned int nbCols = 3, nbRows = 3;
166 for (unsigned int i = 0; i < nbRows; ++i) {
167 for (unsigned int j = 0; j < nbCols; ++j) {
168 double s = 0.;
169 for (unsigned int k = 0; k < nbCols; ++k) {
170 s += (*this)[i][k] * H[k][j];
171 }
172 Hp[i][j] = s;
173 }
174 }
175 return Hp;
176}
177
179{
180 const unsigned int requiredSize = 3;
181 if (b.size() != requiredSize) {
182 throw(vpException(vpException::dimensionError, "Cannot multiply an homography by a vector of dimension %d",
183 b.size()));
184 }
185
186 vpColVector a(requiredSize);
187 for (unsigned int i = 0; i < requiredSize; ++i) {
188 a[i] = 0.;
189 for (unsigned int j = 0; j < requiredSize; ++j) {
190 a[i] += (*this)[i][j] * b[j];
191 }
192 }
193
194 return a;
195}
196
198{
199 const unsigned int nbData = 9; // cols x rows = 3 x 3
200 vpHomography H;
201
202 for (unsigned int i = 0; i < nbData; ++i) {
203 H.data[i] = this->data[i] * v;
204 }
205
206 return H;
207}
208
210{
211 vpPoint a_P;
212 vpColVector v(3), v1(3);
213
214 v[0] = b_P.get_x();
215 v[1] = b_P.get_y();
216 v[2] = b_P.get_w();
217
218 v1[0] = ((*this)[0][0] * v[0]) + ((*this)[0][1] * v[1]) + ((*this)[0][2] * v[2]);
219 v1[1] = ((*this)[1][0] * v[0]) + ((*this)[1][1] * v[1]) + ((*this)[1][2] * v[2]);
220 v1[2] = ((*this)[2][0] * v[0]) + ((*this)[2][1] * v[1]) + ((*this)[2][2] * v[2]);
221
222 // v1 is equal to M v ;
223 a_P.set_x(v1[0]);
224 a_P.set_y(v1[1]);
225 a_P.set_w(v1[2]);
226
227 return a_P;
228}
229
231{
232 vpHomography H;
233 if (std::fabs(v) <= std::numeric_limits<double>::epsilon()) {
234 throw vpMatrixException(vpMatrixException::divideByZeroError, "Divide by zero in method /=(double v)");
235 }
236
237 double vinv = 1 / v;
238
239 const unsigned int nbData = 9; // cols x rows = 3 x 3
240 for (unsigned int i = 0; i < nbData; ++i) {
241 H.data[i] = this->data[i] * vinv;
242 }
243
244 return H;
245}
246
248{
249 if (std::fabs(v) <= std::numeric_limits<double>::epsilon()) {
250 throw vpMatrixException(vpMatrixException::divideByZeroError, "Divide by zero in method /=(double v)");
251 }
252
253 double vinv = 1 / v;
254
255 const unsigned int nbData = 9; // cols x rows = 3 x 3
256 for (unsigned int i = 0; i < nbData; ++i) {
257 data[i] *= vinv;
258 }
259
260 return *this;
261}
262
264{
265 const unsigned int nbCols = 3, nbRows = 3;
266 for (unsigned int i = 0; i < nbRows; ++i) {
267 for (unsigned int j = 0; j < nbCols; ++j) {
268 (*this)[i][j] = H[i][j];
269 }
270 }
271
272 m_aMb = H.m_aMb;
273 m_bP = H.m_bP;
274 return *this;
275}
276
278{
279 const unsigned int nbCols = 3, nbRows = 3;
280 if ((H.getRows() != nbRows) || (H.getCols() != nbCols)) {
281 throw(vpException(vpException::dimensionError, "The matrix is not an homography"));
282 }
283
284 for (unsigned int i = 0; i < nbRows; ++i) {
285 for (unsigned int j = 0; j < nbCols; ++j) {
286 (*this)[i][j] = H[i][j];
287 }
288 }
289
290 return *this;
291}
292
293void vpHomography::load(std::ifstream &f)
294{
295 const unsigned int nbCols = 3, nbRows = 3;
296 if (!f.fail()) {
297 for (unsigned int i = 0; i < nbRows; ++i) {
298 for (unsigned int j = 0; j < nbCols; ++j) {
299 f >> (*this)[i][j];
300 }
301 }
302 }
303 else {
304 throw(vpException(vpException::ioError, "Cannot read the homography from the input stream"));
305 }
306}
307
315void vpHomography::build()
316{
317 const unsigned int nbCols = 3, nbRows = 3;
318 vpColVector n(nbRows);
319 vpColVector atb(nbRows);
320 vpMatrix aRb(nbRows, nbCols);
321 for (unsigned int i = 0; i < nbRows; ++i) {
322 atb[i] = m_aMb[i][3];
323 for (unsigned int j = 0; j < nbCols; ++j) {
324 aRb[i][j] = m_aMb[i][j];
325 }
326 }
327
328 m_bP.getNormal(n);
329
330 double d = m_bP.getD();
331 vpMatrix aHb = aRb - ((atb * n.t()) / d); // the d used in the equation is such as nX=d is the
332 // plane equation. So if the plane is described by
333 // Ax+By+Cz+D=0, d=-D
334
335 for (unsigned int i = 0; i < nbRows; ++i) {
336 for (unsigned int j = 0; j < nbCols; ++j) {
337 (*this)[i][j] = aHb[i][j];
338 }
339 }
340}
341
342#ifndef DOXYGEN_SHOULD_SKIP_THIS
354void vpHomography::build(vpHomography &aHb, const vpHomogeneousMatrix &aMb, const vpPlane &bP)
355{
356 const unsigned int nbCols = 3, nbRows = 3;
357 vpColVector n(nbRows);
358 vpColVector atb(nbRows);
359 vpMatrix aRb(nbRows, nbCols);
360 for (unsigned int i = 0; i < nbRows; ++i) {
361 atb[i] = aMb[i][3];
362 for (unsigned int j = 0; j < nbCols; ++j) {
363 aRb[i][j] = aMb[i][j];
364 }
365 }
366
367 bP.getNormal(n);
368
369 double d = bP.getD();
370 vpMatrix aHb_ = aRb - ((atb * n.t()) / d); // the d used in the equation is such as nX=d is the
371 // plane equation. So if the plane is described by
372 // Ax+By+Cz+D=0, d=-D
373
374 for (unsigned int i = 0; i < nbRows; ++i) {
375 for (unsigned int j = 0; j < nbCols; ++j) {
376 aHb[i][j] = aHb_[i][j];
377 }
378 }
379}
380#endif
381
382double vpHomography::det() const
383{
384 return ((((*this)[0][0] * (((*this)[1][1] * (*this)[2][2]) - ((*this)[1][2] * (*this)[2][1]))) -
385 ((*this)[0][1] * (((*this)[1][0] * (*this)[2][2]) - ((*this)[1][2] * (*this)[2][0])))) +
386 ((*this)[0][2] * (((*this)[1][0] * (*this)[2][1]) - ((*this)[1][1] * (*this)[2][0]))));
387}
388
390{
391 const unsigned int nbCols = 3, nbRows = 3;
392 for (unsigned int i = 0; i < nbRows; ++i) {
393 for (unsigned int j = 0; j < nbCols; ++j) {
394 if (i == j) {
395 (*this)[i][j] = 1.0;
396 }
397 else {
398 (*this)[i][j] = 0.0;
399 }
400 }
401 }
402}
403
405{
406 double xa = iPa.get_u();
407 double ya = iPa.get_v();
409 double z = (xa * bGa[2][0]) + (ya * bGa[2][1]) + bGa[2][2];
410 double xb = ((xa * bGa[0][0]) + (ya * bGa[0][1]) + bGa[0][2]) / z;
411 double yb = ((xa * bGa[1][0]) + (ya * bGa[1][1]) + bGa[1][2]) / z;
412
413 vpImagePoint iPb(yb, xb);
414
415 return iPb;
416}
417
419{
420 double xa = Pa.get_x();
421 double ya = Pa.get_y();
422 double z = (xa * bHa[2][0]) + (ya * bHa[2][1]) + bHa[2][2];
423 double xb = ((xa * bHa[0][0]) + (ya * bHa[0][1]) + bHa[0][2]) / z;
424 double yb = ((xa * bHa[1][0]) + (ya * bHa[1][1]) + bHa[1][2]) / z;
425
426 vpPoint Pb;
427 Pb.set_x(xb);
428 Pb.set_y(yb);
429
430 return Pb;
431}
432
433
434void vpHomography::robust(const std::vector<double> &xb, const std::vector<double> &yb, const std::vector<double> &xa,
435 const std::vector<double> &ya, vpHomography &aHb, std::vector<bool> &inliers,
436 double &residual, double weights_threshold, unsigned int niter, bool normalization)
437{
438 unsigned int n = static_cast<unsigned int>(xb.size());
439 if ((yb.size() != n) || (xa.size() != n) || (ya.size() != n)) {
440 throw(vpException(vpException::dimensionError, "Bad dimension for robust homography estimation"));
441 }
442
443 // 4 point are required
444 const unsigned int nbRequiredPoints = 4;
445 if (n < nbRequiredPoints) {
446 throw(vpException(vpException::fatalError, "There must be at least 4 matched points"));
447 }
448
449 try {
450 std::vector<double> xan, yan, xbn, ybn;
451
452 double xg1 = 0., yg1 = 0., coef1 = 0., xg2 = 0., yg2 = 0., coef2 = 0.;
453
454 vpHomography aHbn;
455
456 if (normalization) {
457 vpHomography::hartleyNormalization(xb, yb, xbn, ybn, xg1, yg1, coef1);
458 vpHomography::hartleyNormalization(xa, ya, xan, yan, xg2, yg2, coef2);
459 }
460 else {
461 xbn = xb;
462 ybn = yb;
463 xan = xa;
464 yan = ya;
465 }
466
467 unsigned int nbLinesA = 2;
468 vpMatrix A(nbLinesA * n, 8);
469 vpColVector X(8);
470 vpColVector Y(nbLinesA * n);
471 vpMatrix W(nbLinesA * n, nbLinesA * n, 0); // Weight matrix
472
473 vpColVector w(nbLinesA * n);
474
475 // All the weights are set to 1 at the beginning to use a classical least
476 // square scheme
477 w = 1;
478 // Update the square matrix associated to the weights
479 for (unsigned int i = 0; i < (nbLinesA * n); ++i) {
480 W[i][i] = w[i];
481 }
482
483 // build matrix A
484 for (unsigned int i = 0; i < n; ++i) {
485 A[nbLinesA * i][0] = xbn[i];
486 A[nbLinesA * i][1] = ybn[i];
487 A[nbLinesA * i][2] = 1;
488 A[nbLinesA * i][3] = 0;
489 A[nbLinesA * i][4] = 0;
490 A[nbLinesA * i][5] = 0;
491 A[nbLinesA * i][6] = -xbn[i] * xan[i];
492 A[nbLinesA * i][7] = -ybn[i] * xan[i];
493
494 A[(nbLinesA * i) + 1][0] = 0;
495 A[(nbLinesA * i) + 1][1] = 0;
496 A[(nbLinesA * i) + 1][2] = 0;
497 A[(nbLinesA * i) + 1][3] = xbn[i];
498 A[(nbLinesA * i) + 1][4] = ybn[i];
499 A[(nbLinesA * i) + 1][5] = 1;
500 A[(nbLinesA * i) + 1][6] = -xbn[i] * yan[i];
501 A[(nbLinesA * i) + 1][7] = -ybn[i] * yan[i];
502
503 Y[nbLinesA * i] = xan[i];
504 Y[(nbLinesA * i) + 1] = yan[i];
505 }
506
507 vpMatrix WA;
508 vpMatrix WAp;
509 unsigned int iter = 0;
510 vpRobust r; // M-Estimator
511
512 while (iter < niter) {
513 WA = W * A;
514
515 X = WA.pseudoInverse(1e-26) * W * Y;
516 vpColVector residu;
517 residu = Y - (A * X);
518
519 // Compute the weights using the Tukey biweight M-Estimator
520 r.MEstimator(vpRobust::TUKEY, residu, w);
521
522 // Update the weights matrix
523 for (unsigned int i = 0; i < (n * nbLinesA); ++i) {
524 W[i][i] = w[i];
525 }
526 // Build the homography
527 for (unsigned int i = 0; i < 8; ++i) {
528 aHbn.data[i] = X[i];
529 }
530 aHbn[2][2] = 1;
531
532 ++iter;
533 }
534 inliers.resize(n);
535 unsigned int nbinliers = 0;
536 for (unsigned int i = 0; i < n; ++i) {
537 if ((w[i * 2] < weights_threshold) && (w[(i * 2) + 1] < weights_threshold)) {
538 inliers[i] = false;
539 }
540 else {
541 inliers[i] = true;
542 ++nbinliers;
543 }
544 }
545
546 if (normalization) {
547 // H after denormalization
548 vpHomography::hartleyDenormalization(aHbn, aHb, xg1, yg1, coef1, xg2, yg2, coef2);
549 }
550 else {
551 aHb = aHbn;
552 }
553
554 residual = 0;
555 vpColVector a(3), b(3), c(3);
556 for (unsigned int i = 0; i < n; ++i) {
557 if (inliers[i]) {
558 a[0] = xa[i];
559 a[1] = ya[i];
560 a[2] = 1;
561 b[0] = xb[i];
562 b[1] = yb[i];
563 b[2] = 1;
564
565 c = aHb * b;
566 c /= c[2];
567 residual += (a - c).sumSquare();
568 }
569 }
570
571 residual = sqrt(residual / nbinliers);
572 }
573 catch (...) {
574 throw(vpException(vpException::fatalError, "Cannot estimate an homography"));
575 }
576}
577
579{
580 vpImagePoint ipa;
581 double u = ipb.get_u();
582 double v = ipb.get_v();
583
584 double u_a = ((*this)[0][0] * u) + ((*this)[0][1] * v) + (*this)[0][2];
585 double v_a = ((*this)[1][0] * u) + ((*this)[1][1] * v) + (*this)[1][2];
586 double w_a = ((*this)[2][0] * u) + ((*this)[2][1] * v) + (*this)[2][2];
587
588 if (std::fabs(w_a) > std::numeric_limits<double>::epsilon()) {
589 ipa.set_u(u_a / w_a);
590 ipa.set_v(v_a / w_a);
591 }
592
593 return ipa;
594}
595
597{
598 const unsigned int nbRows = 3, nbCols = 3;
599 vpMatrix M(nbRows, nbCols);
600 for (unsigned int i = 0; i < nbRows; ++i) {
601 for (unsigned int j = 0; j < nbCols; ++j) {
602 M[i][j] = (*this)[i][j];
603 }
604 }
605
606 return M;
607}
608
610{
611 vpHomography H;
612 double px = cam.get_px();
613 double py = cam.get_py();
614 double u0 = cam.get_u0();
615 double v0 = cam.get_v0();
616 double one_over_px = cam.get_px_inverse();
617 double one_over_py = cam.get_py_inverse();
618 double h00 = (*this)[0][0], h01 = (*this)[0][1], h02 = (*this)[0][2];
619 double h10 = (*this)[1][0], h11 = (*this)[1][1], h12 = (*this)[1][2];
620 double h20 = (*this)[2][0], h21 = (*this)[2][1], h22 = (*this)[2][2];
621
622 double u0_one_over_px = u0 * one_over_px;
623 double v0_one_over_py = v0 * one_over_py;
624
625 double A = (h00 * one_over_px) - (h20 * u0_one_over_px);
626 double B = (h01 * one_over_px) - (h21 * u0_one_over_px);
627 double C = (h02 * one_over_px) - (h22 * u0_one_over_px);
628 double D = (h10 * one_over_py) - (h20 * v0_one_over_py);
629 double E = (h11 * one_over_py) - (h21 * v0_one_over_py);
630 double F = (h12 * one_over_py) - (h22 * v0_one_over_py);
631
632 H[0][0] = A * px;
633 H[1][0] = D * px;
634 H[2][0] = h20 * px;
635
636 H[0][1] = B * py;
637 H[1][1] = E * py;
638 H[2][1] = h21 * py;
639
640 H[0][2] = (A * u0) + (B * v0) + C;
641 H[1][2] = (D * u0) + (E * v0) + F;
642 H[2][2] = (h20 * u0) + (h21 * v0) + h22;
643
644 return H;
645}
646
648{
649 vpHomography H;
650 double px = cam.get_px();
651 double py = cam.get_py();
652 double u0 = cam.get_u0();
653 double v0 = cam.get_v0();
654 double one_over_px = cam.get_px_inverse();
655 double one_over_py = cam.get_py_inverse();
656 double h00 = (*this)[0][0], h01 = (*this)[0][1], h02 = (*this)[0][2];
657 double h10 = (*this)[1][0], h11 = (*this)[1][1], h12 = (*this)[1][2];
658 double h20 = (*this)[2][0], h21 = (*this)[2][1], h22 = (*this)[2][2];
659
660 double A = (h00 * px) + (u0 * h20);
661 double B = (h01 * px) + (u0 * h21);
662 double C = (h02 * px) + (u0 * h22);
663 double D = (h10 * py) + (v0 * h20);
664 double E = (h11 * py) + (v0 * h21);
665 double F = (h12 * py) + (v0 * h22);
666
667 H[0][0] = A * one_over_px;
668 H[1][0] = D * one_over_px;
669 H[2][0] = h20 * one_over_px;
670
671 H[0][1] = B * one_over_py;
672 H[1][1] = E * one_over_py;
673 H[2][1] = h21 * one_over_py;
674
675 double u0_one_over_px = u0 * one_over_px;
676 double v0_one_over_py = v0 * one_over_py;
677
678 H[0][2] = ((-A * u0_one_over_px) - (B * v0_one_over_py)) + C;
679 H[1][2] = ((-D * u0_one_over_px) - (E * v0_one_over_py)) + F;
680 H[2][2] = ((-h20 * u0_one_over_px) - (h21 * v0_one_over_py)) + h22;
681
682 return H;
683}
684
685END_VISP_NAMESPACE
unsigned int getCols() const
Definition vpArray2D.h:423
Type * data
Address of the first element of the data array.
Definition vpArray2D.h:149
unsigned int size() const
Return the number of elements of the 2D array.
Definition vpArray2D.h:435
unsigned int getRows() const
Definition vpArray2D.h:433
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ ioError
I/O error.
Definition vpException.h:67
@ dimensionError
Bad dimension.
Definition vpException.h:71
@ fatalError
Fatal error.
Definition vpException.h:72
@ divideByZeroError
Division by zero.
Definition vpException.h:70
Implementation of an homogeneous matrix and operations on such kind of matrices.
void insert(const vpRotationMatrix &R)
Implementation of an homography and operations on homographies.
vpHomography collineation2homography(const vpCameraParameters &cam) const
vpImagePoint projection(const vpImagePoint &ipb)
double det() const
vpHomography inverse(double sv_threshold=1e-16, unsigned int *rank=nullptr) const
vpHomography & operator/=(double v)
void save(std::ofstream &f) const
vpHomography operator*(const vpHomography &H) const
vpHomography operator/(const double &v) const
vpHomography & operator=(const vpHomography &H)
vpHomography homography2collineation(const vpCameraParameters &cam) const
vpMatrix convert() const
static vpImagePoint project(const vpCameraParameters &cam, const vpHomography &bHa, const vpImagePoint &iPa)
void load(std::ifstream &f)
static void robust(const std::vector< double > &xb, const std::vector< double > &yb, const std::vector< double > &xa, const std::vector< double > &ya, vpHomography &aHb, std::vector< bool > &inliers, double &residual, double weights_threshold=0.4, unsigned int niter=4, bool normalization=true)
vpHomography & buildFrom(const vpRotationMatrix &aRb, const vpTranslationVector &atb, const vpPlane &bP)
Construction from translation and rotation and a plane.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
double get_u() const
void set_u(double u)
void set_v(double v)
double get_v() const
error that can be emitted by the vpMatrix class and its derivatives
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
vpMatrix pseudoInverse(double svThreshold=1e-6) const
This class defines the container for a plane geometrical structure.
Definition vpPlane.h:56
double getD() const
Definition vpPlane.h:106
vpColVector getNormal() const
Definition vpPlane.cpp:311
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition vpPoint.h:79
double get_w() const
Get the point w coordinate in the image plane.
Definition vpPoint.cpp:431
void set_x(double x)
Set the point x coordinate in the image plane.
Definition vpPoint.cpp:471
double get_y() const
Get the point y coordinate in the image plane.
Definition vpPoint.cpp:429
double get_x() const
Get the point x coordinate in the image plane.
Definition vpPoint.cpp:427
void set_y(double y)
Set the point y coordinate in the image plane.
Definition vpPoint.cpp:473
void set_w(double w)
Set the point w coordinate in the image plane.
Definition vpPoint.cpp:475
Implementation of a pose vector and operations on poses.
vpPoseVector & buildFrom(const double &tx, const double &ty, const double &tz, const double &tux, const double &tuy, const double &tuz)
Contains an M-estimator and various influence function.
Definition vpRobust.h:84
@ TUKEY
Tukey influence function.
Definition vpRobust.h:89
Implementation of a rotation matrix and operations on such kind of matrices.
Implementation of a rotation vector as axis-angle minimal representation.
Class that consider the case of a translation vector.