45 #include <visp3/core/vpDebug.h>
46 #include <visp3/core/vpMatrixException.h>
47 #include <visp3/vision/vpHomography.h>
52 #ifndef DOXYGEN_SHOULD_SKIP_THIS
53 const double eps = 1e-6;
88 void HLM(
unsigned int q_cible,
unsigned int nbpt,
double *xm,
double *ym,
double *xmi,
double *ymi,
vpMatrix &H);
90 void HLM(
unsigned int q_cible,
const std::vector<double> &xm,
const std::vector<double> &ym,
91 const std::vector<double> &xmi,
const std::vector<double> &ymi,
vpMatrix &H);
100 for (
unsigned int i = 0; i < 3; i++) {
101 for (
unsigned int j = 0; j < 3; j++) {
102 M[j][i] = p[pts_ref[i]][j];
103 Md[j][i] = pd[pts_ref[i]][j];
111 if (pts_ref[3] > 0) {
115 for (
unsigned int i = 0; i < 3; i++) {
116 for (
unsigned int j = 0; j < 3; j++) {
117 lamb_cour[i] = Mp[i][j] * p[pts_ref[3]][j];
118 lamb_des[i] = Mdp[i][j] * pd[pts_ref[3]][j];
122 for (
unsigned int i = 0; i < 3; i++) {
123 for (
unsigned int j = 0; j < 3; j++) {
124 M[i][j] = M[i][j] * lamb_cour[j];
125 Md[i][j] = Md[i][j] * lamb_des[j];
135 unsigned int cont_pts = 0;
136 for (
unsigned int k = 0; k < nb_pts; k++) {
137 if ((pts_ref[0] != k) && (pts_ref[1] != k) && (pts_ref[2] != k)) {
138 for (
unsigned int i = 0; i < 3; i++) {
139 pn[cont_pts][i] = 0.0;
140 pnd[cont_pts][i] = 0.0;
141 for (
unsigned int j = 0; j < 3; j++) {
142 pn[cont_pts][i] = pn[cont_pts][i] + Mp[i][j] * p[k][j];
143 pnd[cont_pts][i] = pnd[cont_pts][i] + Mdp[i][j] * pd[k][j];
146 cont_pts = cont_pts + 1;
181 unsigned int contZeros, vect;
189 for (
unsigned int j = 0; j < nb_pts; j++) {
193 M[3 * j][3] = -points_des[j][0] * points_cour[j][2];
194 M[3 * j][4] = -points_des[j][1] * points_cour[j][2];
195 M[3 * j][5] = -points_des[j][2] * points_cour[j][2];
196 M[3 * j][6] = points_des[j][0] * points_cour[j][1];
197 M[3 * j][7] = points_des[j][1] * points_cour[j][1];
198 M[3 * j][8] = points_des[j][2] * points_cour[j][1];
200 M[3 * j + 1][0] = points_des[j][0] * points_cour[j][2];
201 M[3 * j + 1][1] = points_des[j][1] * points_cour[j][2];
202 M[3 * j + 1][2] = points_des[j][2] * points_cour[j][2];
206 M[3 * j + 1][6] = -points_des[j][0] * points_cour[j][0];
207 M[3 * j + 1][7] = -points_des[j][1] * points_cour[j][0];
208 M[3 * j + 1][8] = -points_des[j][2] * points_cour[j][0];
210 M[3 * j + 2][0] = -points_des[j][0] * points_cour[j][1];
211 M[3 * j + 2][1] = -points_des[j][1] * points_cour[j][1];
212 M[3 * j + 2][2] = -points_des[j][2] * points_cour[j][1];
213 M[3 * j + 2][3] = points_des[j][0] * points_cour[j][0];
214 M[3 * j + 2][4] = points_des[j][1] * points_cour[j][0];
215 M[3 * j + 2][5] = points_des[j][2] * points_cour[j][0];
236 contZeros = contZeros + 1;
238 for (
unsigned int j = 1; j < 9; j++) {
239 if (sv[j] < vals_inf) {
244 contZeros = contZeros + 1;
256 for (
unsigned int i = 0; i < 3; i++) {
257 for (
unsigned int j = 0; j < 3; j++) {
258 H[i][j] = V[3 * i + j][vect];
288 unsigned int pts_ref[4];
316 changeFrame(pts_ref, nb_pts, pd, p, pnd, pn, M, Mdp);
318 unsigned int cont_pts = nb_pts - 3;
332 for (
unsigned int i = 0; i < nc; i++)
333 for (
unsigned int j = 0; j < nc; j++)
349 unsigned int cont = 0;
350 for (
unsigned int i = 0; i < nb_pts - 5; i++) {
351 for (
unsigned int j = i + 1; j < nb_pts - 4; j++) {
352 for (
unsigned int k = j + 1; k < nb_pts - 3; k++) {
354 C[0] = pn[i][2] * pn[j][2] * pn[k][1] * pnd[k][0]
355 * (pnd[j][0] * pnd[i][1] - pnd[j][1] * pnd[i][0])
356 + pn[i][2] * pn[k][2] * pn[j][1] * pnd[j][0]
357 * (pnd[i][0] * pnd[k][1] - pnd[i][1] * pnd[k][0])
358 + pn[j][2] * pn[k][2] * pn[i][1] * pnd[i][0]
359 * (pnd[k][0] * pnd[j][1] - pnd[k][1] * pnd[j][0]);
361 C[1] = pn[i][2] * pn[j][2] * pn[k][0] * pnd[k][1]
362 * (pnd[i][0] * pnd[j][1] - pnd[i][1] * pnd[j][0])
363 + pn[i][2] * pn[k][2] * pn[j][0] * pnd[j][1]
364 * (pnd[k][0] * pnd[i][1] - pnd[k][1] * pnd[i][0])
365 + pn[j][2] * pn[k][2] * pn[i][0] * pnd[i][1]
366 * (pnd[j][0] * pnd[k][1] - pnd[j][1] * pnd[k][0]);
368 C[2] = +pn[i][1] * pn[k][1] * pn[j][2] * pnd[j][0]
369 * (pnd[k][2] * pnd[i][0] - pnd[k][0] * pnd[i][2])
370 + pn[i][1] * pn[j][1] * pn[k][2] * pnd[k][0]
371 * (pnd[i][2] * pnd[j][0] - pnd[i][0] * pnd[j][2]) +
372 pn[j][1] * pn[k][1] * pn[i][2] * pnd[i][0]
373 * (pnd[j][2] * pnd[k][0] - pnd[j][0] * pnd[k][2]);
376 C[3] = pn[i][0] * pn[j][0] * pn[k][2] * pnd[k][1]
377 * (pnd[i][2] * pnd[j][1] - pnd[i][1] * pnd[j][2])
378 + pn[i][0] * pn[k][0] * pn[j][2] * pnd[j][1]
379 * (pnd[k][2] * pnd[i][1] - pnd[k][1] * pnd[i][2])
380 + pn[j][0] * pn[k][0] * pn[i][2] * pnd[i][1]
381 * (pnd[j][2] * pnd[k][1] - pnd[j][1] * pnd[k][2]);
384 C[5] = pn[i][1] * pn[j][1] * pn[k][0] * pnd[k][2]
385 * (pnd[i][0] * pnd[j][2] - pnd[i][2] * pnd[j][0])
386 + pn[i][1] * pn[k][1] * pn[j][0] * pnd[j][2]
387 * (pnd[k][0] * pnd[i][2] - pnd[k][2] * pnd[i][0])
388 + pn[j][1] * pn[k][1] * pn[i][0] * pnd[i][2]
389 * (pnd[j][0] * pnd[k][2] - pnd[j][2] * pnd[k][0]);
391 C[6] = pn[i][0] * pn[j][0] * pn[k][1] * pnd[k][2]
392 * (pnd[i][1] * pnd[j][2] - pnd[i][2] * pnd[j][1])
393 + pn[i][0] * pn[k][0] * pn[j][1] * pnd[j][2]
394 * (pnd[k][1] * pnd[i][2] - pnd[k][2] * pnd[i][1])
395 + pn[j][0] * pn[k][0] * pn[i][1] * pnd[i][2]
396 * (pnd[j][1] * pnd[k][2] - pnd[j][2] * pnd[k][1]);
398 C[4] = pn[i][0] * pn[k][1] * pn[j][2]
399 * (pnd[k][0] * pnd[j][1] * pnd[i][2] - pnd[j][0] * pnd[i][1] * pnd[k][2])
400 + pn[k][0] * pn[i][1] * pn[j][2]
401 * (pnd[j][0] * pnd[k][1] * pnd[i][2] - pnd[i][0] * pnd[j][1] * pnd[k][2])
402 + pn[i][0] * pn[j][1] * pn[k][2]
403 * (pnd[k][0] * pnd[i][1] * pnd[j][2] - pnd[j][0] * pnd[k][1] * pnd[i][2])
404 + pn[j][0] * pn[i][1] * pn[k][2]
405 * (pnd[i][0] * pnd[k][1] * pnd[j][2] - pnd[k][0] * pnd[j][1] * pnd[i][2])
406 + pn[k][0] * pn[j][1] * pn[i][2]
407 * (pnd[j][0] * pnd[i][1] * pnd[k][2] - pnd[i][0] * pnd[k][1] * pnd[j][2])
408 + pn[j][0] * pn[k][1] * pn[i][2]
409 * (pnd[i][0] * pnd[j][1] * pnd[k][2] - pnd[k][0] * pnd[i][1] * pnd[j][2]);
413 for (
unsigned int ii = 0; ii < nc; ii++) {
414 for (
unsigned int jj = ii; jj < nc; jj++) {
415 CtC[ii][jj] = CtC[ii][jj] + C[ii] * C[jj];
423 for (
unsigned int i = 0; i < nc; i++) {
424 for (
unsigned int j = i + 1; j < nc; j++)
425 CtC[j][i] = CtC[i][j];
459 unsigned int vect = 0;
462 for (
unsigned int j = 0; j < nc; j++) {
464 if (std::fabs(sv[j] - svSorted[cont]) <= std::fabs(
vpMath::maximum(sv[j], svSorted[cont])))
466 if (std::fabs(sv[j] / svSorted[nc - 1]) < eps)
467 cont_zeros = cont_zeros + 1;
470 if (cont_zeros > 5) {
472 HLM2D(nb_pts, pd, p, H);
494 c[0][0] = V[5][vect];
496 c[1][0] = V[6][vect];
498 c[2][0] = V[3][vect];
500 c[3][0] = V[4][vect];
503 c[4][1] = V[6][vect];
505 c[5][1] = V[5][vect];
507 c[6][1] = V[2][vect];
509 c[7][1] = V[4][vect];
512 cp = c.pseudoInverse(1e-6);
524 T[0][0] = -V[1][vect];
525 T[0][1] = V[0][vect];
526 T[1][0] = V[4][vect];
527 T[1][2] = -V[2][vect];
528 T[2][0] = -V[6][vect];
529 T[2][1] = V[2][vect];
530 T[3][0] = V[6][vect];
531 T[3][2] = -V[0][vect];
532 T[4][0] = -V[3][vect];
533 T[4][1] = V[6][vect];
534 T[5][0] = V[3][vect];
535 T[5][2] = -V[1][vect];
536 T[6][0] = -V[5][vect];
537 T[6][1] = V[4][vect];
538 T[7][0] = V[5][vect];
539 T[7][2] = -V[6][vect];
540 T[8][1] = -V[5][vect];
541 T[8][2] = V[2][vect];
544 for (
unsigned int i = 0; i < 3; i++)
552 void HLM(
unsigned int q_cible,
const std::vector<double> &xm,
const std::vector<double> &ym,
553 const std::vector<double> &xmi,
const std::vector<double> &ymi,
vpMatrix &H)
555 unsigned int nbpt = (
unsigned int)xm.size();
564 for (
unsigned int i = 0; i < nbpt; i++) {
582 HLM2D(nbpt, pd, p, H);
587 HLM3D(nbpt, pd, p, H);
595 void vpHomography::HLM(
const std::vector<double> &xb,
const std::vector<double> &yb,
const std::vector<double> &xa,
596 const std::vector<double> &ya,
bool isplanar,
vpHomography &aHb)
598 unsigned int n = (
unsigned int)xb.size();
599 if (yb.size() != n || xa.size() != n || ya.size() != n)
607 unsigned int q_cible;
615 ::HLM(q_cible, xa, ya, xb, yb, H);
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Implementation of column vector and the associated operations.
static vpColVector invSort(const vpColVector &v)
error that can be emitted by ViSP classes.
@ dimensionError
Bad dimension.
Implementation of an homography and operations on homographies.
static void HLM(const std::vector< double > &xb, const std::vector< double > &yb, const std::vector< double > &xa, const std::vector< double > &ya, bool isplanar, vpHomography &aHb)
static Type maximum(const Type &a, const Type &b)
error that can be emitted by the vpMatrix class and its derivatives
@ matrixError
Matrix operation error.
Implementation of a matrix and operations on matrices.
void svd(vpColVector &w, vpMatrix &V)
vpMatrix pseudoInverse(double svThreshold=1e-6) const