Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpHomographyVVS.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
34#include <iostream>
35#include <visp3/core/vpExponentialMap.h>
36#include <visp3/core/vpHomogeneousMatrix.h>
37#include <visp3/core/vpMath.h>
38#include <visp3/core/vpMatrix.h>
39#include <visp3/core/vpPlane.h>
40#include <visp3/core/vpPoint.h>
41#include <visp3/core/vpRobust.h>
42#include <visp3/vision/vpHomography.h>
43
45
46const double vpHomography::m_threshold_rotation = 1e-7;
47const double vpHomography::m_threshold_displacement = 1e-18;
48
49#ifndef DOXYGEN_SHOULD_SKIP_THIS
50
51static void updatePoseRotation(vpColVector &dx, vpHomogeneousMatrix &mati)
52{
54 const unsigned int val_3 = 3;
55
56 double s = sqrt((dx[0] * dx[0]) + (dx[1] * dx[1]) + (dx[2] * dx[2]));
57 if (s > 1.e-25) {
58 double u[3];
59
60 for (unsigned int i = 0; i < val_3; ++i) {
61 u[i] = dx[i] / s;
62 }
63 double sinu = sin(s);
64 double cosi = cos(s);
65 double mcosi = 1 - cosi;
66 rd[0][0] = cosi + (mcosi * u[0] * u[0]);
67 rd[0][1] = (-sinu * u[2]) + (mcosi * u[0] * u[1]);
68 rd[0][2] = (sinu * u[1]) + (mcosi * u[0] * u[2]);
69 rd[1][0] = (sinu * u[2]) + (mcosi * u[1] * u[0]);
70 rd[1][1] = cosi + (mcosi * u[1] * u[1]);
71 rd[1][2] = (-sinu * u[0]) + (mcosi * u[1] * u[2]);
72 rd[2][0] = (-sinu * u[1]) + (mcosi * u[2] * u[0]);
73 rd[2][1] = (sinu * u[0]) + (mcosi * u[2] * u[1]);
74 rd[2][2] = cosi + (mcosi * u[2] * u[2]);
75 }
76 else {
77 for (unsigned int i = 0; i < val_3; ++i) {
78 for (unsigned int j = 0; j < val_3; ++j) {
79 rd[i][j] = 0.0;
80 }
81 rd[i][i] = 1.0;
82 }
83 }
84
86 Delta.insert(rd);
87
88 mati = Delta.inverse() * mati;
89}
90
91double vpHomography::computeRotation(unsigned int nbpoint, vpPoint *c1P, vpPoint *c2P, vpHomogeneousMatrix &c2Mc1,
92 int userobust)
93{
94 vpColVector e(2);
95 double r_1 = -1;
96
97 vpColVector p2(3);
98 vpColVector p1(3);
99 vpColVector Hp2(3);
100 vpColVector Hp1(3);
101
102 vpMatrix H2(2, 3);
103 vpColVector e2(2);
104 vpMatrix H1(2, 3);
105 vpColVector e1(2);
106
107 bool only_1 = false;
108 bool only_2 = false;
109 int iter = 0;
110 const unsigned int val_3 = 3;
111
112 unsigned int n = 0;
113 for (unsigned int i = 0; i < nbpoint; ++i) {
114 // Check if c2P[i].get_x() and c1P[i].get_x() are different from -1
115 if ((std::fabs(c2P[i].get_x() + 1) > std::fabs(vpMath::maximum(c2P[i].get_x(), 1.))) &&
116 (std::fabs(c1P[i].get_x() + 1) > std::fabs(vpMath::maximum(c1P[i].get_x(), 1.)))) {
117 ++n;
118 }
119 }
120 if ((!only_1) && (!only_2)) {
121 n *= 2;
122 }
123
124 vpRobust robust;
125 vpColVector res(n);
126 vpColVector w(n);
127 w = 1;
128 robust.setMinMedianAbsoluteDeviation(0.00001);
129 vpMatrix W(2 * n, 2 * n);
130 W = 0;
131 vpMatrix c2Rc1(3, 3);
132 double r = 0;
133 bool stop = false;
134 while ((vpMath::equal(r_1, r, m_threshold_rotation) == false) && (stop == false)) {
135
136 r_1 = r;
137 // compute current position
138
139 // Change frame (current)
140 for (unsigned int i = 0; i < val_3; ++i) {
141 for (unsigned int j = 0; j < val_3; ++j) {
142 c2Rc1[i][j] = c2Mc1[i][j];
143 }
144 }
145
146 vpMatrix L(2, 3), Lp;
147 int k = 0;
148 for (unsigned int i = 0; i < nbpoint; ++i) {
149 if ((std::fabs(c2P[i].get_x() + 1) > std::fabs(vpMath::maximum(c2P[i].get_x(), 1.))) &&
150 (std::fabs(c1P[i].get_x() + 1) > std::fabs(vpMath::maximum(c1P[i].get_x(), 1.)))) {
151 p2[0] = c2P[i].get_x();
152 p2[1] = c2P[i].get_y();
153 p2[2] = 1.0;
154 p1[0] = c1P[i].get_x();
155 p1[1] = c1P[i].get_y();
156 p1[2] = 1.0;
157
158 Hp2 = c2Rc1.t() * p2; // p2 = Hp1
159 Hp1 = c2Rc1 * p1; // p1 = Hp2
160
161 Hp2 /= Hp2[2]; // normalization
162 Hp1 /= Hp1[2];
163
164 // set up the interaction matrix
165 double x = Hp2[0];
166 double y = Hp2[1];
167
168 H2[0][0] = x * y;
169 H2[0][1] = -(1 + (x * x));
170 H2[0][2] = y;
171 H2[1][0] = 1 + (y * y);
172 H2[1][1] = -x * y;
173 H2[1][2] = -x;
174 H2 *= -1;
175 H2 = H2 * c2Rc1.t();
176
177 // Set up the error vector
178 e2[0] = Hp2[0] - c1P[i].get_x();
179 e2[1] = Hp2[1] - c1P[i].get_y();
180
181 // set up the interaction matrix
182 x = Hp1[0];
183 y = Hp1[1];
184
185 H1[0][0] = x * y;
186 H1[0][1] = -(1 + (x * x));
187 H1[0][2] = y;
188 H1[1][0] = 1 + (y * y);
189 H1[1][1] = -x * y;
190 H1[1][2] = -x;
191
192 // Set up the error vector
193 e1[0] = Hp1[0] - c2P[i].get_x();
194 e1[1] = Hp1[1] - c2P[i].get_y();
195
196 if (only_2) {
197 if (k == 0) {
198 L = H2;
199 e = e2;
200 }
201 else {
202 L = vpMatrix::stack(L, H2);
203 e = vpColVector::stack(e, e2);
204 }
205 }
206 else if (only_1) {
207 if (k == 0) {
208 L = H1;
209 e = e1;
210 }
211 else {
212 L = vpMatrix::stack(L, H1);
213 e = vpColVector::stack(e, e1);
214 }
215 }
216 else {
217 if (k == 0) {
218 L = H2;
219 e = e2;
220 }
221 else {
222 L = vpMatrix::stack(L, H2);
223 e = vpColVector::stack(e, e2);
224 }
225 L = vpMatrix::stack(L, H1);
226 e = vpColVector::stack(e, e1);
227 }
228
229 ++k;
230 }
231 }
232
233 if (userobust) {
234 for (unsigned int l = 0; l < n; ++l) {
235 res[l] = vpMath::sqr(e[2 * l]) + vpMath::sqr(e[(2 * l)+ 1]);
236 }
237 robust.MEstimator(vpRobust::TUKEY, res, w);
238
239 // compute the pseudo inverse of the interaction matrix
240 for (unsigned int l = 0; l < n; ++l) {
241 W[2 * l][2 * l] = w[l];
242 W[(2 * l) + 1][(2 * l) + 1] = w[l];
243 }
244 }
245 else {
246 for (unsigned int l = 0; l < (2 * n); ++l) {
247 W[l][l] = 1;
248 }
249 }
250 L.pseudoInverse(Lp, 1e-6);
251 // Compute the camera velocity
252 vpColVector c2rc1, v(6);
253
254 c2rc1 = -2 * Lp * W * e;
255 for (unsigned int i = 0; i < val_3; ++i) {
256 v[i + 3] = c2rc1[i];
257 }
258
259 // only for simulation
260
261 updatePoseRotation(c2rc1, c2Mc1);
262 r = e.sumSquare();
263
264 if (((W * e).sumSquare() < 1e-10) || (iter > 25)) {
265 stop = true;
266 }
267 ++iter;
268 }
269
270 return (W * e).sumSquare();
271}
272
273static void getPlaneInfo(vpPlane &oN, vpHomogeneousMatrix &cMo, vpColVector &cN, double &cd)
274{
275 double A1 = (cMo[0][0] * oN.getA()) + (cMo[0][1] * oN.getB()) + (cMo[0][2] * oN.getC());
276 double B1 = (cMo[1][0] * oN.getA()) + (cMo[1][1] * oN.getB()) + (cMo[1][2] * oN.getC());
277 double C1 = (cMo[2][0] * oN.getA()) + (cMo[2][1] * oN.getB()) + (cMo[2][2] * oN.getC());
278 double D1 = oN.getD() - ((cMo[0][3] * A1) + (cMo[1][3] * B1) + (cMo[2][3] * C1));
279
280 cN.resize(3);
281 cN[0] = A1;
282 cN[1] = B1;
283 cN[2] = C1;
284 cd = -D1;
285}
286
287double vpHomography::computeDisplacement(unsigned int nbpoint, vpPoint *c1P, vpPoint *c2P, vpPlane &oN,
288 vpHomogeneousMatrix &c2Mc1, vpHomogeneousMatrix &c1Mo, int userobust)
289{
290 vpColVector e(2);
291 double r_1 = -1;
292
293 vpColVector p2(3);
294 vpColVector p1(3);
295 vpColVector Hp2(3);
296 vpColVector Hp1(3);
297
298 vpMatrix H2(2, 6);
299 vpColVector e2(2);
300 vpMatrix H1(2, 6);
301 vpColVector e1(2);
302
303 bool only_1 = true;
304 bool only_2 = false;
305 int iter = 0;
306 unsigned int n = 0;
307 n = nbpoint;
308
309 vpRobust robust;
310 vpColVector res(n);
311 vpColVector w(n);
312 w = 1;
313 robust.setMinMedianAbsoluteDeviation(0.00001);
314 vpMatrix W(2 * n, 2 * n);
315 W = 0;
316
317 vpColVector N1(3), N2(3);
318 double d1, d2;
319
320 double r = 1e10;
321 iter = 0;
322 vpMatrix sTR;
323 bool stop = false;
324 while ((!vpMath::equal(r_1, r, m_threshold_displacement)) && (stop == false)) {
325 r_1 = r;
326 // compute current position
327
328 // Change frame (current)
329 vpHomogeneousMatrix c1Mc2, c2Mo;
330 vpRotationMatrix c1Rc2, c2Rc1;
331 vpTranslationVector c1Tc2, c2Tc1;
332 c1Mc2 = c2Mc1.inverse();
333 c2Mc1.extract(c2Rc1);
334 c2Mc1.extract(c2Tc1);
335 c2Mc1.extract(c1Rc2);
336 c1Mc2.extract(c1Tc2);
337
338 c2Mo = c2Mc1 * c1Mo;
339
340 getPlaneInfo(oN, c1Mo, N1, d1);
341 getPlaneInfo(oN, c2Mo, N2, d2);
342
343 vpMatrix L(2, 3), Lp;
344 int k = 0;
345 for (unsigned int i = 0; i < nbpoint; ++i) {
346 p2[0] = c2P[i].get_x();
347 p2[1] = c2P[i].get_y();
348 p2[2] = 1.0;
349 p1[0] = c1P[i].get_x();
350 p1[1] = c1P[i].get_y();
351 p1[2] = 1.0;
352
353 vpMatrix H(3, 3);
354
355 Hp2 = (static_cast<vpMatrix>(c1Rc2) + ((c1Tc2 * N2.t()) / d2)) * p2; // p2 = Hp1
356 Hp1 = (static_cast<vpMatrix>(c2Rc1) + ((c2Tc1 * N1.t()) / d1)) * p1; // p1 = Hp2
357
358 Hp2 /= Hp2[2]; // normalization
359 Hp1 /= Hp1[2];
360
361 // set up the interaction matrix
362 double x = Hp2[0];
363 double y = Hp2[1];
364 double Z1;
365
366 Z1 = ((N1[0] * x) + (N1[1] * y) + N1[2]) / d1; // 1/z
367
368 H2[0][0] = -Z1;
369 H2[0][1] = 0;
370 H2[0][2] = x * Z1;
371 H2[1][0] = 0;
372 H2[1][1] = -Z1;
373 H2[1][2] = y * Z1;
374 H2[0][3] = x * y;
375 H2[0][4] = -(1 + (x * x));
376 H2[0][5] = y;
377 H2[1][3] = 1 + (y * y);
378 H2[1][4] = -x * y;
379 H2[1][5] = -x;
380 H2 *= -1;
381
382 vpMatrix c1CFc2(6, 6);
383
384 sTR = c1Tc2.skew() * c1Rc2;
385 for (unsigned int k_ = 0; k_ < 3; ++k_) {
386 for (unsigned int l = 0; l < 3; ++l) {
387 c1CFc2[k_][l] = c1Rc2[k_][l];
388 c1CFc2[k_ + 3][l + 3] = c1Rc2[k_][l];
389 c1CFc2[k_][l + 3] = sTR[k_][l];
390 }
391 }
392
393 H2 = H2 * c1CFc2;
394
395 // Set up the error vector
396 e2[0] = Hp2[0] - c1P[i].get_x();
397 e2[1] = Hp2[1] - c1P[i].get_y();
398
399 x = Hp1[0];
400 y = Hp1[1];
401
402 Z1 = ((N2[0] * x) + (N2[1] * y) + N2[2]) / d2; // 1/z
403
404 H1[0][0] = -Z1;
405 H1[0][1] = 0;
406 H1[0][2] = x * Z1;
407 H1[1][0] = 0;
408 H1[1][1] = -Z1;
409 H1[1][2] = y * Z1;
410 H1[0][3] = x * y;
411 H1[0][4] = -(1 + (x * x));
412 H1[0][5] = y;
413 H1[1][3] = 1 + (y * y);
414 H1[1][4] = -x * y;
415 H1[1][5] = -x;
416
417 // Set up the error vector
418 e1[0] = Hp1[0] - c2P[i].get_x();
419 e1[1] = Hp1[1] - c2P[i].get_y();
420
421 if (only_2) {
422 if (k == 0) {
423 L = H2;
424 e = e2;
425 }
426 else {
427 L = vpMatrix::stack(L, H2);
428 e = vpColVector::stack(e, e2);
429 }
430 }
431 else if (only_1) {
432 if (k == 0) {
433 L = H1;
434 e = e1;
435 }
436 else {
437 L = vpMatrix::stack(L, H1);
438 e = vpColVector::stack(e, e1);
439 }
440 }
441 else {
442 if (k == 0) {
443 L = H2;
444 e = e2;
445 }
446 else {
447 L = vpMatrix::stack(L, H2);
448 e = vpColVector::stack(e, e2);
449 }
450 L = vpMatrix::stack(L, H1);
451 e = vpColVector::stack(e, e1);
452 }
453
454 ++k;
455 }
456
457 if (userobust) {
458 for (unsigned int l = 0; l < n; ++l) {
459 res[l] = vpMath::sqr(e[2 * l]) + vpMath::sqr(e[(2 * l)+ 1]);
460 }
461 robust.MEstimator(vpRobust::TUKEY, res, w);
462
463 // compute the pseudo inverse of the interaction matrix
464 for (unsigned int l = 0; l < n; ++l) {
465 W[2 * l][2 * l] = w[l];
466 W[(2 * l) + 1][(2 * l) + 1] = w[l];
467 }
468 }
469 else {
470 for (unsigned int l = 0; l < (2 * n); ++l) {
471 W[l][l] = 1;
472 }
473 }
474 (W * L).pseudoInverse(Lp, 1e-16);
475 // Compute the camera velocity
476 vpColVector c2Tcc1;
477
478 c2Tcc1 = -1 * Lp * W * e;
479
480 // only for simulation
481
482 c2Mc1 = vpExponentialMap::direct(c2Tcc1).inverse() * c2Mc1;
483 r = (W * e).sumSquare();
484
485 if ((r < 1e-15) || (iter > 1000) || (r > r_1)) {
486 stop = true;
487 }
488 ++iter;
489 }
490
491 return (W * e).sumSquare();
492}
493
494double vpHomography::computeDisplacement(unsigned int nbpoint, vpPoint *c1P, vpPoint *c2P, vpPlane *oN,
495 vpHomogeneousMatrix &c2Mc1, vpHomogeneousMatrix &c1Mo, int userobust)
496{
497
498 vpColVector e(2);
499 double r_1 = -1;
500
501 vpColVector p2(3);
502 vpColVector p1(3);
503 vpColVector Hp2(3);
504 vpColVector Hp1(3);
505
506 vpMatrix H2(2, 6);
507 vpColVector e2(2);
508 vpMatrix H1(2, 6);
509 vpColVector e1(2);
510
511 bool only_1 = true;
512 bool only_2 = false;
513 int iter = 0;
514 unsigned int i;
515 unsigned int n = 0;
516 n = nbpoint;
517
518 vpRobust robust;
519 vpColVector res(n);
520 vpColVector w(n);
521 w = 1;
522 robust.setMinMedianAbsoluteDeviation(0.00001);
523 vpMatrix W(2 * n, 2 * n);
524 W = 0;
525
526 vpColVector N1(3), N2(3);
527 double d1, d2;
528
529 double r = 1e10;
530 iter = 0;
531 vpMatrix sTR;
532 bool stop = false;
533 while ((!vpMath::equal(r_1, r, m_threshold_displacement)) && (stop == false)) {
534 r_1 = r;
535 // compute current position
536
537 // Change frame (current)
538 vpHomogeneousMatrix c1Mc2, c2Mo;
539 vpRotationMatrix c1Rc2, c2Rc1;
540 vpTranslationVector c1Tc2, c2Tc1;
541 c1Mc2 = c2Mc1.inverse();
542 c2Mc1.extract(c2Rc1);
543 c2Mc1.extract(c2Tc1);
544 c2Mc1.extract(c1Rc2);
545 c1Mc2.extract(c1Tc2);
546
547 c2Mo = c2Mc1 * c1Mo;
548
549 vpMatrix L(2, 3), Lp;
550 int k = 0;
551 for (i = 0; i < nbpoint; ++i) {
552 getPlaneInfo(oN[i], c1Mo, N1, d1);
553 getPlaneInfo(oN[i], c2Mo, N2, d2);
554 p2[0] = c2P[i].get_x();
555 p2[1] = c2P[i].get_y();
556 p2[2] = 1.0;
557 p1[0] = c1P[i].get_x();
558 p1[1] = c1P[i].get_y();
559 p1[2] = 1.0;
560
561 vpMatrix H(3, 3);
562
563 Hp2 = (static_cast<vpMatrix>(c1Rc2) + ((c1Tc2 * N2.t()) / d2)) * p2; // p2 = Hp1
564 Hp1 = (static_cast<vpMatrix>(c2Rc1) + ((c2Tc1 * N1.t()) / d1)) * p1; // p1 = Hp2
565
566 Hp2 /= Hp2[2]; // normalization
567 Hp1 /= Hp1[2];
568
569 // set up the interaction matrix
570 double x = Hp2[0];
571 double y = Hp2[1];
572 double Z1;
573
574 Z1 = ((N1[0] * x) + (N1[1] * y) + N1[2]) / d1; // 1/z
575
576 H2[0][0] = -Z1;
577 H2[0][1] = 0;
578 H2[0][2] = x * Z1;
579 H2[1][0] = 0;
580 H2[1][1] = -Z1;
581 H2[1][2] = y * Z1;
582 H2[0][3] = x * y;
583 H2[0][4] = -(1 + (x * x));
584 H2[0][5] = y;
585 H2[1][3] = 1 + (y * y);
586 H2[1][4] = -x * y;
587 H2[1][5] = -x;
588 H2 *= -1;
589
590 vpMatrix c1CFc2(6, 6);
591
592 sTR = c1Tc2.skew() * static_cast<vpMatrix>(c1Rc2);
593 for (unsigned int k_ = 0; k_ < 3; ++k_) {
594 for (unsigned int l = 0; l < 3; ++l) {
595 c1CFc2[k_][l] = c1Rc2[k_][l];
596 c1CFc2[k_ + 3][l + 3] = c1Rc2[k_][l];
597 c1CFc2[k_][l + 3] = sTR[k_][l];
598 }
599 }
600
601 H2 = H2 * c1CFc2;
602
603 // Set up the error vector
604 e2[0] = Hp2[0] - c1P[i].get_x();
605 e2[1] = Hp2[1] - c1P[i].get_y();
606
607 x = Hp1[0];
608 y = Hp1[1];
609
610 Z1 = ((N2[0] * x) + (N2[1] * y) + N2[2]) / d2; // 1/z
611
612 H1[0][0] = -Z1;
613 H1[0][1] = 0;
614 H1[0][2] = x * Z1;
615 H1[1][0] = 0;
616 H1[1][1] = -Z1;
617 H1[1][2] = y * Z1;
618 H1[0][3] = x * y;
619 H1[0][4] = -(1 + (x * x));
620 H1[0][5] = y;
621 H1[1][3] = 1 + (y * y);
622 H1[1][4] = -x * y;
623 H1[1][5] = -x;
624
625 // Set up the error vector
626 e1[0] = Hp1[0] - c2P[i].get_x();
627 e1[1] = Hp1[1] - c2P[i].get_y();
628
629 if (only_2) {
630 if (k == 0) {
631 L = H2;
632 e = e2;
633 }
634 else {
635 L = vpMatrix::stack(L, H2);
636 e = vpColVector::stack(e, e2);
637 }
638 }
639 else if (only_1) {
640 if (k == 0) {
641 L = H1;
642 e = e1;
643 }
644 else {
645 L = vpMatrix::stack(L, H1);
646 e = vpColVector::stack(e, e1);
647 }
648 }
649 else {
650 if (k == 0) {
651 L = H2;
652 e = e2;
653 }
654 else {
655 L = vpMatrix::stack(L, H2);
656 e = vpColVector::stack(e, e2);
657 }
658 L = vpMatrix::stack(L, H1);
659 e = vpColVector::stack(e, e1);
660 }
661
662 ++k;
663 }
664
665 if (userobust) {
666 for (unsigned int k_ = 0; k_ < n; ++k_) {
667 res[k_] = vpMath::sqr(e[2 * k_]) + vpMath::sqr(e[(2 * k_) + 1]);
668 }
669 robust.MEstimator(vpRobust::TUKEY, res, w);
670
671 // compute the pseudo inverse of the interaction matrix
672 for (unsigned int k_ = 0; k_ < n; ++k_) {
673 W[2 * k_][2 * k_] = w[k_];
674 W[(2 * k_) + 1][(2 * k_) + 1] = w[k_];
675 }
676 }
677 else {
678 for (unsigned int k_ = 0; k_ < (2 * n); ++k_) {
679 W[k_][k_] = 1;
680 }
681 }
682 (W * L).pseudoInverse(Lp, 1e-16);
683 // Compute the camera velocity
684 vpColVector c2Tcc1;
685
686 c2Tcc1 = -1 * Lp * W * e;
687
688 // only for simulation
689
690 c2Mc1 = vpExponentialMap::direct(c2Tcc1).inverse() * c2Mc1;
691 r = (W * e).sumSquare();
692
693 if ((r < 1e-15) || (iter > 1000) || (r > r_1)) {
694 stop = true;
695 }
696 ++iter;
697 }
698
699 return (W * e).sumSquare();
700}
701
702#endif //#ifndef DOXYGEN_SHOULD_SKIP_THIS
703
704END_VISP_NAMESPACE
Implementation of column vector and the associated operations.
void stack(double d)
void resize(unsigned int i, bool flagNullify=true)
static vpHomogeneousMatrix direct(const vpColVector &v)
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix inverse() const
void extract(vpRotationMatrix &R) const
void insert(const vpRotationMatrix &R)
void computeDisplacement(vpRotationMatrix &aRb, vpTranslationVector &atb, vpColVector &n)
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)
static Type maximum(const Type &a, const Type &b)
Definition vpMath.h:257
static double sqr(double x)
Definition vpMath.h:203
static bool equal(double x, double y, double threshold=0.001)
Definition vpMath.h:470
void stack(const vpMatrix &A)
double sumSquare() const
This class defines the container for a plane geometrical structure.
Definition vpPlane.h:56
double getD() const
Definition vpPlane.h:106
double getA() const
Definition vpPlane.h:100
double getC() const
Definition vpPlane.h:104
double getB() const
Definition vpPlane.h:102
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_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
@ TUKEY
Tukey influence function.
Definition vpRobust.h:89
Implementation of a rotation matrix and operations on such kind of matrices.