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 s, determinantU, determinantV;
141 unsigned int vOrdre[3];
148 #ifdef DEBUG_Homographie
149 printf (
"debut : Homographie_EstimationDeplacementCamera\n");
160 for (
unsigned int i=0 ; i < 3 ; i++)
161 for (
unsigned int j=0 ; j < 3 ; j++) mH[i][j] = aHb[i][j];
171 mTempU.svd(svTemp,mTempV) ;
176 if (svTemp[0] >= svTemp[1]) {
177 if (svTemp[0] >= svTemp[2]) {
178 if (svTemp[1] > svTemp[2]) {
179 vOrdre[0] = 0; vOrdre[1] = 1; vOrdre[2] = 2;
181 vOrdre[0] = 0; vOrdre[1] = 2; vOrdre[2] = 1;
184 vOrdre[0] = 2; vOrdre[1] = 0; vOrdre[2] = 1;
187 if (svTemp[1] >= svTemp[2]){
188 if (svTemp[0] > svTemp[2])
189 { vOrdre[0] = 1; vOrdre[1] = 0; vOrdre[2] = 2; }
191 { vOrdre[0] = 1; vOrdre[1] = 2; vOrdre[2] = 0; }
193 vOrdre[0] = 2; vOrdre[1] = 1; vOrdre[2] = 0;
202 for (
unsigned int i = 0; i < 3; i++) {
203 sv[i] = svTemp[vOrdre[i]];
204 for (
unsigned int j = 0; j < 3; j++) {
205 mU[i][j] = mTempU[i][vOrdre[j]];
206 mV[i][j] = mTempV[i][vOrdre[j]];
210 #ifdef DEBUG_Homographie
211 printf(
"U : \n") ; std::cout << mU << std::endl ;
212 printf(
"V : \n") ; std::cout << mV << std::endl ;
213 printf(
"Valeurs singulieres : ") ; std::cout << sv.t() ;
217 determinantV = mV.det();
218 determinantU = mU.det();
220 s = determinantU * determinantV;
222 #ifdef DEBUG_Homographie
223 printf (
"s = det(U) * det(V) = %f * %f = %f\n",determinantU,determinantV,s);
228 distanceFictive = sv[1];
229 #ifdef DEBUG_Homographie
230 printf (
"d = %f\n",distanceFictive);
234 if (((sv[0] - sv[1]) < sing_threshold) && (sv[0] - sv[2]) < sing_threshold)
248 n[0] = normaleDesiree[0];
249 n[1] = normaleDesiree[1];
250 n[2] = normaleDesiree[2];
254 #ifdef DEBUG_Homographie
255 printf(
"\nCas general\n");
269 mX[0][0] = sqrt ((sv[0] * sv[0] - sv[1] * sv[1])
270 / (sv[0] * sv[0] - sv[2] * sv[2]));
272 mX[2][0] = sqrt ((sv[1] * sv[1] - sv[2] * sv[2])
273 / (sv[0] * sv[0] - sv[2] * sv[2]));
275 mX[0][1] = -mX[0][0];
280 double cosinusAncien = 0.0;
281 for (
unsigned int w = 0; w < 2; w++) {
282 for (
unsigned int k = 0; k < 2; k++) {
285 for (
unsigned int i = 0; i < 3; i++) {
286 normaleEstimee[i] = 0.0;
287 for (
unsigned int j = 0; j < 3; j++) {
288 normaleEstimee[i] += (2.0 * k - 1.0) * mV[i][j] * mX[j][w];
293 double cosinusDesireeEstimee = 0.0;
294 for (
unsigned int i = 0; i < 3; i++)
295 cosinusDesireeEstimee += normaleEstimee[i] * normaleDesiree[i];
301 if (cosinusDesireeEstimee > cosinusAncien)
303 cosinusAncien = cosinusDesireeEstimee;
306 for (
unsigned int j = 0; j < 3; j++)
307 n[j] = normaleEstimee[j];
310 aTbp[0] = (2.0 * k - 1.0) * (sv[0] - sv[2]) * mX[0][w];
311 aTbp[1] = (2.0 * k - 1.0) * (sv[0] - sv[2]) * mX[1][w];
312 aTbp[2] = -(2.0 * k - 1.0) * (sv[0] - sv[2]) * mX[2][w];
326 for (
unsigned int i = 0; i < 3; i++) {
328 for (
unsigned int j = 0; j < 3; j++) {
329 atb[i] += mU[i][j] * aTbp[j];
331 atb[i] /= distanceFictive;
335 #ifdef DEBUG_Homographie
336 printf(
"t' : ") ; std::cout << aTbp.t() ;
337 printf(
"t/d : ") ; std::cout << atb.
t() ;
338 printf(
"n : ") ; std::cout << n.
t() ;
348 sinusTheta = signeSinus*sqrt((sv[0]*sv[0] -sv[1]*sv[1])
349 *(sv[1]*sv[1] -sv[2]*sv[2]))
350 / ((sv[0] + sv[2]) * sv[1]);
352 cosinusTheta = ( sv[1] * sv[1] + sv[0] * sv[2] ) / ((sv[0] + sv[2]) * sv[1]);
355 aRbp[0][0] = cosinusTheta; aRbp[0][1] = 0; aRbp[0][2] = -sinusTheta;
356 aRbp[1][0] = 0; aRbp[1][1] = 1; aRbp[1][2] = 0;
357 aRbp[2][0] = sinusTheta; aRbp[2][1] = 0; aRbp[2][2] = cosinusTheta;
360 for (
unsigned int i = 0; i < 3; i++) {
361 for (
unsigned int j = 0; j < 3; j++) {
363 for (
unsigned int k = 0; k < 3; k++) {
364 aRbint[i][j] += mU[i][k] * aRbp[k][j];
370 for (
unsigned int i = 0; i < 3; i++) {
371 for (
unsigned int j = 0; j < 3; j++) {
373 for (
unsigned int k = 0; k < 3; k++) {
374 aRb[i][j] += aRbint[i][k] * mV[j][k];
379 #ifdef DEBUG_Homographie
414 double distanceFictive;
415 double sinusTheta, cosinusTheta, signeSinus= 1;
416 double s, determinantU, determinantV;
417 unsigned int vOrdre[3];
420 normaleDesiree[0]=0;normaleDesiree[1]=0;normaleDesiree[2]=1;
423 #ifdef DEBUG_Homographie
424 printf (
"debut : Homographie_EstimationDeplacementCamera\n");
436 for (
unsigned int i=0 ; i < 3 ; i++)
437 for (
unsigned int j=0 ; j < 3 ; j++) mH[i][j] = aHb[i][j];
447 mTempU.svd(svTemp,mTempV) ;
452 if (svTemp[0] >= svTemp[1]) {
453 if (svTemp[0] >= svTemp[2]) {
454 if (svTemp[1] > svTemp[2]) {
455 vOrdre[0] = 0; vOrdre[1] = 1; vOrdre[2] = 2;
457 vOrdre[0] = 0; vOrdre[1] = 2; vOrdre[2] = 1;
460 vOrdre[0] = 2; vOrdre[1] = 0; vOrdre[2] = 1;
463 if (svTemp[1] >= svTemp[2]){
464 if (svTemp[0] > svTemp[2])
465 { vOrdre[0] = 1; vOrdre[1] = 0; vOrdre[2] = 2; }
467 { vOrdre[0] = 1; vOrdre[1] = 2; vOrdre[2] = 0; }
469 vOrdre[0] = 2; vOrdre[1] = 1; vOrdre[2] = 0;
478 for (
unsigned int i = 0; i < 3; i++) {
479 sv[i] = svTemp[vOrdre[i]];
480 for (
unsigned int j = 0; j < 3; j++) {
481 mU[i][j] = mTempU[i][vOrdre[j]];
482 mV[i][j] = mTempV[i][vOrdre[j]];
486 #ifdef DEBUG_Homographie
487 printf(
"U : \n") ; std::cout << mU << std::endl ;
488 printf(
"V : \n") ; std::cout << mV << std::endl ;
489 printf(
"Valeurs singulieres : ") ; std::cout << sv.t() ;
493 determinantV = mV.det();
494 determinantU = mU.det();
496 s = determinantU * determinantV;
498 #ifdef DEBUG_Homographie
499 printf (
"s = det(U) * det(V) = %f * %f = %f\n",determinantU,determinantV,s);
504 distanceFictive = sv[1];
505 #ifdef DEBUG_Homographie
506 printf (
"d = %f\n",distanceFictive);
510 if (((sv[0] - sv[1]) < sing_threshold) && (sv[0] - sv[2]) < sing_threshold)
524 n[0] = normaleDesiree[0];
525 n[1] = normaleDesiree[1];
526 n[2] = normaleDesiree[2];
530 #ifdef DEBUG_Homographie
531 printf(
"\nCas general\n");
545 mX[0][0] = sqrt ((sv[0] * sv[0] - sv[1] * sv[1])
546 / (sv[0] * sv[0] - sv[2] * sv[2]));
548 mX[2][0] = sqrt ((sv[1] * sv[1] - sv[2] * sv[2])
549 / (sv[0] * sv[0] - sv[2] * sv[2]));
551 mX[0][1] = -mX[0][0];
556 double cosinusAncien = 0.0;
557 for (
unsigned int w = 0; w < 2; w++) {
558 for (
unsigned int k = 0; k < 2; k++) {
561 for (
unsigned int i = 0; i < 3; i++) {
562 normaleEstimee[i] = 0.0;
563 for (
unsigned int j = 0; j < 3; j++) {
564 normaleEstimee[i] += (2.0 * k - 1.0) * mV[i][j] * mX[j][w];
570 double cosinusDesireeEstimee = 0.0;
571 for (
unsigned int i = 0; i < 3; i++)
572 cosinusDesireeEstimee += normaleEstimee[i] * normaleDesiree[i];
578 if (cosinusDesireeEstimee > cosinusAncien)
580 cosinusAncien = cosinusDesireeEstimee;
583 for (
unsigned int j = 0; j < 3; j++)
584 n[j] = normaleEstimee[j];
587 aTbp[0] = (2.0 * k - 1.0) * (sv[0] - sv[2]) * mX[0][w];
588 aTbp[1] = (2.0 * k - 1.0) * (sv[0] - sv[2]) * mX[1][w];
589 aTbp[2] = -(2.0 * k - 1.0) * (sv[0] - sv[2]) * mX[2][w];
603 for (
unsigned int i = 0; i < 3; i++) {
605 for (
unsigned int j = 0; j < 3; j++) {
606 atb[i] += mU[i][j] * aTbp[j];
608 atb[i] /= distanceFictive;
611 #ifdef DEBUG_Homographie
612 printf(
"t' : ") ; std::cout << aTbp.t() ;
613 printf(
"t/d : ") ; std::cout << atb.
t() ;
614 printf(
"n : ") ; std::cout << n.
t() ;
625 sinusTheta = signeSinus*sqrt((sv[0]*sv[0] -sv[1]*sv[1])
626 *(sv[1]*sv[1] -sv[2]*sv[2]))
627 / ((sv[0] + sv[2]) * sv[1]);
629 cosinusTheta = ( sv[1] * sv[1] + sv[0] * sv[2] ) / ((sv[0] + sv[2]) * sv[1]);
632 aRbp[0][0] = cosinusTheta; aRbp[0][1] = 0; aRbp[0][2] = -sinusTheta;
633 aRbp[1][0] = 0; aRbp[1][1] = 1; aRbp[1][2] = 0;
634 aRbp[2][0] = sinusTheta; aRbp[2][1] = 0; aRbp[2][2] = cosinusTheta;
637 for (
unsigned int i = 0; i < 3; i++) {
638 for (
unsigned int j = 0; j < 3; j++) {
640 for (
unsigned int k = 0; k < 3; k++) {
641 aRbint[i][j] += mU[i][k] * aRbp[k][j];
647 for (
unsigned int i = 0; i < 3; i++) {
648 for (
unsigned int j = 0; j < 3; j++) {
650 for (
unsigned int k = 0; k < 3; k++) {
651 aRb[i][j] += aRbint[i][k] * mV[j][k];
656 #ifdef DEBUG_Homographie
665 std::list<vpRotationMatrix> & vR,
666 std::list<vpTranslationVector> & vT,
667 std::list<vpColVector> & vN)
670 #ifdef DEBUG_Homographie
671 printf (
"debut : Homographie_EstimationDeplacementCamera\n");
679 int cas1 =1, cas2=2, cas3=3, cas4=4;
681 bool norm1ok=
false, norm2ok =
false,norm3ok=
false,norm4ok =
false;
683 double tmp,determinantU,determinantV,s,distanceFictive;
684 vpMatrix mTempU(3,3),mTempV(3,3),U(3,3),V(3,3);
700 unsigned int vOrdre[3];
714 mTempU.
svd(svTemp, mTempV);
718 if (svTemp[0] >= svTemp[1]) {
719 if (svTemp[0] >= svTemp[2])
721 if (svTemp[1] > svTemp[2])
723 vOrdre[0] = 0; vOrdre[1] = 1; vOrdre[2] = 2;
727 vOrdre[0] = 0; vOrdre[1] = 2; vOrdre[2] = 1;
732 vOrdre[0] = 2; vOrdre[1] = 0; vOrdre[2] = 1;
735 if (svTemp[1] >= svTemp[2]){
736 if (svTemp[0] > svTemp[2]) {
737 vOrdre[0] = 1; vOrdre[1] = 0; vOrdre[2] = 2;
739 vOrdre[0] = 1; vOrdre[1] = 2; vOrdre[2] = 0;
742 vOrdre[0] = 2; vOrdre[1] = 1; vOrdre[2] = 0;
750 for (
unsigned int i = 0; i < 3; i++) {
751 sv[i] = svTemp[vOrdre[i]];
752 for (
unsigned int j = 0; j < 3; j++) {
753 U[i][j] = mTempU[i][vOrdre[j]];
754 V[i][j] = mTempV[i][vOrdre[j]];
758 #ifdef DEBUG_Homographie
759 printf(
"U : \n") ; Affiche(U) ;
760 printf(
"V : \n") ; affiche(V) ;
761 printf(
"Valeurs singulieres : ") ; affiche(sv);
765 determinantU = U[0][0] * (U[1][1]*U[2][2] - U[1][2]*U[2][1]) +
766 U[0][1] * (U[1][2]*U[2][0] - U[1][0]*U[2][2]) +
767 U[0][2] * (U[1][0]*U[2][1] - U[1][1]*U[2][0]);
769 determinantV = V[0][0] * (V[1][1]*V[2][2] - V[1][2]*V[2][1]) +
770 V[0][1] * (V[1][2]*V[2][0] - V[1][0]*V[2][2]) +
771 V[0][2] * (V[1][0]*V[2][1] - V[1][1]*V[2][0]);
773 s = determinantU * determinantV;
775 #ifdef DEBUG_Homographie
776 printf (
"s = det(U) * det(V) = %f * %f = %f\n",determinantU,determinantV,s);
789 tmp = H[2][0]*x + H[2][1]*y + H[2][2] ;
791 if ((tmp/(sv[1] *s)) > 0)
792 distanceFictive = sv[1];
794 distanceFictive = -sv[1];
802 if ((sv[0] - sv[1]) < sing_threshold)
804 if ((sv[1] - sv[2]) < sing_threshold)
811 if ((sv[1] - sv[2]) < sing_threshold)
817 Nprim1 = 0.0; Nprim2 = 0.0; Nprim3 = 0.0; Nprim4 = 0.0;
836 Nprim1[0] = sqrt((sv[0] * sv[0] - sv[1] * sv[1] )/
837 (sv[0] * sv[0] - sv[2] * sv[2] ));
839 Nprim1[2] = sqrt((sv[1] * sv[1] - sv[2] * sv[2] )/
840 (sv[0] * sv[0] - sv[2] * sv[2] ));
842 Nprim2[0] = Nprim1[0]; Nprim2[2] = - Nprim1[2];
843 Nprim3[0] = - Nprim1[0]; Nprim3[2] = Nprim1[2];
844 Nprim4[0] = - Nprim1[0]; Nprim4[2] = - Nprim1[2];
872 tmp = N1[0] * x + N1[1] * y + N1[2];
873 tmp/= (distanceFictive *s);
877 tmp = N2[0] * x + N2[1] *y+ N2[2];
878 tmp/= (distanceFictive*s);
882 tmp = N3[0] * x + N3[1]*y+ N3[2];
883 tmp/= (distanceFictive*s);
887 tmp = N4[0] * x + N4[1] * y + N4[2];
888 tmp/= (distanceFictive*s);
895 tmp = N1[0] * x + N1[1] * y + N1[2];
896 tmp/= (distanceFictive*s);
900 tmp = N2[0] * x + N2[1] * y + N2[2];
901 tmp/= (distanceFictive*s);
908 tmp = N1[0] * x + N1[1] * y + N1[2];
909 tmp/= (distanceFictive*s);
913 tmp = N2[0] * x + N2[1] * y + N2[2];
914 tmp/= (distanceFictive*s);
922 if (distanceFictive>0)
930 Rprim1[0][0] = (
vpMath::sqr(sv[1]) + sv[0] * sv[2]) /
931 ((sv[0] + sv[2]) * sv[1]);
933 Rprim1[2][2] = Rprim1[0][0];
938 / ((sv[0] + sv[2]) * sv[1]);
940 Rprim1[0][2] = -Rprim1[2][0];
944 Tprim1[0] = Nprim1[0];
946 Tprim1[2] = -Nprim1[2];
948 Tprim1*=(sv[0] - sv[2]);
956 Rprim2[0][0] = (
vpMath::sqr(sv[1]) + sv[0] * sv[2]) /
957 ((sv[0] + sv[2]) * sv[1]);
959 Rprim2[2][2] = Rprim2[0][0];
964 / ((sv[0] + sv[2]) * sv[1]);
966 Rprim2[0][2] = -Rprim2[2][0];
970 Tprim2[0] = Nprim2[0];
972 Tprim2[2] = -Nprim2[2];
974 Tprim2*=(sv[0] - sv[2]);
982 Rprim3[0][0] = (
vpMath::sqr(sv[1]) + sv[0] * sv[2]) /
983 ((sv[0] + sv[2]) * sv[1]);
985 Rprim3[2][2] = Rprim3[0][0];
990 / ((sv[0] + sv[2]) * sv[1]);
992 Rprim3[0][2] = -Rprim3[2][0];
996 Tprim3[0] = Nprim3[0];
998 Tprim3[2] = -Nprim3[2];
1000 Tprim3*=(sv[0] - sv[2]);
1008 Rprim4[0][0] = (
vpMath::sqr(sv[1]) + sv[0] * sv[2])/
1009 ((sv[0] + sv[2]) * sv[1]);
1011 Rprim4[2][2] = Rprim4[0][0];
1016 / ((sv[0] + sv[2]) * sv[1]);
1018 Rprim4[0][2] = -Rprim4[2][0];
1022 Tprim4[0] = Nprim4[0];
1024 Tprim4[2] = -Nprim4[2];
1026 Tprim4*=(sv[0] - sv[2]);
1040 Tprim1*= (sv[2] - sv[0]);
1048 Tprim2*= (sv[2] - sv[0]);
1058 Tprim1*= (sv[0] - sv[1]);
1066 Tprim2*= (sv[0] - sv[1]);
1077 if (distanceFictive <0)
1087 Rprim1[0][0] = ( sv[0] * sv[2] -
vpMath::sqr(sv[1])) /
1088 ((sv[0] - sv[2]) * sv[1]);
1090 Rprim1[2][2] = -Rprim1[0][0];
1095 / ((sv[0] - sv[2]) * sv[1]);
1097 Rprim1[0][2] = Rprim1[2][0];
1099 Rprim1[1][1] = -1.0;
1101 Tprim1[0] = Nprim1[0];
1103 Tprim1[2] = Nprim1[2];
1105 Tprim1*=(sv[0] + sv[2]);
1113 Rprim2[0][0] = (sv[0] * sv[2] -
vpMath::sqr(sv[1])) /
1114 ((sv[0] - sv[2]) * sv[1]);
1116 Rprim2[2][2] = -Rprim2[0][0];
1121 / ((sv[0] - sv[2]) * sv[1]);
1123 Rprim2[0][2] = Rprim2[2][0];
1125 Rprim2[1][1] = - 1.0;
1127 Tprim2[0] = Nprim2[0];
1129 Tprim2[2] = Nprim2[2];
1131 Tprim2*=(sv[0] + sv[2]);
1139 Rprim3[0][0] = ( sv[0] * sv[2] -
vpMath::sqr(sv[1])) /
1140 ((sv[0] - sv[2]) * sv[1]);
1142 Rprim3[2][2] = -Rprim3[0][0];
1147 / ((sv[0] - sv[2]) * sv[1]);
1149 Rprim3[0][2] = Rprim3[2][0];
1151 Rprim3[1][1] = -1.0;
1153 Tprim3[0] = Nprim3[0];
1155 Tprim3[2] = Nprim3[2];
1157 Tprim3*=(sv[0] + sv[2]);
1164 Rprim4[0][0] = ( sv[0] * sv[2]-
vpMath::sqr(sv[1]))/((sv[0] - sv[2]) * sv[1]);
1166 Rprim4[2][2] = -Rprim4[0][0];
1171 / ((sv[0] - sv[2]) * sv[1]);
1173 Rprim4[0][2] = Rprim4[2][0];
1175 Rprim4[1][1] = - 1.0;
1177 Tprim4[0] = Nprim4[0];
1179 Tprim4[2] = Nprim4[2];
1181 Tprim4*=(sv[0] + sv[2]);
1195 Tprim1*= (sv[2] + sv[0]);
1205 Tprim2*= (sv[2] + sv[0]);
1217 Tprim1*= (sv[2] + sv[0]);
1227 Tprim2*= (sv[0] + sv[2]);
1237 if ((distanceFictive>0) || (cas != cas4))
1243 R1 = s * U * Rprim1 * V.
t();
1245 T1 /= (distanceFictive *s);
1255 R2 = s * U * Rprim2 * V.
t();
1257 T2 /= (distanceFictive *s);
1267 R3 = s * U * Rprim3 * V.
t();
1269 T3 /= (distanceFictive *s);
1278 R4 = s * U * Rprim4 * V.
t();
1280 T4 /= (distanceFictive *s);
1291 std::cout <<
"On tombe dans le cas particulier ou le mouvement n'est pas estimable!" << std::endl;
1310 #ifdef DEBUG_Homographie
1311 printf(
"fin : Homographie_EstimationDeplacementCamera\n");
1314 #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)