1 #include <visp/vpCalibration.h>
2 #include <visp/vpMath.h>
3 #include <visp/vpPose.h>
4 #include <visp/vpPixelMeterConversion.h>
19 std::list<double>::const_iterator it_LoX = LoX.begin();
20 std::list<double>::const_iterator it_LoY = LoY.begin();
21 std::list<double>::const_iterator it_LoZ = LoZ.begin();
22 std::list<vpImagePoint>::const_iterator it_Lip = Lip.begin();
26 for (
unsigned int i = 0 ; i < npt ; i++)
35 double xi = ip.
get_u() ;
36 double yi = ip.
get_v() ;
101 unsigned int imin = 1;
102 for (
unsigned int i=0;i<x1.getRows();i++)
113 for (
unsigned int i=0;i<x1.getRows();i++)
115 if (x1[i] < x1[imin]) imin = i;
118 for (
unsigned int i=0;i<x1.getRows();i++)
119 x1[i] = AtA[i][imin];
126 for (
unsigned int i=0;i<3;i++) sol[i] = x1[i];
127 for (
unsigned int i=0;i<9;i++)
132 if (sol[11] < 0.0)
for (
unsigned int i=0;i<12;i++) sol[i] = -sol[i];
134 resul[0] = sol[3]*sol[0]+sol[4]*sol[1]+sol[5]*sol[2];
136 resul[1] = sol[6]*sol[0]+sol[7]*sol[1]+sol[8]*sol[2];
138 resul[2] = sqrt(sol[3]*sol[3]+sol[4]*sol[4]+sol[5]*sol[5]
140 resul[3] = sqrt(sol[6]*sol[6]+sol[7]*sol[7]+sol[8]*sol[8]
145 resul[4] = (sol[9]-sol[11]*resul[0])/resul[2];
146 resul[5] = (sol[10]-sol[11]*resul[1])/resul[3];
151 for (
unsigned int i=0;i<3;i++) rd[0][i] = (sol[i+3]-sol[i]*resul[0])/resul[2];
152 for (
unsigned int i=0;i<3;i++) rd[1][i] = (sol[i+6]-sol[i]*resul[1])/resul[3];
153 for (
unsigned int i=0;i<3;i++) rd[2][i] = sol[i];
158 for (
unsigned int i=0 ; i < 3 ; i++)
160 for (
unsigned int j=0 ; j < 3 ; j++)
161 cMo_est[i][j] = rd[i][j];
163 for (
unsigned int i=0 ; i < 3 ; i++) cMo_est[i][3] = resul[i+4] ;
165 this->
cMo = cMo_est ;
168 double deviation,deviation_dist;
179 std::ios::fmtflags original_flags( std::cout.flags() );
180 std::cout.precision(10);
181 unsigned int n_points = npt ;
194 std::list<double>::const_iterator it_LoX = LoX.begin();
195 std::list<double>::const_iterator it_LoY = LoY.begin();
196 std::list<double>::const_iterator it_LoZ = LoZ.begin();
197 std::list<vpImagePoint>::const_iterator it_Lip = Lip.begin();
199 for (
unsigned int i =0 ; i < n_points ; i++)
217 unsigned int iter = 0 ;
219 double residu_1 = 1e12 ;
221 while (
vpMath::equal(residu_1,r,threshold) ==
false && iter < nbIterMax)
226 double px = cam_est.
get_px();
227 double py = cam_est.
get_py();
228 double u0 = cam_est.
get_u0();
229 double v0 = cam_est.
get_v0();
233 for (
unsigned int i=0 ; i < n_points; i++)
235 cX[i] = oX[i]*cMo_est[0][0]+oY[i]*cMo_est[0][1]+oZ[i]*cMo_est[0][2] + cMo_est[0][3];
236 cY[i] = oX[i]*cMo_est[1][0]+oY[i]*cMo_est[1][1]+oZ[i]*cMo_est[1][2] + cMo_est[1][3];
237 cZ[i] = oX[i]*cMo_est[2][0]+oY[i]*cMo_est[2][1]+oZ[i]*cMo_est[2][2] + cMo_est[2][3];
242 P[2*i] = cX[i]/cZ[i]*px + u0 ;
243 P[2*i+1] = cY[i]/cZ[i]*py + v0 ;
253 for (
unsigned int i=0 ; i < n_points; i++)
265 L[2*i][0] = px * (-inv_z) ;
267 L[2*i][2] = px*X*inv_z ;
269 L[2*i][4] = -px*(1+X*X) ;
280 L[2*i+1][1] = py*(-inv_z) ;
281 L[2*i+1][2] = py*(Y*inv_z) ;
282 L[2*i+1][3] = py* (1+Y*Y) ;
283 L[2*i+1][4] = -py*X*Y ;
284 L[2*i+1][5] = -py*X ;
294 Lp = L.pseudoInverse(1e-10) ;
303 for (
unsigned int i=0 ; i <6 ; i++)
311 std::cout <<
" std dev " << sqrt(r/n_points) << std::endl;
314 if (iter == nbIterMax)
316 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)",nbIterMax);
318 "Maximum number of iterations reached")) ;
323 this->residual_dist = r;
325 std::cout <<
" std dev " << sqrt(r/n_points) << std::endl;
327 std::cout.flags(original_flags);
331 vpCalibration::calibVVSMulti(std::vector<vpCalibration> &table_cal,
333 double &globalReprojectionError,
336 std::ios::fmtflags original_flags( std::cout.flags() );
337 std::cout.precision(10);
338 unsigned int nbPoint[256];
339 unsigned int nbPointTotal = 0;
340 unsigned int nbPose = (
unsigned int)table_cal.size();
341 unsigned int nbPose6 = 6*nbPose;
343 for (
unsigned int i=0; i<nbPose ; i++)
345 nbPoint[i] = table_cal[i].npt;
346 nbPointTotal += nbPoint[i];
349 if (nbPointTotal < 4) {
352 "Not enough point to calibrate")) ;
365 unsigned int curPoint = 0 ;
366 for (
unsigned int p=0; p<nbPose ; p++)
368 std::list<double>::const_iterator it_LoX = table_cal[p].LoX.begin();
369 std::list<double>::const_iterator it_LoY = table_cal[p].LoY.begin();
370 std::list<double>::const_iterator it_LoZ = table_cal[p].LoZ.begin();
371 std::list<vpImagePoint>::const_iterator it_Lip = table_cal[p].Lip.begin();
373 for (
unsigned int i =0 ; i < nbPoint[p] ; i++)
375 oX[curPoint] = *it_LoX;
376 oY[curPoint] = *it_LoY;
377 oZ[curPoint] = *it_LoZ;
380 u[curPoint] = ip.
get_u() ;
381 v[curPoint] = ip.
get_v() ;
392 unsigned int iter = 0 ;
394 double residu_1 = 1e12 ;
396 while (
vpMath::equal(residu_1,r,threshold) ==
false && iter < nbIterMax)
402 double px = cam_est.
get_px();
403 double py = cam_est.
get_py();
404 double u0 = cam_est.
get_u0();
405 double v0 = cam_est.
get_v0();
409 for (
unsigned int p=0; p<nbPose ; p++)
412 for (
unsigned int i=0 ; i < nbPoint[p]; i++)
414 unsigned int curPoint2 = 2*curPoint;
416 cX[curPoint] = oX[curPoint]*cMoTmp[0][0]+oY[curPoint]*cMoTmp[0][1]
417 +oZ[curPoint]*cMoTmp[0][2] + cMoTmp[0][3];
418 cY[curPoint] = oX[curPoint]*cMoTmp[1][0]+oY[curPoint]*cMoTmp[1][1]
419 +oZ[curPoint]*cMoTmp[1][2] + cMoTmp[1][3];
420 cZ[curPoint] = oX[curPoint]*cMoTmp[2][0]+oY[curPoint]*cMoTmp[2][1]
421 +oZ[curPoint]*cMoTmp[2][2] + cMoTmp[2][3];
423 Pd[curPoint2] = u[curPoint] ;
424 Pd[curPoint2+1] = v[curPoint] ;
426 P[curPoint2] = cX[curPoint]/cZ[curPoint]*px + u0 ;
427 P[curPoint2+1] = cY[curPoint]/cZ[curPoint]*py + v0 ;
439 vpMatrix L(nbPointTotal*2,nbPose6+4) ;
441 for (
unsigned int p=0; p<nbPose ; p++)
443 unsigned int q = 6*p;
444 for (
unsigned int i=0 ; i < nbPoint[p]; i++)
446 unsigned int curPoint2 = 2*curPoint;
447 unsigned int curPoint21 = curPoint2 + 1;
449 double x = cX[curPoint] ;
450 double y = cY[curPoint] ;
451 double z = cZ[curPoint] ;
461 L[curPoint2][q] = px * (-inv_z) ;
462 L[curPoint2][q+1] = 0 ;
463 L[curPoint2][q+2] = px*(X*inv_z) ;
464 L[curPoint2][q+3] = px*X*Y ;
465 L[curPoint2][q+4] = -px*(1+X*X) ;
466 L[curPoint2][q+5] = px*Y ;
469 L[curPoint2][nbPose6]= 1 ;
470 L[curPoint2][nbPose6+1]= 0 ;
471 L[curPoint2][nbPose6+2]= X ;
472 L[curPoint2][nbPose6+3]= 0;
475 L[curPoint21][q] = 0 ;
476 L[curPoint21][q+1] = py*(-inv_z) ;
477 L[curPoint21][q+2] = py*(Y*inv_z) ;
478 L[curPoint21][q+3] = py* (1+Y*Y) ;
479 L[curPoint21][q+4] = -py*X*Y ;
480 L[curPoint21][q+5] = -py*X ;
483 L[curPoint21][nbPose6]= 0 ;
484 L[curPoint21][nbPose6+1]= 1 ;
485 L[curPoint21][nbPose6+2]= 0;
486 L[curPoint21][nbPose6+3]= Y ;
494 Lp = L.pseudoInverse(1e-10) ;
503 for (
unsigned int i = 0 ; i < nbPose6 ; i++)
514 for (
unsigned int p = 0 ; p < nbPose ; p++)
516 for (
unsigned int i = 0 ; i < 6 ; i++)
517 Tc_v_Tmp[i] = Tc_v[6*p + i];
524 std::cout <<
" std dev " << sqrt(r/nbPointTotal) << std::endl;
527 if (iter == nbIterMax)
529 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)",nbIterMax);
531 "Maximum number of iterations reached")) ;
533 for (
unsigned int p = 0 ; p < nbPose ; p++)
535 table_cal[p].cMo_dist = table_cal[p].cMo ;
536 table_cal[p].cam = cam_est;
537 table_cal[p].cam_dist = cam_est;
538 double deviation,deviation_dist;
539 table_cal[p].computeStdDeviation(deviation,deviation_dist);
541 globalReprojectionError = sqrt(r/nbPointTotal);
543 std::cout.flags(original_flags);
551 std::ios::fmtflags original_flags( std::cout.flags() );
552 std::cout.precision(10);
553 unsigned int n_points =npt ;
564 std::list<double>::const_iterator it_LoX = LoX.begin();
565 std::list<double>::const_iterator it_LoY = LoY.begin();
566 std::list<double>::const_iterator it_LoZ = LoZ.begin();
567 std::list<vpImagePoint>::const_iterator it_Lip = Lip.begin();
571 for (
unsigned int i =0 ; i < n_points ; i++)
588 unsigned int iter = 0 ;
590 double residu_1 = 1e12 ;
592 while (
vpMath::equal(residu_1,r,threshold) ==
false && iter < nbIterMax)
598 double u0 = cam_est.
get_u0() ;
599 double v0 = cam_est.
get_v0() ;
601 double px = cam_est.
get_px() ;
602 double py = cam_est.
get_py() ;
604 double inv_px = 1/px ;
605 double inv_py = 1/py ;
607 double kud = cam_est.
get_kud() ;
608 double kdu = cam_est.
get_kdu() ;
614 for (
unsigned int i=0 ; i < n_points; i++)
616 unsigned int i4 = 4*i;
617 unsigned int i41 = 4*i+1;
618 unsigned int i42 = 4*i+2;
619 unsigned int i43 = 4*i+3;
621 cX[i] = oX[i]*cMo_est[0][0]+oY[i]*cMo_est[0][1]+oZ[i]*cMo_est[0][2] + cMo_est[0][3];
622 cY[i] = oX[i]*cMo_est[1][0]+oY[i]*cMo_est[1][1]+oZ[i]*cMo_est[1][2] + cMo_est[1][3];
623 cZ[i] = oX[i]*cMo_est[2][0]+oY[i]*cMo_est[2][1]+oZ[i]*cMo_est[2][2] + cMo_est[2][3];
643 double up0 = up - u0;
644 double vp0 = vp - v0;
646 double xp0 = up0 * inv_px;
647 double xp02 = xp0 *xp0 ;
649 double yp0 = vp0 * inv_py;
650 double yp02 = yp0 * yp0;
652 double r2du = xp02 + yp02 ;
653 double kr2du = kdu * r2du;
655 P[i4] = u0 + px*X - kr2du *(up0) ;
656 P[i41] = v0 + py*Y - kr2du *(vp0) ;
658 double r2ud = X2 + Y2 ;
659 double kr2ud = 1 + kud * r2ud;
661 double Axx = px*(kr2ud+k2ud*X2);
662 double Axy = px*k2ud*XY;
663 double Ayy = py*(kr2ud+k2ud*Y2);
664 double Ayx = py*k2ud*XY;
669 P[i42] = u0 + px*X*kr2ud ;
670 P[i43] = v0 + py*Y*kr2ud ;
680 L[i4][0] = px * (-inv_z) ;
682 L[i4][2] = px*X*inv_z ;
684 L[i4][4] = -px*(1+X2) ;
688 L[i4][6]= 1 + kr2du + k2du*xp02 ;
689 L[i4][7]= k2du*up0*yp0*inv_py ;
690 L[i4][8]= X + k2du*xp02*xp0 ;
691 L[i4][9]= k2du*up0*yp02*inv_py ;
692 L[i4][10] = -(up0)*(r2du) ;
697 L[i41][1] = py*(-inv_z) ;
698 L[i41][2] = py*Y*inv_z ;
699 L[i41][3] = py* (1+Y2) ;
704 L[i41][6]= k2du*xp0*vp0*inv_px ;
705 L[i41][7]= 1 + kr2du + k2du*yp02;
706 L[i41][8]= k2du*vp0*xp02*inv_px;
707 L[i41][9]= Y + k2du*yp02*yp0;
708 L[i41][10] = -vp0*r2du ;
713 L[i42][0] = Axx*(-inv_z) ;
714 L[i42][1] = Axy*(-inv_z) ;
715 L[i42][2] = Axx*(X*inv_z) + Axy*(Y*inv_z) ;
716 L[i42][3] = Axx*X*Y + Axy*(1+Y2);
717 L[i42][4] = -Axx*(1+X2) - Axy*XY;
718 L[i42][5] = Axx*Y -Axy*X;
726 L[i42][11] = px*X*r2ud ;
729 L[i43][0] = Ayx*(-inv_z) ;
730 L[i43][1] = Ayy*(-inv_z) ;
731 L[i43][2] = Ayx*(X*inv_z) + Ayy*(Y*inv_z) ;
732 L[i43][3] = Ayx*XY + Ayy*(1+Y2) ;
733 L[i43][4] = -Ayx*(1+X2) -Ayy*XY ;
734 L[i43][5] = Ayx*Y -Ayy*X;
742 L[i43][11] = py*Y*r2ud ;
752 Lp = L.pseudoInverse(1e-10) ;
760 for (
unsigned int i=0 ; i <6 ; i++)
764 u0 + Tc[6], v0 + Tc[7],
770 std::cout <<
" std dev " << sqrt(r/n_points) << std::endl;
773 if (iter == nbIterMax)
775 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)",nbIterMax);
777 "Maximum number of iterations reached")) ;
779 this->residual_dist = r;
784 std::cout <<
" std dev " << sqrt(r/n_points) << std::endl;
787 std::cout.flags(original_flags);
792 vpCalibration::calibVVSWithDistortionMulti(std::vector<vpCalibration> &table_cal,
796 std::ios::fmtflags original_flags( std::cout.flags() );
797 std::cout.precision(10);
798 unsigned int nbPoint[1024];
799 unsigned int nbPointTotal = 0;
800 unsigned int nbPose = (
unsigned int)table_cal.size();
801 unsigned int nbPose6 = 6*nbPose;
802 for (
unsigned int i=0; i<nbPose ; i++)
804 nbPoint[i] = table_cal[i].npt;
805 nbPointTotal += nbPoint[i];
808 if (nbPointTotal < 4)
812 "Not enough point to calibrate")) ;
825 unsigned int curPoint = 0 ;
826 for (
unsigned int p=0; p<nbPose ; p++)
828 std::list<double>::const_iterator it_LoX = table_cal[p].LoX.begin();
829 std::list<double>::const_iterator it_LoY = table_cal[p].LoY.begin();
830 std::list<double>::const_iterator it_LoZ = table_cal[p].LoZ.begin();
831 std::list<vpImagePoint>::const_iterator it_Lip = table_cal[p].Lip.begin();
833 for (
unsigned int i =0 ; i < nbPoint[p] ; i++)
835 oX[curPoint] = *it_LoX;
836 oY[curPoint] = *it_LoY;
837 oZ[curPoint] = *it_LoZ;
840 u[curPoint] = ip.
get_u() ;
841 v[curPoint] = ip.
get_v() ;
851 unsigned int iter = 0 ;
853 double residu_1 = 1e12 ;
855 while (
vpMath::equal(residu_1,r,threshold) ==
false && iter < nbIterMax)
862 for (
unsigned int p=0; p<nbPose ; p++)
865 for (
unsigned int i=0 ; i < nbPoint[p]; i++)
867 cX[curPoint] = oX[curPoint]*cMoTmp[0][0]+oY[curPoint]*cMoTmp[0][1]
868 +oZ[curPoint]*cMoTmp[0][2] + cMoTmp[0][3];
869 cY[curPoint] = oX[curPoint]*cMoTmp[1][0]+oY[curPoint]*cMoTmp[1][1]
870 +oZ[curPoint]*cMoTmp[1][2] + cMoTmp[1][3];
871 cZ[curPoint] = oX[curPoint]*cMoTmp[2][0]+oY[curPoint]*cMoTmp[2][1]
872 +oZ[curPoint]*cMoTmp[2][2] + cMoTmp[2][3];
879 vpMatrix L(nbPointTotal*4,nbPose6+6) ;
881 double px = cam_est.
get_px() ;
882 double py = cam_est.
get_py() ;
883 double u0 = cam_est.
get_u0() ;
884 double v0 = cam_est.
get_v0() ;
886 double inv_px = 1/px ;
887 double inv_py = 1/py ;
889 double kud = cam_est.
get_kud() ;
890 double kdu = cam_est.
get_kdu() ;
895 for (
unsigned int p=0; p<nbPose ; p++)
897 unsigned int q = 6*p;
898 for (
unsigned int i=0 ; i < nbPoint[p]; i++)
900 unsigned int curPoint4 = 4*curPoint;
901 double x = cX[curPoint] ;
902 double y = cY[curPoint] ;
903 double z = cZ[curPoint] ;
913 double up = u[curPoint] ;
914 double vp = v[curPoint] ;
917 Pd[curPoint4+1] = vp ;
919 double up0 = up - u0;
920 double vp0 = vp - v0;
922 double xp0 = up0 * inv_px;
923 double xp02 = xp0 *xp0 ;
925 double yp0 = vp0 * inv_py;
926 double yp02 = yp0 * yp0;
928 double r2du = xp02 + yp02 ;
929 double kr2du = kdu * r2du;
931 P[curPoint4] = u0 + px*X - kr2du *(up0) ;
932 P[curPoint4+1] = v0 + py*Y - kr2du *(vp0) ;
934 double r2ud = X2 + Y2 ;
935 double kr2ud = 1 + kud * r2ud;
937 double Axx = px*(kr2ud+k2ud*X2);
938 double Axy = px*k2ud*XY;
939 double Ayy = py*(kr2ud+k2ud*Y2);
940 double Ayx = py*k2ud*XY;
942 Pd[curPoint4+2] = up ;
943 Pd[curPoint4+3] = vp ;
945 P[curPoint4+2] = u0 + px*X*kr2ud ;
946 P[curPoint4+3] = v0 + py*Y*kr2ud ;
953 unsigned int curInd = curPoint4;
957 L[curInd][q] = px * (-inv_z) ;
959 L[curInd][q+2] = px*X*inv_z ;
960 L[curInd][q+3] = px*X*Y ;
961 L[curInd][q+4] = -px*(1+X2) ;
962 L[curInd][q+5] = px*Y ;
965 L[curInd][nbPose6]= 1 + kr2du + k2du*xp02 ;
966 L[curInd][nbPose6+1]= k2du*up0*yp0*inv_py ;
967 L[curInd][nbPose6+2]= X + k2du*xp02*xp0 ;
968 L[curInd][nbPose6+3]= k2du*up0*yp02*inv_py ;
969 L[curInd][nbPose6+4] = -(up0)*(r2du) ;
970 L[curInd][nbPose6+5] = 0 ;
975 L[curInd][q+1] = py*(-inv_z) ;
976 L[curInd][q+2] = py*Y*inv_z ;
977 L[curInd][q+3] = py* (1+Y2) ;
978 L[curInd][q+4] = -py*XY ;
979 L[curInd][q+5] = -py*X ;
982 L[curInd][nbPose6]= k2du*xp0*vp0*inv_px ;
983 L[curInd][nbPose6+1]= 1 + kr2du + k2du*yp02;
984 L[curInd][nbPose6+2]= k2du*vp0*xp02*inv_px;
985 L[curInd][nbPose6+3]= Y + k2du*yp02*yp0;
986 L[curInd][nbPose6+4] = -vp0*r2du ;
987 L[curInd][nbPose6+5] = 0 ;
992 L[curInd][q] = Axx*(-inv_z) ;
993 L[curInd][q+1] = Axy*(-inv_z) ;
994 L[curInd][q+2] = Axx*(X*inv_z) + Axy*(Y*inv_z) ;
995 L[curInd][q+3] = Axx*X*Y + Axy*(1+Y2);
996 L[curInd][q+4] = -Axx*(1+X2) - Axy*XY;
997 L[curInd][q+5] = Axx*Y -Axy*X;
1000 L[curInd][nbPose6]= 1 ;
1001 L[curInd][nbPose6+1]= 0 ;
1002 L[curInd][nbPose6+2]= X*kr2ud ;
1003 L[curInd][nbPose6+3]= 0;
1004 L[curInd][nbPose6+4] = 0 ;
1005 L[curInd][nbPose6+5] = px*X*r2ud ;
1009 L[curInd][q] = Ayx*(-inv_z) ;
1010 L[curInd][q+1] = Ayy*(-inv_z) ;
1011 L[curInd][q+2] = Ayx*(X*inv_z) + Ayy*(Y*inv_z) ;
1012 L[curInd][q+3] = Ayx*XY + Ayy*(1+Y2) ;
1013 L[curInd][q+4] = -Ayx*(1+X2) -Ayy*XY ;
1014 L[curInd][q+5] = Ayx*Y -Ayy*X;
1017 L[curInd][nbPose6]= 0 ;
1018 L[curInd][nbPose6+1]= 1;
1019 L[curInd][nbPose6+2]= 0;
1020 L[curInd][nbPose6+3]= Y*kr2ud ;
1021 L[curInd][nbPose6+4] = 0 ;
1022 L[curInd][nbPose6+5] = py*Y*r2ud ;
1035 L.pseudoInverse(Lp,1e-10) ;
1040 for (
unsigned int i = 0 ; i < 6*nbPose ; i++)
1044 u0+Tc[nbPose6], v0+Tc[nbPose6+1],
1045 kud + Tc[nbPose6+5],
1046 kdu + Tc[nbPose6+4]);
1049 for (
unsigned int p = 0 ; p < nbPose ; p++)
1051 for (
unsigned int i = 0 ; i < 6 ; i++)
1052 Tc_v_Tmp[i] = Tc_v[6*p + i];
1055 * table_cal[p].cMo_dist;
1058 std::cout <<
" std dev: " << sqrt(r/nbPointTotal) << std::endl;
1062 if (iter == nbIterMax)
1064 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)",nbIterMax);
1066 "Maximum number of iterations reached")) ;
1069 double perViewError;
1070 double totalError = 0;
1071 int totalPoints = 0;
1072 for (
unsigned int p = 0 ; p < nbPose ; p++)
1074 table_cal[p].cam_dist = cam_est ;
1075 perViewError = table_cal[p].computeStdDeviation_dist(table_cal[p].
cMo_dist, cam_est);
1076 totalError += perViewError*perViewError * table_cal[p].npt;
1077 totalPoints += (int)table_cal[p].npt;
1079 globalReprojectionError = sqrt(r/(nbPointTotal));
1082 std::cout.flags(original_flags);
1085 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
1112 unsigned int k = 0 ;
1114 for (
unsigned int i=0 ; i < nbPose ; i++)
1121 for (
unsigned int j=0 ; j < nbPose ; j++)
1136 double theta = sqrt(rPeij[0]*rPeij[0] + rPeij[1]*rPeij[1]
1137 + rPeij[2]*rPeij[2]);
1139 for (
unsigned int m=0;m<3;m++) rPeij[m] = rPeij[m] *
vpMath::sinc(theta/2);
1142 theta = sqrt(cijPo[0]*cijPo[0] + cijPo[1]*cijPo[1]
1143 + cijPo[2]*cijPo[2]);
1144 for (
unsigned int m=0;m<3;m++) cijPo[m] = cijPo[m] *
vpMath::sinc(theta/2);
1192 for (
unsigned int i=0 ; i < 3 ; i++) x[i] = 2*x[i]/sqrt(1+d) ;
1194 theta = 2*asin(theta) ;
1196 if (std::fabs(theta) > std::numeric_limits<double>::epsilon())
1198 for (
unsigned int i=0 ; i < 3 ; i++) x[i] *= theta/(2*sin(theta/2)) ;
1216 for (
unsigned int i=0 ; i < nbPose ; i++)
1226 for (
unsigned int j=0 ; j < nbPose ; j++)
1243 rTeij = rRej.
t()*rTeij ;
1249 b = eRc*cjTo - rReij*eRc*ciTo + rTeij ;
1309 std::vector<vpHomogeneousMatrix>& rMe,
1313 unsigned int nbPose = (
unsigned int)cMo.
size();
1318 unsigned int k = 0 ;
1320 for (
unsigned int i=0 ; i < nbPose ; i++)
1323 rMe[i].extract(rRei) ;
1324 cMo[i].extract(ciRo) ;
1327 for (
unsigned int j=0 ; j < nbPose ; j++)
1332 rMe[j].extract(rRej) ;
1333 cMo[j].extract(cjRo) ;
1342 double theta = sqrt(rPeij[0]*rPeij[0] + rPeij[1]*rPeij[1]
1343 + rPeij[2]*rPeij[2]);
1345 for (
unsigned int m=0;m<3;m++) rPeij[m] = rPeij[m] *
vpMath::sinc(theta/2);
1348 theta = sqrt(cijPo[0]*cijPo[0] + cijPo[1]*cijPo[1]
1349 + cijPo[2]*cijPo[2]);
1350 for (
unsigned int m=0;m<3;m++) cijPo[m] = cijPo[m] *
vpMath::sinc(theta/2);
1398 for (
unsigned int i=0 ; i < 3 ; i++) x[i] = 2*x[i]/sqrt(1+d) ;
1400 theta = 2*asin(theta) ;
1402 if (std::fabs(theta) > std::numeric_limits<double>::epsilon())
1404 for (
unsigned int i=0 ; i < 3 ; i++) x[i] *= theta/(2*sin(theta/2)) ;
1422 for (
unsigned int i=0 ; i < nbPose ; i++)
1426 rMe[i].extract(rRei) ;
1427 cMo[i].extract(ciRo) ;
1428 rMe[i].extract(rTei) ;
1429 cMo[i].extract(ciTo) ;
1432 for (
unsigned int j=0 ; j < nbPose ; j++)
1438 rMe[j].extract(rRej) ;
1439 cMo[j].extract(cjRo) ;
1442 rMe[j].extract(rTej) ;
1443 cMo[j].extract(cjTo) ;
1449 rTeij = rRej.
t()*rTeij ;
1455 b = eRc*cjTo - rReij*eRc*ciTo + rTeij ;
1501 vpCalibration::calibVVSMulti(
unsigned int nbPose,
1506 std::ios::fmtflags original_flags( std::cout.flags() );
1507 std::cout.precision(10);
1508 unsigned int nbPoint[256];
1509 unsigned int nbPointTotal = 0;
1511 unsigned int nbPose6 = 6*nbPose;
1513 for (
unsigned int i=0; i<nbPose ; i++)
1515 nbPoint[i] = table_cal[i].npt;
1516 nbPointTotal += nbPoint[i];
1519 if (nbPointTotal < 4)
1523 "Not enough point to calibrate")) ;
1536 unsigned int curPoint = 0 ;
1537 for (
unsigned int p=0; p<nbPose ; p++)
1539 std::list<double>::const_iterator it_LoX = table_cal[p].LoX.begin();
1540 std::list<double>::const_iterator it_LoY = table_cal[p].LoY.begin();
1541 std::list<double>::const_iterator it_LoZ = table_cal[p].LoZ.begin();
1542 std::list<vpImagePoint>::const_iterator it_Lip = table_cal[p].Lip.begin();
1544 for (
unsigned int i =0 ; i < nbPoint[p] ; i++)
1546 oX[curPoint] = *it_LoX;
1547 oY[curPoint] = *it_LoY;
1548 oZ[curPoint] = *it_LoZ;
1551 u[curPoint] = ip.
get_u() ;
1552 v[curPoint] = ip.
get_v() ;
1563 unsigned int iter = 0 ;
1565 double residu_1 = 1e12 ;
1567 while (
vpMath::equal(residu_1,r,threshold) ==
false && iter < nbIterMax)
1573 double px = cam_est.
get_px();
1574 double py = cam_est.
get_py();
1575 double u0 = cam_est.
get_u0();
1576 double v0 = cam_est.
get_v0();
1580 for (
unsigned int p=0; p<nbPose ; p++)
1583 for (
unsigned int i=0 ; i < nbPoint[p]; i++)
1585 unsigned int curPoint2 = 2*curPoint;
1587 cX[curPoint] = oX[curPoint]*cMoTmp[0][0]+oY[curPoint]*cMoTmp[0][1]
1588 +oZ[curPoint]*cMoTmp[0][2] + cMoTmp[0][3];
1589 cY[curPoint] = oX[curPoint]*cMoTmp[1][0]+oY[curPoint]*cMoTmp[1][1]
1590 +oZ[curPoint]*cMoTmp[1][2] + cMoTmp[1][3];
1591 cZ[curPoint] = oX[curPoint]*cMoTmp[2][0]+oY[curPoint]*cMoTmp[2][1]
1592 +oZ[curPoint]*cMoTmp[2][2] + cMoTmp[2][3];
1594 Pd[curPoint2] = u[curPoint] ;
1595 Pd[curPoint2+1] = v[curPoint] ;
1597 P[curPoint2] = cX[curPoint]/cZ[curPoint]*px + u0 ;
1598 P[curPoint2+1] = cY[curPoint]/cZ[curPoint]*py + v0 ;
1610 vpMatrix L(nbPointTotal*2,nbPose6+4) ;
1612 for (
unsigned int p=0; p<nbPose ; p++)
1614 unsigned int q = 6*p;
1615 for (
unsigned int i=0 ; i < nbPoint[p]; i++)
1617 unsigned int curPoint2 = 2*curPoint;
1618 unsigned int curPoint21 = curPoint2 + 1;
1620 double x = cX[curPoint] ;
1621 double y = cY[curPoint] ;
1622 double z = cZ[curPoint] ;
1626 double X = x*inv_z ;
1627 double Y = y*inv_z ;
1632 L[curPoint2][q] = px * (-inv_z) ;
1633 L[curPoint2][q+1] = 0 ;
1634 L[curPoint2][q+2] = px*(X*inv_z) ;
1635 L[curPoint2][q+3] = px*X*Y ;
1636 L[curPoint2][q+4] = -px*(1+X*X) ;
1637 L[curPoint2][q+5] = px*Y ;
1640 L[curPoint2][nbPose6]= 1 ;
1641 L[curPoint2][nbPose6+1]= 0 ;
1642 L[curPoint2][nbPose6+2]= X ;
1643 L[curPoint2][nbPose6+3]= 0;
1646 L[curPoint21][q] = 0 ;
1647 L[curPoint21][q+1] = py*(-inv_z) ;
1648 L[curPoint21][q+2] = py*(Y*inv_z) ;
1649 L[curPoint21][q+3] = py* (1+Y*Y) ;
1650 L[curPoint21][q+4] = -py*X*Y ;
1651 L[curPoint21][q+5] = -py*X ;
1654 L[curPoint21][nbPose6]= 0 ;
1655 L[curPoint21][nbPose6+1]= 1 ;
1656 L[curPoint21][nbPose6+2]= 0;
1657 L[curPoint21][nbPose6+3]= Y ;
1665 Lp = L.pseudoInverse(1e-10) ;
1674 for (
unsigned int i = 0 ; i < nbPose6 ; i++)
1685 for (
unsigned int p = 0 ; p < nbPose ; p++)
1687 for (
unsigned int i = 0 ; i < 6 ; i++)
1688 Tc_v_Tmp[i] = Tc_v[6*p + i];
1694 std::cout <<
" std dev " << sqrt(r/nbPointTotal) << std::endl;
1697 if (iter == nbIterMax)
1699 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)",nbIterMax);
1701 "Maximum number of iterations reached")) ;
1703 for (
unsigned int p = 0 ; p < nbPose ; p++)
1706 table_cal[p].
cam = cam_est;
1708 double deviation,deviation_dist;
1712 std::cout <<
" Global std dev " << sqrt(r/nbPointTotal) << std::endl;
1715 std::cout.flags(original_flags);
1720 vpCalibration::calibVVSWithDistortionMulti(
1721 unsigned int nbPose,
1726 std::ios::fmtflags original_flags( std::cout.flags() );
1727 std::cout.precision(10);
1728 unsigned int nbPoint[1024];
1729 unsigned int nbPointTotal = 0;
1731 unsigned int nbPose6 = 6*nbPose;
1732 for (
unsigned int i=0; i<nbPose ; i++)
1734 nbPoint[i] = table_cal[i].npt;
1735 nbPointTotal += nbPoint[i];
1738 if (nbPointTotal < 4)
1742 "Not enough point to calibrate")) ;
1755 unsigned int curPoint = 0 ;
1756 for (
unsigned int p=0; p<nbPose ; p++)
1758 std::list<double>::const_iterator it_LoX = table_cal[p].LoX.begin();
1759 std::list<double>::const_iterator it_LoY = table_cal[p].LoY.begin();
1760 std::list<double>::const_iterator it_LoZ = table_cal[p].LoZ.begin();
1761 std::list<vpImagePoint>::const_iterator it_Lip = table_cal[p].Lip.begin();
1763 for (
unsigned int i =0 ; i < nbPoint[p] ; i++)
1765 oX[curPoint] = *it_LoX;
1766 oY[curPoint] = *it_LoY;
1767 oZ[curPoint] = *it_LoZ;
1770 u[curPoint] = ip.
get_u() ;
1771 v[curPoint] = ip.
get_v() ;
1781 unsigned int iter = 0 ;
1783 double residu_1 = 1e12 ;
1785 while (
vpMath::equal(residu_1,r,threshold) ==
false && iter < nbIterMax)
1792 for (
unsigned int p=0; p<nbPose ; p++)
1795 for (
unsigned int i=0 ; i < nbPoint[p]; i++)
1797 cX[curPoint] = oX[curPoint]*cMoTmp[0][0]+oY[curPoint]*cMoTmp[0][1]
1798 +oZ[curPoint]*cMoTmp[0][2] + cMoTmp[0][3];
1799 cY[curPoint] = oX[curPoint]*cMoTmp[1][0]+oY[curPoint]*cMoTmp[1][1]
1800 +oZ[curPoint]*cMoTmp[1][2] + cMoTmp[1][3];
1801 cZ[curPoint] = oX[curPoint]*cMoTmp[2][0]+oY[curPoint]*cMoTmp[2][1]
1802 +oZ[curPoint]*cMoTmp[2][2] + cMoTmp[2][3];
1809 vpMatrix L(nbPointTotal*4,nbPose6+6) ;
1811 double px = cam_est.
get_px() ;
1812 double py = cam_est.
get_py() ;
1813 double u0 = cam_est.
get_u0() ;
1814 double v0 = cam_est.
get_v0() ;
1816 double inv_px = 1/px ;
1817 double inv_py = 1/py ;
1819 double kud = cam_est.
get_kud() ;
1820 double kdu = cam_est.
get_kdu() ;
1822 double k2ud = 2*kud;
1823 double k2du = 2*kdu;
1825 for (
unsigned int p=0; p<nbPose ; p++)
1827 unsigned int q = 6*p;
1828 for (
unsigned int i=0 ; i < nbPoint[p]; i++)
1830 unsigned int curPoint4 = 4*curPoint;
1831 double x = cX[curPoint] ;
1832 double y = cY[curPoint] ;
1833 double z = cZ[curPoint] ;
1836 double X = x*inv_z ;
1837 double Y = y*inv_z ;
1843 double up = u[curPoint] ;
1844 double vp = v[curPoint] ;
1846 Pd[curPoint4] = up ;
1847 Pd[curPoint4+1] = vp ;
1849 double up0 = up - u0;
1850 double vp0 = vp - v0;
1852 double xp0 = up0 * inv_px;
1853 double xp02 = xp0 *xp0 ;
1855 double yp0 = vp0 * inv_py;
1856 double yp02 = yp0 * yp0;
1858 double r2du = xp02 + yp02 ;
1859 double kr2du = kdu * r2du;
1861 P[curPoint4] = u0 + px*X - kr2du *(up0) ;
1862 P[curPoint4+1] = v0 + py*Y - kr2du *(vp0) ;
1864 double r2ud = X2 + Y2 ;
1865 double kr2ud = 1 + kud * r2ud;
1867 double Axx = px*(kr2ud+k2ud*X2);
1868 double Axy = px*k2ud*XY;
1869 double Ayy = py*(kr2ud+k2ud*Y2);
1870 double Ayx = py*k2ud*XY;
1872 Pd[curPoint4+2] = up ;
1873 Pd[curPoint4+3] = vp ;
1875 P[curPoint4+2] = u0 + px*X*kr2ud ;
1876 P[curPoint4+3] = v0 + py*Y*kr2ud ;
1881 vpMath::sqr(P[curPoint4+3]-Pd[curPoint4+3]))*0.5 ;
1883 unsigned int curInd = curPoint4;
1887 L[curInd][q] = px * (-inv_z) ;
1888 L[curInd][q+1] = 0 ;
1889 L[curInd][q+2] = px*X*inv_z ;
1890 L[curInd][q+3] = px*X*Y ;
1891 L[curInd][q+4] = -px*(1+X2) ;
1892 L[curInd][q+5] = px*Y ;
1895 L[curInd][nbPose6]= 1 + kr2du + k2du*xp02 ;
1896 L[curInd][nbPose6+1]= k2du*up0*yp0*inv_py ;
1897 L[curInd][nbPose6+2]= X + k2du*xp02*xp0 ;
1898 L[curInd][nbPose6+3]= k2du*up0*yp02*inv_py ;
1899 L[curInd][nbPose6+4] = -(up0)*(r2du) ;
1900 L[curInd][nbPose6+5] = 0 ;
1905 L[curInd][q+1] = py*(-inv_z) ;
1906 L[curInd][q+2] = py*Y*inv_z ;
1907 L[curInd][q+3] = py* (1+Y2) ;
1908 L[curInd][q+4] = -py*XY ;
1909 L[curInd][q+5] = -py*X ;
1912 L[curInd][nbPose6]= k2du*xp0*vp0*inv_px ;
1913 L[curInd][nbPose6+1]= 1 + kr2du + k2du*yp02;
1914 L[curInd][nbPose6+2]= k2du*vp0*xp02*inv_px;
1915 L[curInd][nbPose6+3]= Y + k2du*yp02*yp0;
1916 L[curInd][nbPose6+4] = -vp0*r2du ;
1917 L[curInd][nbPose6+5] = 0 ;
1922 L[curInd][q] = Axx*(-inv_z) ;
1923 L[curInd][q+1] = Axy*(-inv_z) ;
1924 L[curInd][q+2] = Axx*(X*inv_z) + Axy*(Y*inv_z) ;
1925 L[curInd][q+3] = Axx*X*Y + Axy*(1+Y2);
1926 L[curInd][q+4] = -Axx*(1+X2) - Axy*XY;
1927 L[curInd][q+5] = Axx*Y -Axy*X;
1930 L[curInd][nbPose6]= 1 ;
1931 L[curInd][nbPose6+1]= 0 ;
1932 L[curInd][nbPose6+2]= X*kr2ud ;
1933 L[curInd][nbPose6+3]= 0;
1934 L[curInd][nbPose6+4] = 0 ;
1935 L[curInd][nbPose6+5] = px*X*r2ud ;
1939 L[curInd][q] = Ayx*(-inv_z) ;
1940 L[curInd][q+1] = Ayy*(-inv_z) ;
1941 L[curInd][q+2] = Ayx*(X*inv_z) + Ayy*(Y*inv_z) ;
1942 L[curInd][q+3] = Ayx*XY + Ayy*(1+Y2) ;
1943 L[curInd][q+4] = -Ayx*(1+X2) -Ayy*XY ;
1944 L[curInd][q+5] = Ayx*Y -Ayy*X;
1947 L[curInd][nbPose6]= 0 ;
1948 L[curInd][nbPose6+1]= 1;
1949 L[curInd][nbPose6+2]= 0;
1950 L[curInd][nbPose6+3]= Y*kr2ud ;
1951 L[curInd][nbPose6+4] = 0 ;
1952 L[curInd][nbPose6+5] = py*Y*r2ud ;
1965 L.pseudoInverse(Lp,1e-10) ;
1970 for (
unsigned int i = 0 ; i < 6*nbPose ; i++)
1974 u0+Tc[nbPose6], v0+Tc[nbPose6+1],
1975 kud + Tc[nbPose6+5],
1976 kdu + Tc[nbPose6+4]);
1979 for (
unsigned int p = 0 ; p < nbPose ; p++)
1981 for (
unsigned int i = 0 ; i < 6 ; i++)
1982 Tc_v_Tmp[i] = Tc_v[6*p + i];
1988 std::cout <<
" std dev: " << sqrt(r/nbPointTotal) << std::endl;
1992 if (iter == nbIterMax)
1994 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)",nbIterMax);
1996 "Maximum number of iterations reached")) ;
1999 for (
unsigned int p = 0 ; p < nbPose ; p++)
2005 std::cout <<
" Global std dev " << sqrt(r/(nbPointTotal)) << std::endl;
2008 std::cout.flags(original_flags);
Definition of the vpMatrix class.
Error that can be emited by the vpCalibration class.
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
static bool equal(double x, double y, double s=0.001)
vpRotationMatrix t() const
transpose
void setIdentity()
Basic initialisation (identity)
Tools for perspective camera calibration.
double sumSquare() const
return sum of the Aij^2 (for all i, for all j)
static double sinc(double x)
vpHomogeneousMatrix cMo
(as a 3x4 matrix [R T])
The vpRotationMatrix considers the particular case of a rotation matrix.
unsigned int size() const
void initPersProjWithoutDistortion(const double px, const double py, const double u0, const double v0)
void insert(const vpRotationMatrix &R)
void svd(vpColVector &w, vpMatrix &v)
something is not initialized
static double sqr(double x)
vpHomogeneousMatrix cMo_dist
Generic class defining intrinsic camera parameters.
void extract(vpRotationMatrix &R) const
void stackMatrices(const vpMatrix &A)
double computeStdDeviation_dist(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam)
static void calibrationTsai(std::vector< vpHomogeneousMatrix > &cMo, std::vector< vpHomogeneousMatrix > &rMe, vpHomogeneousMatrix &eMc)
calibration method of effector-camera from R. Tsai and R. Lorenz .
vpCameraParameters cam_dist
projection model with distortion
Class that provides a data structure for the column vectors as well as a set of operations on these v...
vpHomogeneousMatrix inverse() const
iterative algorithm doesn't converge
static vpHomogeneousMatrix direct(const vpColVector &v)
static vpMatrix skew(const vpColVector &v)
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
void computeStdDeviation(double &deviation, double &deviation_dist)
vpCameraParameters cam
projection model without distortion
Class that consider the case of a translation vector.
Class that consider the case of the parameterization for the rotation.
void initPersProjWithDistortion(const double px, const double py, const double u0, const double v0, const double kud, const double kdu)