40 #include <visp3/core/vpMath.h> 41 #include <visp3/core/vpPixelMeterConversion.h> 42 #include <visp3/vision/vpCalibration.h> 43 #include <visp3/vision/vpPose.h> 57 std::list<double>::const_iterator it_LoX = LoX.begin();
58 std::list<double>::const_iterator it_LoY = LoY.begin();
59 std::list<double>::const_iterator it_LoZ = LoZ.begin();
60 std::list<vpImagePoint>::const_iterator it_Lip = Lip.begin();
64 for (
unsigned int i = 0; i < npt; i++) {
72 double xi = ip.
get_u();
73 double yi = ip.
get_v();
75 A[2 * i][0] = x0 * xi;
76 A[2 * i][1] = y0 * xi;
77 A[2 * i][2] = z0 * xi;
87 A[2 * i + 1][0] = x0 * yi;
88 A[2 * i + 1][1] = y0 * yi;
89 A[2 * i + 1][2] = z0 * yi;
90 B[2 * i + 1][0] = 0.0;
91 B[2 * i + 1][1] = 0.0;
92 B[2 * i + 1][2] = 0.0;
93 B[2 * i + 1][3] = -x0;
94 B[2 * i + 1][4] = -y0;
95 B[2 * i + 1][5] = -z0;
96 B[2 * i + 1][6] = 0.0;
97 B[2 * i + 1][7] = -1.0;
123 e = -(A.t() * B) * r;
137 unsigned int imin = 1;
138 for (
unsigned int i = 0; i < x1.getRows(); i++) {
147 for (
unsigned int i = 0; i < x1.getRows(); i++) {
148 if (x1[i] < x1[imin])
152 for (
unsigned int i = 0; i < x1.getRows(); i++)
153 x1[i] = AtA[i][imin];
159 for (
unsigned int i = 0; i < 3; i++)
161 for (
unsigned int i = 0; i < 9; i++)
167 for (
unsigned int i = 0; i < 12; i++)
170 resul[0] = sol[3] * sol[0] + sol[4] * sol[1] + sol[5] * sol[2];
172 resul[1] = sol[6] * sol[0] + sol[7] * sol[1] + sol[8] * sol[2];
174 resul[2] = sqrt(sol[3] * sol[3] + sol[4] * sol[4] + sol[5] * sol[5]
175 - resul[0] * resul[0]);
176 resul[3] = sqrt(sol[6] * sol[6] + sol[7] * sol[7] + sol[8] * sol[8]
177 - resul[1] * resul[1]);
181 resul[4] = (sol[9] - sol[11] * resul[0]) / resul[2];
182 resul[5] = (sol[10] - sol[11] * resul[1]) / resul[3];
187 for (
unsigned int i = 0; i < 3; i++)
188 rd[0][i] = (sol[i + 3] - sol[i] * resul[0]) / resul[2];
189 for (
unsigned int i = 0; i < 3; i++)
190 rd[1][i] = (sol[i + 6] - sol[i] * resul[1]) / resul[3];
191 for (
unsigned int i = 0; i < 3; i++)
197 for (
unsigned int i = 0; i < 3; i++) {
198 for (
unsigned int j = 0; j < 3; j++)
199 cMo_est[i][j] = rd[i][j];
201 for (
unsigned int i = 0; i < 3; i++)
202 cMo_est[i][3] = resul[i + 4];
207 double deviation, deviation_dist;
213 std::ios::fmtflags original_flags(std::cout.flags());
214 std::cout.precision(10);
215 unsigned int n_points = npt;
228 std::list<double>::const_iterator it_LoX = LoX.begin();
229 std::list<double>::const_iterator it_LoY = LoY.begin();
230 std::list<double>::const_iterator it_LoZ = LoZ.begin();
231 std::list<vpImagePoint>::const_iterator it_Lip = Lip.begin();
233 for (
unsigned int i = 0; i < n_points; i++) {
250 unsigned int iter = 0;
252 double residu_1 = 1e12;
254 while (
vpMath::equal(residu_1, r, threshold) ==
false && iter < nbIterMax) {
258 double px = cam_est.
get_px();
259 double py = cam_est.
get_py();
260 double u0 = cam_est.
get_u0();
261 double v0 = cam_est.
get_v0();
265 for (
unsigned int i = 0; i < n_points; i++) {
266 cX[i] = oX[i] * cMo_est[0][0] + oY[i] * cMo_est[0][1] + oZ[i] * cMo_est[0][2] + cMo_est[0][3];
267 cY[i] = oX[i] * cMo_est[1][0] + oY[i] * cMo_est[1][1] + oZ[i] * cMo_est[1][2] + cMo_est[1][3];
268 cZ[i] = oX[i] * cMo_est[2][0] + oY[i] * cMo_est[2][1] + oZ[i] * cMo_est[2][2] + cMo_est[2][3];
271 Pd[2 * i + 1] = v[i];
273 P[2 * i] = cX[i] / cZ[i] * px + u0;
274 P[2 * i + 1] = cY[i] / cZ[i] * py + v0;
284 for (
unsigned int i = 0; i < n_points; i++) {
288 double inv_z = 1 / z;
290 double X = x * inv_z;
291 double Y = y * inv_z;
295 L[2 * i][0] = px * (-inv_z);
297 L[2 * i][2] = px * X * inv_z;
298 L[2 * i][3] = px * X * Y;
299 L[2 * i][4] = -px * (1 + X * X);
300 L[2 * i][5] = px * Y;
310 L[2 * i + 1][1] = py * (-inv_z);
311 L[2 * i + 1][2] = py * (Y * inv_z);
312 L[2 * i + 1][3] = py * (1 + Y * Y);
313 L[2 * i + 1][4] = -py * X * Y;
314 L[2 * i + 1][5] = -py * X;
324 Lp = L.pseudoInverse(1e-10);
333 for (
unsigned int i = 0; i < 6; i++)
340 std::cout <<
" std dev " << sqrt(r / n_points) << std::endl;
342 if (iter == nbIterMax) {
343 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)", nbIterMax);
349 this->residual_dist = r;
351 std::cout <<
" std dev " << sqrt(r / n_points) << std::endl;
353 std::cout.flags(original_flags);
356 void vpCalibration::calibVVSMulti(std::vector<vpCalibration> &table_cal,
vpCameraParameters &cam_est,
357 double &globalReprojectionError,
bool verbose)
359 std::ios::fmtflags original_flags(std::cout.flags());
360 std::cout.precision(10);
361 unsigned int nbPoint[256];
362 unsigned int nbPointTotal = 0;
363 unsigned int nbPose = (
unsigned int)table_cal.size();
364 unsigned int nbPose6 = 6 * nbPose;
366 for (
unsigned int i = 0; i < nbPose; i++) {
367 nbPoint[i] = table_cal[i].npt;
368 nbPointTotal += nbPoint[i];
371 if (nbPointTotal < 4) {
386 unsigned int curPoint = 0;
387 for (
unsigned int p = 0; p < nbPose; p++) {
388 std::list<double>::const_iterator it_LoX = table_cal[p].LoX.begin();
389 std::list<double>::const_iterator it_LoY = table_cal[p].LoY.begin();
390 std::list<double>::const_iterator it_LoZ = table_cal[p].LoZ.begin();
391 std::list<vpImagePoint>::const_iterator it_Lip = table_cal[p].Lip.begin();
393 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
394 oX[curPoint] = *it_LoX;
395 oY[curPoint] = *it_LoY;
396 oZ[curPoint] = *it_LoZ;
399 u[curPoint] = ip.
get_u();
400 v[curPoint] = ip.
get_v();
411 unsigned int iter = 0;
413 double residu_1 = 1e12;
415 while (
vpMath::equal(residu_1, r, threshold) ==
false && iter < nbIterMax) {
420 double px = cam_est.
get_px();
421 double py = cam_est.
get_py();
422 double u0 = cam_est.
get_u0();
423 double v0 = cam_est.
get_v0();
427 for (
unsigned int p = 0; p < nbPose; p++) {
429 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
430 unsigned int curPoint2 = 2 * curPoint;
433 oX[curPoint] * cMoTmp[0][0] + oY[curPoint] * cMoTmp[0][1] + oZ[curPoint] * cMoTmp[0][2] + cMoTmp[0][3];
435 oX[curPoint] * cMoTmp[1][0] + oY[curPoint] * cMoTmp[1][1] + oZ[curPoint] * cMoTmp[1][2] + cMoTmp[1][3];
437 oX[curPoint] * cMoTmp[2][0] + oY[curPoint] * cMoTmp[2][1] + oZ[curPoint] * cMoTmp[2][2] + cMoTmp[2][3];
439 Pd[curPoint2] = u[curPoint];
440 Pd[curPoint2 + 1] = v[curPoint];
442 P[curPoint2] = cX[curPoint] / cZ[curPoint] * px + u0;
443 P[curPoint2 + 1] = cY[curPoint] / cZ[curPoint] * py + v0;
454 vpMatrix L(nbPointTotal * 2, nbPose6 + 4);
456 for (
unsigned int p = 0; p < nbPose; p++) {
457 unsigned int q = 6 * p;
458 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
459 unsigned int curPoint2 = 2 * curPoint;
460 unsigned int curPoint21 = curPoint2 + 1;
462 double x = cX[curPoint];
463 double y = cY[curPoint];
464 double z = cZ[curPoint];
466 double inv_z = 1 / z;
468 double X = x * inv_z;
469 double Y = y * inv_z;
474 L[curPoint2][q] = px * (-inv_z);
475 L[curPoint2][q + 1] = 0;
476 L[curPoint2][q + 2] = px * (X * inv_z);
477 L[curPoint2][q + 3] = px * X * Y;
478 L[curPoint2][q + 4] = -px * (1 + X * X);
479 L[curPoint2][q + 5] = px * Y;
482 L[curPoint2][nbPose6] = 1;
483 L[curPoint2][nbPose6 + 1] = 0;
484 L[curPoint2][nbPose6 + 2] = X;
485 L[curPoint2][nbPose6 + 3] = 0;
488 L[curPoint21][q] = 0;
489 L[curPoint21][q + 1] = py * (-inv_z);
490 L[curPoint21][q + 2] = py * (Y * inv_z);
491 L[curPoint21][q + 3] = py * (1 + Y * Y);
492 L[curPoint21][q + 4] = -py * X * Y;
493 L[curPoint21][q + 5] = -py * X;
496 L[curPoint21][nbPose6] = 0;
497 L[curPoint21][nbPose6 + 1] = 1;
498 L[curPoint21][nbPose6 + 2] = 0;
499 L[curPoint21][nbPose6 + 3] = Y;
506 Lp = L.pseudoInverse(1e-10);
515 for (
unsigned int i = 0; i < nbPose6; i++)
519 v0 + Tc[nbPose6 + 1]);
524 for (
unsigned int p = 0; p < nbPose; p++) {
525 for (
unsigned int i = 0; i < 6; i++)
526 Tc_v_Tmp[i] = Tc_v[6 * p + i];
532 std::cout <<
" std dev " << sqrt(r / nbPointTotal) << std::endl;
534 if (iter == nbIterMax) {
535 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)", nbIterMax);
538 for (
unsigned int p = 0; p < nbPose; p++) {
539 table_cal[p].cMo_dist = table_cal[p].cMo;
540 table_cal[p].cam = cam_est;
541 table_cal[p].cam_dist = cam_est;
542 double deviation, deviation_dist;
543 table_cal[p].computeStdDeviation(deviation, deviation_dist);
545 globalReprojectionError = sqrt(r / nbPointTotal);
547 std::cout.flags(original_flags);
552 std::ios::fmtflags original_flags(std::cout.flags());
553 std::cout.precision(10);
554 unsigned int n_points = npt;
565 std::list<double>::const_iterator it_LoX = LoX.begin();
566 std::list<double>::const_iterator it_LoY = LoY.begin();
567 std::list<double>::const_iterator it_LoZ = LoZ.begin();
568 std::list<vpImagePoint>::const_iterator it_Lip = Lip.begin();
572 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) {
597 double u0 = cam_est.
get_u0();
598 double v0 = cam_est.
get_v0();
600 double px = cam_est.
get_px();
601 double py = cam_est.
get_py();
603 double inv_px = 1 / px;
604 double inv_py = 1 / py;
606 double kud = cam_est.
get_kud();
607 double kdu = cam_est.
get_kdu();
609 double k2ud = 2 * kud;
610 double k2du = 2 * kdu;
613 for (
unsigned int i = 0; i < n_points; i++) {
614 unsigned int i4 = 4 * i;
615 unsigned int i41 = 4 * i + 1;
616 unsigned int i42 = 4 * i + 2;
617 unsigned int i43 = 4 * i + 3;
619 cX[i] = oX[i] * cMo_est[0][0] + oY[i] * cMo_est[0][1] + oZ[i] * cMo_est[0][2] + cMo_est[0][3];
620 cY[i] = oX[i] * cMo_est[1][0] + oY[i] * cMo_est[1][1] + oZ[i] * cMo_est[1][2] + cMo_est[1][3];
621 cZ[i] = oX[i] * cMo_est[2][0] + oY[i] * cMo_est[2][1] + oZ[i] * cMo_est[2][2] + cMo_est[2][3];
626 double inv_z = 1 / z;
628 double X = x * inv_z;
629 double Y = y * inv_z;
641 double up0 = up - u0;
642 double vp0 = vp - v0;
644 double xp0 = up0 * inv_px;
645 double xp02 = xp0 * xp0;
647 double yp0 = vp0 * inv_py;
648 double yp02 = yp0 * yp0;
650 double r2du = xp02 + yp02;
651 double kr2du = kdu * r2du;
653 P[i4] = u0 + px * X - kr2du * (up0);
654 P[i41] = v0 + py * Y - kr2du * (vp0);
656 double r2ud = X2 + Y2;
657 double kr2ud = 1 + kud * r2ud;
659 double Axx = px * (kr2ud + k2ud * X2);
660 double Axy = px * k2ud * XY;
661 double Ayy = py * (kr2ud + k2ud * Y2);
662 double Ayx = py * k2ud * XY;
667 P[i42] = u0 + px * X * kr2ud;
668 P[i43] = v0 + py * Y * kr2ud;
677 L[i4][0] = px * (-inv_z);
679 L[i4][2] = px * X * inv_z;
680 L[i4][3] = px * X * Y;
681 L[i4][4] = -px * (1 + X2);
685 L[i4][6] = 1 + kr2du + k2du * xp02;
686 L[i4][7] = k2du * up0 * yp0 * inv_py;
687 L[i4][8] = X + k2du * xp02 * xp0;
688 L[i4][9] = k2du * up0 * yp02 * inv_py;
689 L[i4][10] = -(up0) * (r2du);
694 L[i41][1] = py * (-inv_z);
695 L[i41][2] = py * Y * inv_z;
696 L[i41][3] = py * (1 + Y2);
697 L[i41][4] = -py * XY;
701 L[i41][6] = k2du * xp0 * vp0 * inv_px;
702 L[i41][7] = 1 + kr2du + k2du * yp02;
703 L[i41][8] = k2du * vp0 * xp02 * inv_px;
704 L[i41][9] = Y + k2du * yp02 * yp0;
705 L[i41][10] = -vp0 * r2du;
710 L[i42][0] = Axx * (-inv_z);
711 L[i42][1] = Axy * (-inv_z);
712 L[i42][2] = Axx * (X * inv_z) + Axy * (Y * inv_z);
713 L[i42][3] = Axx * X * Y + Axy * (1 + Y2);
714 L[i42][4] = -Axx * (1 + X2) - Axy * XY;
715 L[i42][5] = Axx * Y - Axy * X;
720 L[i42][8] = X * kr2ud;
723 L[i42][11] = px * X * r2ud;
726 L[i43][0] = Ayx * (-inv_z);
727 L[i43][1] = Ayy * (-inv_z);
728 L[i43][2] = Ayx * (X * inv_z) + Ayy * (Y * inv_z);
729 L[i43][3] = Ayx * XY + Ayy * (1 + Y2);
730 L[i43][4] = -Ayx * (1 + X2) - Ayy * XY;
731 L[i43][5] = Ayx * Y - Ayy * X;
737 L[i43][9] = Y * kr2ud;
739 L[i43][11] = py * Y * r2ud;
749 Lp = L.pseudoInverse(1e-10);
757 for (
unsigned int i = 0; i < 6; i++)
764 std::cout <<
" std dev " << sqrt(r / n_points) << std::endl;
766 if (iter == nbIterMax) {
767 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)", nbIterMax);
770 this->residual_dist = r;
775 std::cout <<
" std dev " << sqrt(r / n_points) << std::endl;
778 std::cout.flags(original_flags);
781 void vpCalibration::calibVVSWithDistortionMulti(std::vector<vpCalibration> &table_cal,
vpCameraParameters &cam_est,
782 double &globalReprojectionError,
bool verbose)
784 std::ios::fmtflags original_flags(std::cout.flags());
785 std::cout.precision(10);
786 unsigned int nbPoint[1024];
787 unsigned int nbPointTotal = 0;
788 unsigned int nbPose = (
unsigned int)table_cal.size();
789 unsigned int nbPose6 = 6 * nbPose;
790 for (
unsigned int i = 0; i < nbPose; i++) {
791 nbPoint[i] = table_cal[i].npt;
792 nbPointTotal += nbPoint[i];
795 if (nbPointTotal < 4) {
810 unsigned int curPoint = 0;
811 for (
unsigned int p = 0; p < nbPose; p++) {
812 std::list<double>::const_iterator it_LoX = table_cal[p].LoX.begin();
813 std::list<double>::const_iterator it_LoY = table_cal[p].LoY.begin();
814 std::list<double>::const_iterator it_LoZ = table_cal[p].LoZ.begin();
815 std::list<vpImagePoint>::const_iterator it_Lip = table_cal[p].Lip.begin();
817 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
818 oX[curPoint] = *it_LoX;
819 oY[curPoint] = *it_LoY;
820 oZ[curPoint] = *it_LoZ;
823 u[curPoint] = ip.
get_u();
824 v[curPoint] = ip.
get_v();
834 unsigned int iter = 0;
836 double residu_1 = 1e12;
838 while (
vpMath::equal(residu_1, r, threshold) ==
false && iter < nbIterMax) {
844 for (
unsigned int p = 0; p < nbPose; p++) {
846 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
848 oX[curPoint] * cMoTmp[0][0] + oY[curPoint] * cMoTmp[0][1] + oZ[curPoint] * cMoTmp[0][2] + cMoTmp[0][3];
850 oX[curPoint] * cMoTmp[1][0] + oY[curPoint] * cMoTmp[1][1] + oZ[curPoint] * cMoTmp[1][2] + cMoTmp[1][3];
852 oX[curPoint] * cMoTmp[2][0] + oY[curPoint] * cMoTmp[2][1] + oZ[curPoint] * cMoTmp[2][2] + cMoTmp[2][3];
858 vpMatrix L(nbPointTotal * 4, nbPose6 + 6);
860 double px = cam_est.
get_px();
861 double py = cam_est.
get_py();
862 double u0 = cam_est.
get_u0();
863 double v0 = cam_est.
get_v0();
865 double inv_px = 1 / px;
866 double inv_py = 1 / py;
868 double kud = cam_est.
get_kud();
869 double kdu = cam_est.
get_kdu();
871 double k2ud = 2 * kud;
872 double k2du = 2 * kdu;
874 for (
unsigned int p = 0; p < nbPose; p++) {
875 unsigned int q = 6 * p;
876 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
877 unsigned int curPoint4 = 4 * curPoint;
878 double x = cX[curPoint];
879 double y = cY[curPoint];
880 double z = cZ[curPoint];
882 double inv_z = 1 / z;
883 double X = x * inv_z;
884 double Y = y * inv_z;
890 double up = u[curPoint];
891 double vp = v[curPoint];
894 Pd[curPoint4 + 1] = vp;
896 double up0 = up - u0;
897 double vp0 = vp - v0;
899 double xp0 = up0 * inv_px;
900 double xp02 = xp0 * xp0;
902 double yp0 = vp0 * inv_py;
903 double yp02 = yp0 * yp0;
905 double r2du = xp02 + yp02;
906 double kr2du = kdu * r2du;
908 P[curPoint4] = u0 + px * X - kr2du * (up0);
909 P[curPoint4 + 1] = v0 + py * Y - kr2du * (vp0);
911 double r2ud = X2 + Y2;
912 double kr2ud = 1 + kud * r2ud;
914 double Axx = px * (kr2ud + k2ud * X2);
915 double Axy = px * k2ud * XY;
916 double Ayy = py * (kr2ud + k2ud * Y2);
917 double Ayx = py * k2ud * XY;
919 Pd[curPoint4 + 2] = up;
920 Pd[curPoint4 + 3] = vp;
922 P[curPoint4 + 2] = u0 + px * X * kr2ud;
923 P[curPoint4 + 3] = v0 + py * Y * kr2ud;
929 unsigned int curInd = curPoint4;
933 L[curInd][q] = px * (-inv_z);
934 L[curInd][q + 1] = 0;
935 L[curInd][q + 2] = px * X * inv_z;
936 L[curInd][q + 3] = px * X * Y;
937 L[curInd][q + 4] = -px * (1 + X2);
938 L[curInd][q + 5] = px * Y;
941 L[curInd][nbPose6] = 1 + kr2du + k2du * xp02;
942 L[curInd][nbPose6 + 1] = k2du * up0 * yp0 * inv_py;
943 L[curInd][nbPose6 + 2] = X + k2du * xp02 * xp0;
944 L[curInd][nbPose6 + 3] = k2du * up0 * yp02 * inv_py;
945 L[curInd][nbPose6 + 4] = -(up0) * (r2du);
946 L[curInd][nbPose6 + 5] = 0;
951 L[curInd][q + 1] = py * (-inv_z);
952 L[curInd][q + 2] = py * Y * inv_z;
953 L[curInd][q + 3] = py * (1 + Y2);
954 L[curInd][q + 4] = -py * XY;
955 L[curInd][q + 5] = -py * X;
958 L[curInd][nbPose6] = k2du * xp0 * vp0 * inv_px;
959 L[curInd][nbPose6 + 1] = 1 + kr2du + k2du * yp02;
960 L[curInd][nbPose6 + 2] = k2du * vp0 * xp02 * inv_px;
961 L[curInd][nbPose6 + 3] = Y + k2du * yp02 * yp0;
962 L[curInd][nbPose6 + 4] = -vp0 * r2du;
963 L[curInd][nbPose6 + 5] = 0;
968 L[curInd][q] = Axx * (-inv_z);
969 L[curInd][q + 1] = Axy * (-inv_z);
970 L[curInd][q + 2] = Axx * (X * inv_z) + Axy * (Y * inv_z);
971 L[curInd][q + 3] = Axx * X * Y + Axy * (1 + Y2);
972 L[curInd][q + 4] = -Axx * (1 + X2) - Axy * XY;
973 L[curInd][q + 5] = Axx * Y - Axy * X;
976 L[curInd][nbPose6] = 1;
977 L[curInd][nbPose6 + 1] = 0;
978 L[curInd][nbPose6 + 2] = X * kr2ud;
979 L[curInd][nbPose6 + 3] = 0;
980 L[curInd][nbPose6 + 4] = 0;
981 L[curInd][nbPose6 + 5] = px * X * r2ud;
985 L[curInd][q] = Ayx * (-inv_z);
986 L[curInd][q + 1] = Ayy * (-inv_z);
987 L[curInd][q + 2] = Ayx * (X * inv_z) + Ayy * (Y * inv_z);
988 L[curInd][q + 3] = Ayx * XY + Ayy * (1 + Y2);
989 L[curInd][q + 4] = -Ayx * (1 + X2) - Ayy * XY;
990 L[curInd][q + 5] = Ayx * Y - Ayy * X;
993 L[curInd][nbPose6] = 0;
994 L[curInd][nbPose6 + 1] = 1;
995 L[curInd][nbPose6 + 2] = 0;
996 L[curInd][nbPose6 + 3] = Y * kr2ud;
997 L[curInd][nbPose6 + 4] = 0;
998 L[curInd][nbPose6 + 5] = py * Y * r2ud;
1011 L.pseudoInverse(Lp, 1e-10);
1016 for (
unsigned int i = 0; i < 6 * nbPose; i++)
1020 v0 + Tc[nbPose6 + 1], kud + Tc[nbPose6 + 5], kdu + Tc[nbPose6 + 4]);
1023 for (
unsigned int p = 0; p < nbPose; p++) {
1024 for (
unsigned int i = 0; i < 6; i++)
1025 Tc_v_Tmp[i] = Tc_v[6 * p + i];
1030 std::cout <<
" std dev: " << sqrt(r / nbPointTotal) << std::endl;
1033 if (iter == nbIterMax) {
1034 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)", nbIterMax);
1041 for (
unsigned int p = 0; p < nbPose; p++) {
1042 table_cal[p].cam_dist = cam_est;
1048 globalReprojectionError = sqrt(r / (nbPointTotal));
1051 std::cout.flags(original_flags);
1074 unsigned int nbPose = (
unsigned int)cMo.
size();
1075 if (cMo.size() != rMe.size())
1082 for (
unsigned int i = 0; i < nbPose; i++) {
1084 rMe[i].extract(rRei);
1085 cMo[i].extract(ciRo);
1088 for (
unsigned int j = 0; j < nbPose; j++) {
1092 rMe[j].extract(rRej);
1093 cMo[j].extract(cjRo);
1102 double theta = sqrt(rPeij[0] * rPeij[0] + rPeij[1] * rPeij[1] + rPeij[2] * rPeij[2]);
1104 for (
unsigned int m = 0; m < 3; m++)
1108 theta = sqrt(cijPo[0] * cijPo[0] + cijPo[1] * cijPo[1] + cijPo[2] * cijPo[2]);
1109 for (
unsigned int m = 0; m < 3; m++)
1155 for (
unsigned int i = 0; i < 3; i++)
1156 x[i] = 2 * x[i] / sqrt(1 + d);
1158 theta = 2 * asin(theta);
1160 if (std::fabs(theta) > std::numeric_limits<double>::epsilon()) {
1161 for (
unsigned int i = 0; i < 3; i++)
1162 x[i] *= theta / (2 * sin(theta / 2));
1179 for (
unsigned int i = 0; i < nbPose; i++) {
1182 rMe[i].extract(rRei);
1183 cMo[i].extract(ciRo);
1184 rMe[i].extract(rTei);
1185 cMo[i].extract(ciTo);
1187 for (
unsigned int j = 0; j < nbPose; j++) {
1192 rMe[j].extract(rRej);
1193 cMo[j].extract(cjRo);
1196 rMe[j].extract(rTej);
1197 cMo[j].extract(cjTo);
1203 rTeij = rRej.
t() * rTeij;
1208 b = eRc * cjTo - rReij * eRc * ciTo + rTeij;
1228 AeTc = Ap * A.
t() * B;
1252 std::ios::fmtflags original_flags(std::cout.flags());
1253 std::cout.precision(10);
1254 unsigned int nbPoint[256];
1255 unsigned int nbPointTotal = 0;
1257 unsigned int nbPose6 = 6 * nbPose;
1259 for (
unsigned int i = 0; i < nbPose; i++) {
1260 nbPoint[i] = table_cal[i].npt;
1261 nbPointTotal += nbPoint[i];
1264 if (nbPointTotal < 4) {
1279 unsigned int curPoint = 0;
1280 for (
unsigned int p = 0; p < nbPose; p++) {
1281 std::list<double>::const_iterator it_LoX = table_cal[p].LoX.begin();
1282 std::list<double>::const_iterator it_LoY = table_cal[p].LoY.begin();
1283 std::list<double>::const_iterator it_LoZ = table_cal[p].LoZ.begin();
1284 std::list<vpImagePoint>::const_iterator it_Lip = table_cal[p].Lip.begin();
1286 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
1287 oX[curPoint] = *it_LoX;
1288 oY[curPoint] = *it_LoY;
1289 oZ[curPoint] = *it_LoZ;
1292 u[curPoint] = ip.
get_u();
1293 v[curPoint] = ip.
get_v();
1304 unsigned int iter = 0;
1306 double residu_1 = 1e12;
1307 double r = 1e12 - 1;
1308 while (
vpMath::equal(residu_1, r, threshold) ==
false && iter < nbIterMax) {
1313 double px = cam_est.
get_px();
1314 double py = cam_est.
get_py();
1315 double u0 = cam_est.
get_u0();
1316 double v0 = cam_est.
get_v0();
1320 for (
unsigned int p = 0; p < nbPose; p++) {
1322 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
1323 unsigned int curPoint2 = 2 * curPoint;
1326 oX[curPoint] * cMoTmp[0][0] + oY[curPoint] * cMoTmp[0][1] + oZ[curPoint] * cMoTmp[0][2] + cMoTmp[0][3];
1328 oX[curPoint] * cMoTmp[1][0] + oY[curPoint] * cMoTmp[1][1] + oZ[curPoint] * cMoTmp[1][2] + cMoTmp[1][3];
1330 oX[curPoint] * cMoTmp[2][0] + oY[curPoint] * cMoTmp[2][1] + oZ[curPoint] * cMoTmp[2][2] + cMoTmp[2][3];
1332 Pd[curPoint2] = u[curPoint];
1333 Pd[curPoint2 + 1] = v[curPoint];
1335 P[curPoint2] = cX[curPoint] / cZ[curPoint] * px + u0;
1336 P[curPoint2 + 1] = cY[curPoint] / cZ[curPoint] * py + v0;
1347 vpMatrix L(nbPointTotal * 2, nbPose6 + 4);
1349 for (
unsigned int p = 0; p < nbPose; p++) {
1350 unsigned int q = 6 * p;
1351 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
1352 unsigned int curPoint2 = 2 * curPoint;
1353 unsigned int curPoint21 = curPoint2 + 1;
1355 double x = cX[curPoint];
1356 double y = cY[curPoint];
1357 double z = cZ[curPoint];
1359 double inv_z = 1 / z;
1361 double X = x * inv_z;
1362 double Y = y * inv_z;
1367 L[curPoint2][q] = px * (-inv_z);
1368 L[curPoint2][q + 1] = 0;
1369 L[curPoint2][q + 2] = px * (X * inv_z);
1370 L[curPoint2][q + 3] = px * X * Y;
1371 L[curPoint2][q + 4] = -px * (1 + X * X);
1372 L[curPoint2][q + 5] = px * Y;
1375 L[curPoint2][nbPose6] = 1;
1376 L[curPoint2][nbPose6 + 1] = 0;
1377 L[curPoint2][nbPose6 + 2] = X;
1378 L[curPoint2][nbPose6 + 3] = 0;
1381 L[curPoint21][q] = 0;
1382 L[curPoint21][q + 1] = py * (-inv_z);
1383 L[curPoint21][q + 2] = py * (Y * inv_z);
1384 L[curPoint21][q + 3] = py * (1 + Y * Y);
1385 L[curPoint21][q + 4] = -py * X * Y;
1386 L[curPoint21][q + 5] = -py * X;
1389 L[curPoint21][nbPose6] = 0;
1390 L[curPoint21][nbPose6 + 1] = 1;
1391 L[curPoint21][nbPose6 + 2] = 0;
1392 L[curPoint21][nbPose6 + 3] = Y;
1408 for (
unsigned int i = 0; i < nbPose6; i++)
1412 v0 + Tc[nbPose6 + 1]);
1417 for (
unsigned int p = 0; p < nbPose; p++) {
1418 for (
unsigned int i = 0; i < 6; i++)
1419 Tc_v_Tmp[i] = Tc_v[6 * p + i];
1424 std::cout <<
" std dev " << sqrt(r / nbPointTotal) << std::endl;
1426 if (iter == nbIterMax) {
1427 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)", nbIterMax);
1430 for (
unsigned int p = 0; p < nbPose; p++) {
1432 table_cal[p].
cam = cam_est;
1434 double deviation, deviation_dist;
1438 std::cout <<
" Global std dev " << sqrt(r / nbPointTotal) << std::endl;
1441 std::cout.flags(original_flags);
1444 void vpCalibration::calibVVSWithDistortionMulti(
unsigned int nbPose,
vpCalibration table_cal[],
1447 std::ios::fmtflags original_flags(std::cout.flags());
1448 std::cout.precision(10);
1449 unsigned int nbPoint[1024];
1450 unsigned int nbPointTotal = 0;
1452 unsigned int nbPose6 = 6 * nbPose;
1453 for (
unsigned int i = 0; i < nbPose; i++) {
1454 nbPoint[i] = table_cal[i].npt;
1455 nbPointTotal += nbPoint[i];
1458 if (nbPointTotal < 4) {
1473 unsigned int curPoint = 0;
1474 for (
unsigned int p = 0; p < nbPose; p++) {
1475 std::list<double>::const_iterator it_LoX = table_cal[p].LoX.begin();
1476 std::list<double>::const_iterator it_LoY = table_cal[p].LoY.begin();
1477 std::list<double>::const_iterator it_LoZ = table_cal[p].LoZ.begin();
1478 std::list<vpImagePoint>::const_iterator it_Lip = table_cal[p].Lip.begin();
1480 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
1481 oX[curPoint] = *it_LoX;
1482 oY[curPoint] = *it_LoY;
1483 oZ[curPoint] = *it_LoZ;
1486 u[curPoint] = ip.
get_u();
1487 v[curPoint] = ip.
get_v();
1497 unsigned int iter = 0;
1499 double residu_1 = 1e12;
1500 double r = 1e12 - 1;
1501 while (
vpMath::equal(residu_1, r, threshold) ==
false && iter < nbIterMax) {
1507 for (
unsigned int p = 0; p < nbPose; p++) {
1509 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
1511 oX[curPoint] * cMoTmp[0][0] + oY[curPoint] * cMoTmp[0][1] + oZ[curPoint] * cMoTmp[0][2] + cMoTmp[0][3];
1513 oX[curPoint] * cMoTmp[1][0] + oY[curPoint] * cMoTmp[1][1] + oZ[curPoint] * cMoTmp[1][2] + cMoTmp[1][3];
1515 oX[curPoint] * cMoTmp[2][0] + oY[curPoint] * cMoTmp[2][1] + oZ[curPoint] * cMoTmp[2][2] + cMoTmp[2][3];
1521 vpMatrix L(nbPointTotal * 4, nbPose6 + 6);
1523 double px = cam_est.
get_px();
1524 double py = cam_est.
get_py();
1525 double u0 = cam_est.
get_u0();
1526 double v0 = cam_est.
get_v0();
1528 double inv_px = 1 / px;
1529 double inv_py = 1 / py;
1531 double kud = cam_est.
get_kud();
1532 double kdu = cam_est.
get_kdu();
1534 double k2ud = 2 * kud;
1535 double k2du = 2 * kdu;
1537 for (
unsigned int p = 0; p < nbPose; p++) {
1538 unsigned int q = 6 * p;
1539 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
1540 unsigned int curPoint4 = 4 * curPoint;
1541 double x = cX[curPoint];
1542 double y = cY[curPoint];
1543 double z = cZ[curPoint];
1545 double inv_z = 1 / z;
1546 double X = x * inv_z;
1547 double Y = y * inv_z;
1553 double up = u[curPoint];
1554 double vp = v[curPoint];
1557 Pd[curPoint4 + 1] = vp;
1559 double up0 = up - u0;
1560 double vp0 = vp - v0;
1562 double xp0 = up0 * inv_px;
1563 double xp02 = xp0 * xp0;
1565 double yp0 = vp0 * inv_py;
1566 double yp02 = yp0 * yp0;
1568 double r2du = xp02 + yp02;
1569 double kr2du = kdu * r2du;
1571 P[curPoint4] = u0 + px * X - kr2du * (up0);
1572 P[curPoint4 + 1] = v0 + py * Y - kr2du * (vp0);
1574 double r2ud = X2 + Y2;
1575 double kr2ud = 1 + kud * r2ud;
1577 double Axx = px * (kr2ud + k2ud * X2);
1578 double Axy = px * k2ud * XY;
1579 double Ayy = py * (kr2ud + k2ud * Y2);
1580 double Ayx = py * k2ud * XY;
1582 Pd[curPoint4 + 2] = up;
1583 Pd[curPoint4 + 3] = vp;
1585 P[curPoint4 + 2] = u0 + px * X * kr2ud;
1586 P[curPoint4 + 3] = v0 + py * Y * kr2ud;
1592 unsigned int curInd = curPoint4;
1596 L[curInd][q] = px * (-inv_z);
1597 L[curInd][q + 1] = 0;
1598 L[curInd][q + 2] = px * X * inv_z;
1599 L[curInd][q + 3] = px * X * Y;
1600 L[curInd][q + 4] = -px * (1 + X2);
1601 L[curInd][q + 5] = px * Y;
1604 L[curInd][nbPose6] = 1 + kr2du + k2du * xp02;
1605 L[curInd][nbPose6 + 1] = k2du * up0 * yp0 * inv_py;
1606 L[curInd][nbPose6 + 2] = X + k2du * xp02 * xp0;
1607 L[curInd][nbPose6 + 3] = k2du * up0 * yp02 * inv_py;
1608 L[curInd][nbPose6 + 4] = -(up0) * (r2du);
1609 L[curInd][nbPose6 + 5] = 0;
1614 L[curInd][q + 1] = py * (-inv_z);
1615 L[curInd][q + 2] = py * Y * inv_z;
1616 L[curInd][q + 3] = py * (1 + Y2);
1617 L[curInd][q + 4] = -py * XY;
1618 L[curInd][q + 5] = -py * X;
1621 L[curInd][nbPose6] = k2du * xp0 * vp0 * inv_px;
1622 L[curInd][nbPose6 + 1] = 1 + kr2du + k2du * yp02;
1623 L[curInd][nbPose6 + 2] = k2du * vp0 * xp02 * inv_px;
1624 L[curInd][nbPose6 + 3] = Y + k2du * yp02 * yp0;
1625 L[curInd][nbPose6 + 4] = -vp0 * r2du;
1626 L[curInd][nbPose6 + 5] = 0;
1631 L[curInd][q] = Axx * (-inv_z);
1632 L[curInd][q + 1] = Axy * (-inv_z);
1633 L[curInd][q + 2] = Axx * (X * inv_z) + Axy * (Y * inv_z);
1634 L[curInd][q + 3] = Axx * X * Y + Axy * (1 + Y2);
1635 L[curInd][q + 4] = -Axx * (1 + X2) - Axy * XY;
1636 L[curInd][q + 5] = Axx * Y - Axy * X;
1639 L[curInd][nbPose6] = 1;
1640 L[curInd][nbPose6 + 1] = 0;
1641 L[curInd][nbPose6 + 2] = X * kr2ud;
1642 L[curInd][nbPose6 + 3] = 0;
1643 L[curInd][nbPose6 + 4] = 0;
1644 L[curInd][nbPose6 + 5] = px * X * r2ud;
1648 L[curInd][q] = Ayx * (-inv_z);
1649 L[curInd][q + 1] = Ayy * (-inv_z);
1650 L[curInd][q + 2] = Ayx * (X * inv_z) + Ayy * (Y * inv_z);
1651 L[curInd][q + 3] = Ayx * XY + Ayy * (1 + Y2);
1652 L[curInd][q + 4] = -Ayx * (1 + X2) - Ayy * XY;
1653 L[curInd][q + 5] = Ayx * Y - Ayy * X;
1656 L[curInd][nbPose6] = 0;
1657 L[curInd][nbPose6 + 1] = 1;
1658 L[curInd][nbPose6 + 2] = 0;
1659 L[curInd][nbPose6 + 3] = Y * kr2ud;
1660 L[curInd][nbPose6 + 4] = 0;
1661 L[curInd][nbPose6 + 5] = py * Y * r2ud;
1679 for (
unsigned int i = 0; i < 6 * nbPose; i++)
1683 v0 + Tc[nbPose6 + 1], kud + Tc[nbPose6 + 5], kdu + Tc[nbPose6 + 4]);
1686 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];
1693 std::cout <<
" std dev: " << sqrt(r / nbPointTotal) << std::endl;
1696 if (iter == nbIterMax) {
1697 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)", nbIterMax);
1701 for (
unsigned int p = 0; p < nbPose; p++) {
1706 std::cout <<
" Global std dev " << sqrt(r / (nbPointTotal)) << std::endl;
1709 std::cout.flags(original_flags);
void svd(vpColVector &w, vpMatrix &V)
Implementation of a matrix and operations on matrices.
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Error that can be emited by the vpCalibration class.
void stack(const double &d)
Implementation of an homogeneous matrix and operations on such kind of matrices.
static bool equal(double x, double y, double s=0.001)
void stack(const vpMatrix &A)
vpHomogeneousMatrix inverse() const
unsigned int size() const
Return the number of elements of the 2D array.
Tools for perspective camera calibration.
vpRotationMatrix t() const
static double sinc(double x)
vpHomogeneousMatrix cMo
(as a 3x4 matrix [R T])
Implementation of a rotation matrix and operations on such kind of matrices.
void initPersProjWithoutDistortion(const double px, const double py, const double u0, const double v0)
void insert(const vpRotationMatrix &R)
something is not initialized
static double sqr(double x)
vpHomogeneousMatrix cMo_dist
Generic class defining intrinsic camera parameters.
vpHomogeneousMatrix rMe
reference coordinates (manipulator base coordinates)
double computeStdDeviation_dist(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam)
vpCameraParameters cam_dist
projection model with distortion
Implementation of column vector and the associated operations.
static void calibrationTsai(const std::vector< vpHomogeneousMatrix > &cMo, const std::vector< vpHomogeneousMatrix > &rMe, vpHomogeneousMatrix &eMc)
calibration method of effector-camera from R. Tsai and R. Lorenz .
iterative algorithm doesn't converge
static vpHomogeneousMatrix direct(const vpColVector &v)
vpHomogeneousMatrix eMc
position of the camera in relation to the effector
static vpMatrix skew(const vpColVector &v)
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.
Implementation of a rotation vector as axis-angle minimal representation.
void initPersProjWithDistortion(const double px, const double py, const double u0, const double v0, const double kud, const double kdu)