38 #include <visp3/vision/vpHomography.h>
39 #include <visp3/core/vpMath.h>
47 const double vpHomography::sing_threshold = 0.0001;
67 nd[0]=0;nd[1]=0;nd[2]=1;
101 #ifndef DOXYGEN_SHOULD_SKIP_THIS
138 double distanceFictive;
139 double sinusTheta, cosinusTheta, signeSinus= 1;
140 double cosinusDesireeEstimee, cosinusAncien;
141 double s, determinantU, determinantV;
142 unsigned int i, j, k, w;
143 unsigned int vOrdre[3];
150 #ifdef DEBUG_Homographie
151 printf (
"debut : Homographie_EstimationDeplacementCamera\n");
163 for (i=0 ; i < 3 ; i++)
164 for (j=0 ; j < 3 ; j++) mH[i][j] = aHb[i][j];
174 mTempU.svd(svTemp,mTempV) ;
179 if (svTemp[0] >= svTemp[1]) {
180 if (svTemp[0] >= svTemp[2]) {
181 if (svTemp[1] > svTemp[2]) {
182 vOrdre[0] = 0; vOrdre[1] = 1; vOrdre[2] = 2;
184 vOrdre[0] = 0; vOrdre[1] = 2; vOrdre[2] = 1;
187 vOrdre[0] = 2; vOrdre[1] = 0; vOrdre[2] = 1;
190 if (svTemp[1] >= svTemp[2]){
191 if (svTemp[0] > svTemp[2])
192 { vOrdre[0] = 1; vOrdre[1] = 0; vOrdre[2] = 2; }
194 { vOrdre[0] = 1; vOrdre[1] = 2; vOrdre[2] = 0; }
196 vOrdre[0] = 2; vOrdre[1] = 1; vOrdre[2] = 0;
206 for (i = 0; i < 3; i++) {
207 sv[i] = svTemp[vOrdre[i]];
208 for (j = 0; j < 3; j++) {
209 mU[i][j] = mTempU[i][vOrdre[j]];
210 mV[i][j] = mTempV[i][vOrdre[j]];
214 #ifdef DEBUG_Homographie
215 printf(
"U : \n") ; std::cout << mU << std::endl ;
216 printf(
"V : \n") ; std::cout << mV << std::endl ;
217 printf(
"Valeurs singulieres : ") ; std::cout << sv.t() ;
221 determinantV = mV.det();
222 determinantU = mU.det();
224 s = determinantU * determinantV;
226 #ifdef DEBUG_Homographie
227 printf (
"s = det(U) * det(V) = %f * %f = %f\n",determinantU,determinantV,s);
233 distanceFictive = sv[1];
234 #ifdef DEBUG_Homographie
235 printf (
"d = %f\n",distanceFictive);
239 if (((sv[0] - sv[1]) < sing_threshold) && (sv[0] - sv[2]) < sing_threshold)
253 n[0] = normaleDesiree[0];
254 n[1] = normaleDesiree[1];
255 n[2] = normaleDesiree[2];
259 #ifdef DEBUG_Homographie
260 printf(
"\nCas general\n");
274 mX[0][0] = sqrt ((sv[0] * sv[0] - sv[1] * sv[1])
275 / (sv[0] * sv[0] - sv[2] * sv[2]));
277 mX[2][0] = sqrt ((sv[1] * sv[1] - sv[2] * sv[2])
278 / (sv[0] * sv[0] - sv[2] * sv[2]));
280 mX[0][1] = -mX[0][0];
286 for (w = 0; w < 2; w++) {
287 for (k = 0; k < 2; k++) {
290 for (i = 0; i < 3; i++) {
291 normaleEstimee[i] = 0.0;
292 for (j = 0; j < 3; j++) {
293 normaleEstimee[i] += (2.0 * k - 1.0) * mV[i][j] * mX[j][w];
299 cosinusDesireeEstimee = 0.0;
300 for (i = 0; i < 3; i++)
301 cosinusDesireeEstimee += normaleEstimee[i] * normaleDesiree[i];
307 if (cosinusDesireeEstimee > cosinusAncien)
309 cosinusAncien = cosinusDesireeEstimee;
312 for (j = 0; j < 3; j++)
313 n[j] = normaleEstimee[j];
316 aTbp[0] = (2.0 * k - 1.0) * (sv[0] - sv[2]) * mX[0][w];
317 aTbp[1] = (2.0 * k - 1.0) * (sv[0] - sv[2]) * mX[1][w];
318 aTbp[2] = -(2.0 * k - 1.0) * (sv[0] - sv[2]) * mX[2][w];
332 for (i = 0; i < 3; i++) {
334 for (j = 0; j < 3; j++) {
335 atb[i] += mU[i][j] * aTbp[j];
337 atb[i] /= distanceFictive;
341 #ifdef DEBUG_Homographie
342 printf(
"t' : ") ; std::cout << aTbp.t() ;
343 printf(
"t/d : ") ; std::cout << atb.
t() ;
344 printf(
"n : ") ; std::cout << n.
t() ;
355 sinusTheta = signeSinus*sqrt((sv[0]*sv[0] -sv[1]*sv[1])
356 *(sv[1]*sv[1] -sv[2]*sv[2]))
357 / ((sv[0] + sv[2]) * sv[1]);
359 cosinusTheta = ( sv[1] * sv[1] + sv[0] * sv[2] ) / ((sv[0] + sv[2]) * sv[1]);
362 aRbp[0][0] = cosinusTheta; aRbp[0][1] = 0; aRbp[0][2] = -sinusTheta;
363 aRbp[1][0] = 0; aRbp[1][1] = 1; aRbp[1][2] = 0;
364 aRbp[2][0] = sinusTheta; aRbp[2][1] = 0; aRbp[2][2] = cosinusTheta;
369 for (i = 0; i < 3; i++) {
370 for (j = 0; j < 3; j++) {
372 for (k = 0; k < 3; k++) {
373 aRbint[i][j] += mU[i][k] * aRbp[k][j];
379 for (i = 0; i < 3; i++) {
380 for (j = 0; j < 3; j++) {
382 for (k = 0; k < 3; k++) {
383 aRb[i][j] += aRbint[i][k] * mV[j][k];
388 #ifdef DEBUG_Homographie
424 double distanceFictive;
425 double sinusTheta, cosinusTheta, signeSinus= 1;
426 double cosinusDesireeEstimee, cosinusAncien;
427 double s, determinantU, determinantV;
428 unsigned int i, j, k, w;
429 unsigned int vOrdre[3];
432 normaleDesiree[0]=0;normaleDesiree[1]=0;normaleDesiree[2]=1;
435 #ifdef DEBUG_Homographie
436 printf (
"debut : Homographie_EstimationDeplacementCamera\n");
448 for (i=0 ; i < 3 ; i++)
449 for (j=0 ; j < 3 ; j++) mH[i][j] = aHb[i][j];
459 mTempU.svd(svTemp,mTempV) ;
464 if (svTemp[0] >= svTemp[1]) {
465 if (svTemp[0] >= svTemp[2]) {
466 if (svTemp[1] > svTemp[2]) {
467 vOrdre[0] = 0; vOrdre[1] = 1; vOrdre[2] = 2;
469 vOrdre[0] = 0; vOrdre[1] = 2; vOrdre[2] = 1;
472 vOrdre[0] = 2; vOrdre[1] = 0; vOrdre[2] = 1;
475 if (svTemp[1] >= svTemp[2]){
476 if (svTemp[0] > svTemp[2])
477 { vOrdre[0] = 1; vOrdre[1] = 0; vOrdre[2] = 2; }
479 { vOrdre[0] = 1; vOrdre[1] = 2; vOrdre[2] = 0; }
481 vOrdre[0] = 2; vOrdre[1] = 1; vOrdre[2] = 0;
491 for (i = 0; i < 3; i++) {
492 sv[i] = svTemp[vOrdre[i]];
493 for (j = 0; j < 3; j++) {
494 mU[i][j] = mTempU[i][vOrdre[j]];
495 mV[i][j] = mTempV[i][vOrdre[j]];
499 #ifdef DEBUG_Homographie
500 printf(
"U : \n") ; std::cout << mU << std::endl ;
501 printf(
"V : \n") ; std::cout << mV << std::endl ;
502 printf(
"Valeurs singulieres : ") ; std::cout << sv.t() ;
506 determinantV = mV.det();
507 determinantU = mU.det();
509 s = determinantU * determinantV;
511 #ifdef DEBUG_Homographie
512 printf (
"s = det(U) * det(V) = %f * %f = %f\n",determinantU,determinantV,s);
518 distanceFictive = sv[1];
519 #ifdef DEBUG_Homographie
520 printf (
"d = %f\n",distanceFictive);
524 if (((sv[0] - sv[1]) < sing_threshold) && (sv[0] - sv[2]) < sing_threshold)
538 n[0] = normaleDesiree[0];
539 n[1] = normaleDesiree[1];
540 n[2] = normaleDesiree[2];
544 #ifdef DEBUG_Homographie
545 printf(
"\nCas general\n");
559 mX[0][0] = sqrt ((sv[0] * sv[0] - sv[1] * sv[1])
560 / (sv[0] * sv[0] - sv[2] * sv[2]));
562 mX[2][0] = sqrt ((sv[1] * sv[1] - sv[2] * sv[2])
563 / (sv[0] * sv[0] - sv[2] * sv[2]));
565 mX[0][1] = -mX[0][0];
571 for (w = 0; w < 2; w++) {
572 for (k = 0; k < 2; k++) {
575 for (i = 0; i < 3; i++) {
576 normaleEstimee[i] = 0.0;
577 for (j = 0; j < 3; j++) {
578 normaleEstimee[i] += (2.0 * k - 1.0) * mV[i][j] * mX[j][w];
584 cosinusDesireeEstimee = 0.0;
585 for (i = 0; i < 3; i++)
586 cosinusDesireeEstimee += normaleEstimee[i] * normaleDesiree[i];
592 if (cosinusDesireeEstimee > cosinusAncien)
594 cosinusAncien = cosinusDesireeEstimee;
597 for (j = 0; j < 3; j++)
598 n[j] = normaleEstimee[j];
601 aTbp[0] = (2.0 * k - 1.0) * (sv[0] - sv[2]) * mX[0][w];
602 aTbp[1] = (2.0 * k - 1.0) * (sv[0] - sv[2]) * mX[1][w];
603 aTbp[2] = -(2.0 * k - 1.0) * (sv[0] - sv[2]) * mX[2][w];
617 for (i = 0; i < 3; i++) {
619 for (j = 0; j < 3; j++) {
620 atb[i] += mU[i][j] * aTbp[j];
622 atb[i] /= distanceFictive;
626 #ifdef DEBUG_Homographie
627 printf(
"t' : ") ; std::cout << aTbp.t() ;
628 printf(
"t/d : ") ; std::cout << atb.
t() ;
629 printf(
"n : ") ; std::cout << n.
t() ;
640 sinusTheta = signeSinus*sqrt((sv[0]*sv[0] -sv[1]*sv[1])
641 *(sv[1]*sv[1] -sv[2]*sv[2]))
642 / ((sv[0] + sv[2]) * sv[1]);
644 cosinusTheta = ( sv[1] * sv[1] + sv[0] * sv[2] ) / ((sv[0] + sv[2]) * sv[1]);
647 aRbp[0][0] = cosinusTheta; aRbp[0][1] = 0; aRbp[0][2] = -sinusTheta;
648 aRbp[1][0] = 0; aRbp[1][1] = 1; aRbp[1][2] = 0;
649 aRbp[2][0] = sinusTheta; aRbp[2][1] = 0; aRbp[2][2] = cosinusTheta;
654 for (i = 0; i < 3; i++) {
655 for (j = 0; j < 3; j++) {
657 for (k = 0; k < 3; k++) {
658 aRbint[i][j] += mU[i][k] * aRbp[k][j];
664 for (i = 0; i < 3; i++) {
665 for (j = 0; j < 3; j++) {
667 for (k = 0; k < 3; k++) {
668 aRb[i][j] += aRbint[i][k] * mV[j][k];
673 #ifdef DEBUG_Homographie
682 std::list<vpRotationMatrix> & vR,
683 std::list<vpTranslationVector> & vT,
684 std::list<vpColVector> & vN)
687 #ifdef DEBUG_Homographie
688 printf (
"debut : Homographie_EstimationDeplacementCamera\n");
696 int cas1 =1, cas2=2, cas3=3, cas4=4;
698 bool norm1ok=
false, norm2ok =
false,norm3ok=
false,norm4ok =
false;
700 double tmp,determinantU,determinantV,s,distanceFictive;
701 vpMatrix mTempU(3,3),mTempV(3,3),U(3,3),V(3,3);
717 unsigned int vOrdre[3];
731 mTempU.
svd(svTemp, mTempV);
735 if (svTemp[0] >= svTemp[1]) {
736 if (svTemp[0] >= svTemp[2])
738 if (svTemp[1] > svTemp[2])
740 vOrdre[0] = 0; vOrdre[1] = 1; vOrdre[2] = 2;
744 vOrdre[0] = 0; vOrdre[1] = 2; vOrdre[2] = 1;
749 vOrdre[0] = 2; vOrdre[1] = 0; vOrdre[2] = 1;
752 if (svTemp[1] >= svTemp[2]){
753 if (svTemp[0] > svTemp[2]) {
754 vOrdre[0] = 1; vOrdre[1] = 0; vOrdre[2] = 2;
756 vOrdre[0] = 1; vOrdre[1] = 2; vOrdre[2] = 0;
759 vOrdre[0] = 2; vOrdre[1] = 1; vOrdre[2] = 0;
767 for (
unsigned int i = 0; i < 3; i++) {
768 sv[i] = svTemp[vOrdre[i]];
769 for (
unsigned int j = 0; j < 3; j++) {
770 U[i][j] = mTempU[i][vOrdre[j]];
771 V[i][j] = mTempV[i][vOrdre[j]];
775 #ifdef DEBUG_Homographie
776 printf(
"U : \n") ; Affiche(U) ;
777 printf(
"V : \n") ; affiche(V) ;
778 printf(
"Valeurs singulieres : ") ; affiche(sv);
782 determinantU = U[0][0] * (U[1][1]*U[2][2] - U[1][2]*U[2][1]) +
783 U[0][1] * (U[1][2]*U[2][0] - U[1][0]*U[2][2]) +
784 U[0][2] * (U[1][0]*U[2][1] - U[1][1]*U[2][0]);
786 determinantV = V[0][0] * (V[1][1]*V[2][2] - V[1][2]*V[2][1]) +
787 V[0][1] * (V[1][2]*V[2][0] - V[1][0]*V[2][2]) +
788 V[0][2] * (V[1][0]*V[2][1] - V[1][1]*V[2][0]);
790 s = determinantU * determinantV;
792 #ifdef DEBUG_Homographie
793 printf (
"s = det(U) * det(V) = %f * %f = %f\n",determinantU,determinantV,s);
806 tmp = H[2][0]*x + H[2][1]*y + H[2][2] ;
808 if ((tmp/(sv[1] *s)) > 0)
809 distanceFictive = sv[1];
811 distanceFictive = -sv[1];
819 if ((sv[0] - sv[1]) < sing_threshold)
821 if ((sv[1] - sv[2]) < sing_threshold)
828 if ((sv[1] - sv[2]) < sing_threshold)
834 Nprim1 = 0.0; Nprim2 = 0.0; Nprim3 = 0.0; Nprim4 = 0.0;
853 Nprim1[0] = sqrt((sv[0] * sv[0] - sv[1] * sv[1] )/
854 (sv[0] * sv[0] - sv[2] * sv[2] ));
856 Nprim1[2] = sqrt((sv[1] * sv[1] - sv[2] * sv[2] )/
857 (sv[0] * sv[0] - sv[2] * sv[2] ));
859 Nprim2[0] = Nprim1[0]; Nprim2[2] = - Nprim1[2];
860 Nprim3[0] = - Nprim1[0]; Nprim3[2] = Nprim1[2];
861 Nprim4[0] = - Nprim1[0]; Nprim4[2] = - Nprim1[2];
889 tmp = N1[0] * x + N1[1] * y + N1[2];
890 tmp/= (distanceFictive *s);
894 tmp = N2[0] * x + N2[1] *y+ N2[2];
895 tmp/= (distanceFictive*s);
899 tmp = N3[0] * x + N3[1]*y+ N3[2];
900 tmp/= (distanceFictive*s);
904 tmp = N4[0] * x + N4[1] * y + N4[2];
905 tmp/= (distanceFictive*s);
912 tmp = N1[0] * x + N1[1] * y + N1[2];
913 tmp/= (distanceFictive*s);
917 tmp = N2[0] * x + N2[1] * y + N2[2];
918 tmp/= (distanceFictive*s);
925 tmp = N1[0] * x + N1[1] * y + N1[2];
926 tmp/= (distanceFictive*s);
930 tmp = N2[0] * x + N2[1] * y + N2[2];
931 tmp/= (distanceFictive*s);
939 if (distanceFictive>0)
947 Rprim1[0][0] = (
vpMath::sqr(sv[1]) + sv[0] * sv[2]) /
948 ((sv[0] + sv[2]) * sv[1]);
950 Rprim1[2][2] = Rprim1[0][0];
955 / ((sv[0] + sv[2]) * sv[1]);
957 Rprim1[0][2] = -Rprim1[2][0];
961 Tprim1[0] = Nprim1[0];
963 Tprim1[2] = -Nprim1[2];
965 Tprim1*=(sv[0] - sv[2]);
973 Rprim2[0][0] = (
vpMath::sqr(sv[1]) + sv[0] * sv[2]) /
974 ((sv[0] + sv[2]) * sv[1]);
976 Rprim2[2][2] = Rprim2[0][0];
981 / ((sv[0] + sv[2]) * sv[1]);
983 Rprim2[0][2] = -Rprim2[2][0];
987 Tprim2[0] = Nprim2[0];
989 Tprim2[2] = -Nprim2[2];
991 Tprim2*=(sv[0] - sv[2]);
999 Rprim3[0][0] = (
vpMath::sqr(sv[1]) + sv[0] * sv[2]) /
1000 ((sv[0] + sv[2]) * sv[1]);
1002 Rprim3[2][2] = Rprim3[0][0];
1007 / ((sv[0] + sv[2]) * sv[1]);
1009 Rprim3[0][2] = -Rprim3[2][0];
1013 Tprim3[0] = Nprim3[0];
1015 Tprim3[2] = -Nprim3[2];
1017 Tprim3*=(sv[0] - sv[2]);
1025 Rprim4[0][0] = (
vpMath::sqr(sv[1]) + sv[0] * sv[2])/
1026 ((sv[0] + sv[2]) * sv[1]);
1028 Rprim4[2][2] = Rprim4[0][0];
1033 / ((sv[0] + sv[2]) * sv[1]);
1035 Rprim4[0][2] = -Rprim4[2][0];
1039 Tprim4[0] = Nprim4[0];
1041 Tprim4[2] = -Nprim4[2];
1043 Tprim4*=(sv[0] - sv[2]);
1057 Tprim1*= (sv[2] - sv[0]);
1065 Tprim2*= (sv[2] - sv[0]);
1075 Tprim1*= (sv[0] - sv[1]);
1083 Tprim2*= (sv[0] - sv[1]);
1094 if (distanceFictive <0)
1104 Rprim1[0][0] = ( sv[0] * sv[2] -
vpMath::sqr(sv[1])) /
1105 ((sv[0] - sv[2]) * sv[1]);
1107 Rprim1[2][2] = -Rprim1[0][0];
1112 / ((sv[0] - sv[2]) * sv[1]);
1114 Rprim1[0][2] = Rprim1[2][0];
1116 Rprim1[1][1] = -1.0;
1118 Tprim1[0] = Nprim1[0];
1120 Tprim1[2] = Nprim1[2];
1122 Tprim1*=(sv[0] + sv[2]);
1130 Rprim2[0][0] = (sv[0] * sv[2] -
vpMath::sqr(sv[1])) /
1131 ((sv[0] - sv[2]) * sv[1]);
1133 Rprim2[2][2] = -Rprim2[0][0];
1138 / ((sv[0] - sv[2]) * sv[1]);
1140 Rprim2[0][2] = Rprim2[2][0];
1142 Rprim2[1][1] = - 1.0;
1144 Tprim2[0] = Nprim2[0];
1146 Tprim2[2] = Nprim2[2];
1148 Tprim2*=(sv[0] + sv[2]);
1156 Rprim3[0][0] = ( sv[0] * sv[2] -
vpMath::sqr(sv[1])) /
1157 ((sv[0] - sv[2]) * sv[1]);
1159 Rprim3[2][2] = -Rprim3[0][0];
1164 / ((sv[0] - sv[2]) * sv[1]);
1166 Rprim3[0][2] = Rprim3[2][0];
1168 Rprim3[1][1] = -1.0;
1170 Tprim3[0] = Nprim3[0];
1172 Tprim3[2] = Nprim3[2];
1174 Tprim3*=(sv[0] + sv[2]);
1181 Rprim4[0][0] = ( sv[0] * sv[2]-
vpMath::sqr(sv[1]))/((sv[0] - sv[2]) * sv[1]);
1183 Rprim4[2][2] = -Rprim4[0][0];
1188 / ((sv[0] - sv[2]) * sv[1]);
1190 Rprim4[0][2] = Rprim4[2][0];
1192 Rprim4[1][1] = - 1.0;
1194 Tprim4[0] = Nprim4[0];
1196 Tprim4[2] = Nprim4[2];
1198 Tprim4*=(sv[0] + sv[2]);
1212 Tprim1*= (sv[2] + sv[0]);
1222 Tprim2*= (sv[2] + sv[0]);
1234 Tprim1*= (sv[2] + sv[0]);
1244 Tprim2*= (sv[0] + sv[2]);
1254 if ((distanceFictive>0) || (cas != cas4))
1260 R1 = s * U * Rprim1 * V.
t();
1262 T1 /= (distanceFictive *s);
1272 R2 = s * U * Rprim2 * V.
t();
1274 T2 /= (distanceFictive *s);
1284 R3 = s * U * Rprim3 * V.
t();
1286 T3 /= (distanceFictive *s);
1295 R4 = s * U * Rprim4 * V.
t();
1297 T4 /= (distanceFictive *s);
1308 std::cout <<
"On tombe dans le cas particulier ou le mouvement n'est pas estimable!" << std::endl;
1327 #ifdef DEBUG_Homographie
1328 printf(
"fin : Homographie_EstimationDeplacementCamera\n");
1331 #endif //#ifndef DOXYGEN_SHOULD_SKIP_THIS
Implementation of a matrix and operations on matrices.
vpRotationMatrix t() const
void computeDisplacement(vpRotationMatrix &aRb, vpTranslationVector &atb, vpColVector &n)
bool isARotationMatrix() const
Implementation of a rotation matrix and operations on such kind of matrices.
Implementation of an homography and operations on homographies.
void svd(vpColVector &w, vpMatrix &v)
static double sqr(double x)
Implementation of column vector and the associated operations.
Class that consider the case of a translation vector.
void resize(const unsigned int i, const bool flagNullify=true)