40 #include <visp3/core/vpMath.h> 41 #include <visp3/core/vpPixelMeterConversion.h> 42 #include <visp3/vision/vpCalibration.h> 43 #include <visp3/vision/vpPose.h> 48 #define DEBUG_LEVEL1 0 49 #define DEBUG_LEVEL2 0 60 std::list<double>::const_iterator it_LoX = LoX.begin();
61 std::list<double>::const_iterator it_LoY = LoY.begin();
62 std::list<double>::const_iterator it_LoZ = LoZ.begin();
63 std::list<vpImagePoint>::const_iterator it_Lip = Lip.begin();
67 for (
unsigned int i = 0; i < npt; i++) {
75 double xi = ip.
get_u();
76 double yi = ip.
get_v();
78 A[2 * i][0] = x0 * xi;
79 A[2 * i][1] = y0 * xi;
80 A[2 * i][2] = z0 * xi;
90 A[2 * i + 1][0] = x0 * yi;
91 A[2 * i + 1][1] = y0 * yi;
92 A[2 * i + 1][2] = z0 * yi;
93 B[2 * i + 1][0] = 0.0;
94 B[2 * i + 1][1] = 0.0;
95 B[2 * i + 1][2] = 0.0;
96 B[2 * i + 1][3] = -x0;
97 B[2 * i + 1][4] = -y0;
98 B[2 * i + 1][5] = -z0;
99 B[2 * i + 1][6] = 0.0;
100 B[2 * i + 1][7] = -1.0;
101 B[2 * i + 1][8] = yi;
126 e = -(A.t() * B) * r;
140 unsigned int imin = 1;
141 for (
unsigned int i = 0; i < x1.getRows(); i++) {
150 for (
unsigned int i = 0; i < x1.getRows(); i++) {
151 if (x1[i] < x1[imin])
155 for (
unsigned int i = 0; i < x1.getRows(); i++)
156 x1[i] = AtA[i][imin];
162 for (
unsigned int i = 0; i < 3; i++)
164 for (
unsigned int i = 0; i < 9; i++)
170 for (
unsigned int i = 0; i < 12; i++)
173 resul[0] = sol[3] * sol[0] + sol[4] * sol[1] + sol[5] * sol[2];
175 resul[1] = sol[6] * sol[0] + sol[7] * sol[1] + sol[8] * sol[2];
177 resul[2] = sqrt(sol[3] * sol[3] + sol[4] * sol[4] + sol[5] * sol[5]
178 - resul[0] * resul[0]);
179 resul[3] = sqrt(sol[6] * sol[6] + sol[7] * sol[7] + sol[8] * sol[8]
180 - resul[1] * resul[1]);
184 resul[4] = (sol[9] - sol[11] * resul[0]) / resul[2];
185 resul[5] = (sol[10] - sol[11] * resul[1]) / resul[3];
190 for (
unsigned int i = 0; i < 3; i++)
191 rd[0][i] = (sol[i + 3] - sol[i] * resul[0]) / resul[2];
192 for (
unsigned int i = 0; i < 3; i++)
193 rd[1][i] = (sol[i + 6] - sol[i] * resul[1]) / resul[3];
194 for (
unsigned int i = 0; i < 3; i++)
200 for (
unsigned int i = 0; i < 3; i++) {
201 for (
unsigned int j = 0; j < 3; j++)
202 cMo_est[i][j] = rd[i][j];
204 for (
unsigned int i = 0; i < 3; i++)
205 cMo_est[i][3] = resul[i + 4];
210 double deviation, deviation_dist;
216 std::ios::fmtflags original_flags(std::cout.flags());
217 std::cout.precision(10);
218 unsigned int n_points = npt;
231 std::list<double>::const_iterator it_LoX = LoX.begin();
232 std::list<double>::const_iterator it_LoY = LoY.begin();
233 std::list<double>::const_iterator it_LoZ = LoZ.begin();
234 std::list<vpImagePoint>::const_iterator it_Lip = Lip.begin();
236 for (
unsigned int i = 0; i < n_points; i++) {
253 unsigned int iter = 0;
255 double residu_1 = 1e12;
257 while (
vpMath::equal(residu_1, r, threshold) ==
false && iter < nbIterMax) {
261 double px = cam_est.
get_px();
262 double py = cam_est.
get_py();
263 double u0 = cam_est.
get_u0();
264 double v0 = cam_est.
get_v0();
268 for (
unsigned int i = 0; i < n_points; i++) {
269 cX[i] = oX[i] * cMo_est[0][0] + oY[i] * cMo_est[0][1] + oZ[i] * cMo_est[0][2] + cMo_est[0][3];
270 cY[i] = oX[i] * cMo_est[1][0] + oY[i] * cMo_est[1][1] + oZ[i] * cMo_est[1][2] + cMo_est[1][3];
271 cZ[i] = oX[i] * cMo_est[2][0] + oY[i] * cMo_est[2][1] + oZ[i] * cMo_est[2][2] + cMo_est[2][3];
274 Pd[2 * i + 1] = v[i];
276 P[2 * i] = cX[i] / cZ[i] * px + u0;
277 P[2 * i + 1] = cY[i] / cZ[i] * py + v0;
287 for (
unsigned int i = 0; i < n_points; i++) {
291 double inv_z = 1 / z;
293 double X = x * inv_z;
294 double Y = y * inv_z;
298 L[2 * i][0] = px * (-inv_z);
300 L[2 * i][2] = px * X * inv_z;
301 L[2 * i][3] = px * X * Y;
302 L[2 * i][4] = -px * (1 + X * X);
303 L[2 * i][5] = px * Y;
313 L[2 * i + 1][1] = py * (-inv_z);
314 L[2 * i + 1][2] = py * (Y * inv_z);
315 L[2 * i + 1][3] = py * (1 + Y * Y);
316 L[2 * i + 1][4] = -py * X * Y;
317 L[2 * i + 1][5] = -py * X;
327 Lp = L.pseudoInverse(1e-10);
336 for (
unsigned int i = 0; i < 6; i++)
343 std::cout <<
" std dev " << sqrt(r / n_points) << std::endl;
345 if (iter == nbIterMax) {
346 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)", nbIterMax);
352 this->residual_dist = r;
354 std::cout <<
" std dev " << sqrt(r / n_points) << std::endl;
356 std::cout.flags(original_flags);
359 void vpCalibration::calibVVSMulti(std::vector<vpCalibration> &table_cal,
vpCameraParameters &cam_est,
360 double &globalReprojectionError,
bool verbose)
362 std::ios::fmtflags original_flags(std::cout.flags());
363 std::cout.precision(10);
364 unsigned int nbPoint[256];
365 unsigned int nbPointTotal = 0;
366 unsigned int nbPose = (
unsigned int)table_cal.size();
367 unsigned int nbPose6 = 6 * nbPose;
369 for (
unsigned int i = 0; i < nbPose; i++) {
370 nbPoint[i] = table_cal[i].npt;
371 nbPointTotal += nbPoint[i];
374 if (nbPointTotal < 4) {
389 unsigned int curPoint = 0;
390 for (
unsigned int p = 0; p < nbPose; p++) {
391 std::list<double>::const_iterator it_LoX = table_cal[p].LoX.begin();
392 std::list<double>::const_iterator it_LoY = table_cal[p].LoY.begin();
393 std::list<double>::const_iterator it_LoZ = table_cal[p].LoZ.begin();
394 std::list<vpImagePoint>::const_iterator it_Lip = table_cal[p].Lip.begin();
396 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
397 oX[curPoint] = *it_LoX;
398 oY[curPoint] = *it_LoY;
399 oZ[curPoint] = *it_LoZ;
402 u[curPoint] = ip.
get_u();
403 v[curPoint] = ip.
get_v();
414 unsigned int iter = 0;
416 double residu_1 = 1e12;
418 while (
vpMath::equal(residu_1, r, threshold) ==
false && iter < nbIterMax) {
423 double px = cam_est.
get_px();
424 double py = cam_est.
get_py();
425 double u0 = cam_est.
get_u0();
426 double v0 = cam_est.
get_v0();
430 for (
unsigned int p = 0; p < nbPose; p++) {
432 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
433 unsigned int curPoint2 = 2 * curPoint;
436 oX[curPoint] * cMoTmp[0][0] + oY[curPoint] * cMoTmp[0][1] + oZ[curPoint] * cMoTmp[0][2] + cMoTmp[0][3];
438 oX[curPoint] * cMoTmp[1][0] + oY[curPoint] * cMoTmp[1][1] + oZ[curPoint] * cMoTmp[1][2] + cMoTmp[1][3];
440 oX[curPoint] * cMoTmp[2][0] + oY[curPoint] * cMoTmp[2][1] + oZ[curPoint] * cMoTmp[2][2] + cMoTmp[2][3];
442 Pd[curPoint2] = u[curPoint];
443 Pd[curPoint2 + 1] = v[curPoint];
445 P[curPoint2] = cX[curPoint] / cZ[curPoint] * px + u0;
446 P[curPoint2 + 1] = cY[curPoint] / cZ[curPoint] * py + v0;
457 vpMatrix L(nbPointTotal * 2, nbPose6 + 4);
459 for (
unsigned int p = 0; p < nbPose; p++) {
460 unsigned int q = 6 * p;
461 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
462 unsigned int curPoint2 = 2 * curPoint;
463 unsigned int curPoint21 = curPoint2 + 1;
465 double x = cX[curPoint];
466 double y = cY[curPoint];
467 double z = cZ[curPoint];
469 double inv_z = 1 / z;
471 double X = x * inv_z;
472 double Y = y * inv_z;
477 L[curPoint2][q] = px * (-inv_z);
478 L[curPoint2][q + 1] = 0;
479 L[curPoint2][q + 2] = px * (X * inv_z);
480 L[curPoint2][q + 3] = px * X * Y;
481 L[curPoint2][q + 4] = -px * (1 + X * X);
482 L[curPoint2][q + 5] = px * Y;
485 L[curPoint2][nbPose6] = 1;
486 L[curPoint2][nbPose6 + 1] = 0;
487 L[curPoint2][nbPose6 + 2] = X;
488 L[curPoint2][nbPose6 + 3] = 0;
491 L[curPoint21][q] = 0;
492 L[curPoint21][q + 1] = py * (-inv_z);
493 L[curPoint21][q + 2] = py * (Y * inv_z);
494 L[curPoint21][q + 3] = py * (1 + Y * Y);
495 L[curPoint21][q + 4] = -py * X * Y;
496 L[curPoint21][q + 5] = -py * X;
499 L[curPoint21][nbPose6] = 0;
500 L[curPoint21][nbPose6 + 1] = 1;
501 L[curPoint21][nbPose6 + 2] = 0;
502 L[curPoint21][nbPose6 + 3] = Y;
509 Lp = L.pseudoInverse(1e-10);
518 for (
unsigned int i = 0; i < nbPose6; i++)
522 v0 + Tc[nbPose6 + 1]);
527 for (
unsigned int p = 0; p < nbPose; p++) {
528 for (
unsigned int i = 0; i < 6; i++)
529 Tc_v_Tmp[i] = Tc_v[6 * p + i];
535 std::cout <<
" std dev " << sqrt(r / nbPointTotal) << std::endl;
537 if (iter == nbIterMax) {
538 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)", nbIterMax);
541 for (
unsigned int p = 0; p < nbPose; p++) {
542 table_cal[p].cMo_dist = table_cal[p].cMo;
543 table_cal[p].cam = cam_est;
544 table_cal[p].cam_dist = cam_est;
545 double deviation, deviation_dist;
546 table_cal[p].computeStdDeviation(deviation, deviation_dist);
548 globalReprojectionError = sqrt(r / nbPointTotal);
550 std::cout.flags(original_flags);
555 std::ios::fmtflags original_flags(std::cout.flags());
556 std::cout.precision(10);
557 unsigned int n_points = npt;
568 std::list<double>::const_iterator it_LoX = LoX.begin();
569 std::list<double>::const_iterator it_LoY = LoY.begin();
570 std::list<double>::const_iterator it_LoZ = LoZ.begin();
571 std::list<vpImagePoint>::const_iterator it_Lip = Lip.begin();
575 for (
unsigned int i = 0; i < n_points; i++) {
591 unsigned int iter = 0;
593 double residu_1 = 1e12;
595 while (
vpMath::equal(residu_1, r, threshold) ==
false && iter < nbIterMax) {
600 double u0 = cam_est.
get_u0();
601 double v0 = cam_est.
get_v0();
603 double px = cam_est.
get_px();
604 double py = cam_est.
get_py();
606 double inv_px = 1 / px;
607 double inv_py = 1 / py;
609 double kud = cam_est.
get_kud();
610 double kdu = cam_est.
get_kdu();
612 double k2ud = 2 * kud;
613 double k2du = 2 * kdu;
616 for (
unsigned int i = 0; i < n_points; i++) {
617 unsigned int i4 = 4 * i;
618 unsigned int i41 = 4 * i + 1;
619 unsigned int i42 = 4 * i + 2;
620 unsigned int i43 = 4 * i + 3;
622 cX[i] = oX[i] * cMo_est[0][0] + oY[i] * cMo_est[0][1] + oZ[i] * cMo_est[0][2] + cMo_est[0][3];
623 cY[i] = oX[i] * cMo_est[1][0] + oY[i] * cMo_est[1][1] + oZ[i] * cMo_est[1][2] + cMo_est[1][3];
624 cZ[i] = oX[i] * cMo_est[2][0] + oY[i] * cMo_est[2][1] + oZ[i] * cMo_est[2][2] + cMo_est[2][3];
629 double inv_z = 1 / z;
631 double X = x * inv_z;
632 double Y = y * inv_z;
644 double up0 = up - u0;
645 double vp0 = vp - v0;
647 double xp0 = up0 * inv_px;
648 double xp02 = xp0 * xp0;
650 double yp0 = vp0 * inv_py;
651 double yp02 = yp0 * yp0;
653 double r2du = xp02 + yp02;
654 double kr2du = kdu * r2du;
656 P[i4] = u0 + px * X - kr2du * (up0);
657 P[i41] = v0 + py * Y - kr2du * (vp0);
659 double r2ud = X2 + Y2;
660 double kr2ud = 1 + kud * r2ud;
662 double Axx = px * (kr2ud + k2ud * X2);
663 double Axy = px * k2ud * XY;
664 double Ayy = py * (kr2ud + k2ud * Y2);
665 double Ayx = py * k2ud * XY;
670 P[i42] = u0 + px * X * kr2ud;
671 P[i43] = v0 + py * Y * kr2ud;
680 L[i4][0] = px * (-inv_z);
682 L[i4][2] = px * X * inv_z;
683 L[i4][3] = px * X * Y;
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);
700 L[i41][4] = -py * XY;
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;
723 L[i42][8] = X * kr2ud;
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;
740 L[i43][9] = Y * kr2ud;
742 L[i43][11] = py * Y * r2ud;
752 Lp = L.pseudoInverse(1e-10);
760 for (
unsigned int i = 0; i < 6; i++)
767 std::cout <<
" std dev " << sqrt(r / n_points) << std::endl;
769 if (iter == nbIterMax) {
770 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)", nbIterMax);
773 this->residual_dist = r;
778 std::cout <<
" std dev " << sqrt(r / n_points) << std::endl;
781 std::cout.flags(original_flags);
784 void vpCalibration::calibVVSWithDistortionMulti(std::vector<vpCalibration> &table_cal,
vpCameraParameters &cam_est,
785 double &globalReprojectionError,
bool verbose)
787 std::ios::fmtflags original_flags(std::cout.flags());
788 std::cout.precision(10);
789 unsigned int nbPoint[1024];
790 unsigned int nbPointTotal = 0;
791 unsigned int nbPose = (
unsigned int)table_cal.size();
792 unsigned int nbPose6 = 6 * nbPose;
793 for (
unsigned int i = 0; i < nbPose; i++) {
794 nbPoint[i] = table_cal[i].npt;
795 nbPointTotal += nbPoint[i];
798 if (nbPointTotal < 4) {
813 unsigned int curPoint = 0;
814 for (
unsigned int p = 0; p < nbPose; p++) {
815 std::list<double>::const_iterator it_LoX = table_cal[p].LoX.begin();
816 std::list<double>::const_iterator it_LoY = table_cal[p].LoY.begin();
817 std::list<double>::const_iterator it_LoZ = table_cal[p].LoZ.begin();
818 std::list<vpImagePoint>::const_iterator it_Lip = table_cal[p].Lip.begin();
820 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
821 oX[curPoint] = *it_LoX;
822 oY[curPoint] = *it_LoY;
823 oZ[curPoint] = *it_LoZ;
826 u[curPoint] = ip.
get_u();
827 v[curPoint] = ip.
get_v();
837 unsigned int iter = 0;
839 double residu_1 = 1e12;
841 while (
vpMath::equal(residu_1, r, threshold) ==
false && iter < nbIterMax) {
847 for (
unsigned int p = 0; p < nbPose; p++) {
849 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
851 oX[curPoint] * cMoTmp[0][0] + oY[curPoint] * cMoTmp[0][1] + oZ[curPoint] * cMoTmp[0][2] + cMoTmp[0][3];
853 oX[curPoint] * cMoTmp[1][0] + oY[curPoint] * cMoTmp[1][1] + oZ[curPoint] * cMoTmp[1][2] + cMoTmp[1][3];
855 oX[curPoint] * cMoTmp[2][0] + oY[curPoint] * cMoTmp[2][1] + oZ[curPoint] * cMoTmp[2][2] + cMoTmp[2][3];
861 vpMatrix L(nbPointTotal * 4, nbPose6 + 6);
863 double px = cam_est.
get_px();
864 double py = cam_est.
get_py();
865 double u0 = cam_est.
get_u0();
866 double v0 = cam_est.
get_v0();
868 double inv_px = 1 / px;
869 double inv_py = 1 / py;
871 double kud = cam_est.
get_kud();
872 double kdu = cam_est.
get_kdu();
874 double k2ud = 2 * kud;
875 double k2du = 2 * kdu;
877 for (
unsigned int p = 0; p < nbPose; p++) {
878 unsigned int q = 6 * p;
879 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
880 unsigned int curPoint4 = 4 * curPoint;
881 double x = cX[curPoint];
882 double y = cY[curPoint];
883 double z = cZ[curPoint];
885 double inv_z = 1 / z;
886 double X = x * inv_z;
887 double Y = y * inv_z;
893 double up = u[curPoint];
894 double vp = v[curPoint];
897 Pd[curPoint4 + 1] = vp;
899 double up0 = up - u0;
900 double vp0 = vp - v0;
902 double xp0 = up0 * inv_px;
903 double xp02 = xp0 * xp0;
905 double yp0 = vp0 * inv_py;
906 double yp02 = yp0 * yp0;
908 double r2du = xp02 + yp02;
909 double kr2du = kdu * r2du;
911 P[curPoint4] = u0 + px * X - kr2du * (up0);
912 P[curPoint4 + 1] = v0 + py * Y - kr2du * (vp0);
914 double r2ud = X2 + Y2;
915 double kr2ud = 1 + kud * r2ud;
917 double Axx = px * (kr2ud + k2ud * X2);
918 double Axy = px * k2ud * XY;
919 double Ayy = py * (kr2ud + k2ud * Y2);
920 double Ayx = py * k2ud * XY;
922 Pd[curPoint4 + 2] = up;
923 Pd[curPoint4 + 3] = vp;
925 P[curPoint4 + 2] = u0 + px * X * kr2ud;
926 P[curPoint4 + 3] = v0 + py * Y * kr2ud;
932 unsigned int curInd = curPoint4;
936 L[curInd][q] = px * (-inv_z);
937 L[curInd][q + 1] = 0;
938 L[curInd][q + 2] = px * X * inv_z;
939 L[curInd][q + 3] = px * X * Y;
940 L[curInd][q + 4] = -px * (1 + X2);
941 L[curInd][q + 5] = px * Y;
944 L[curInd][nbPose6] = 1 + kr2du + k2du * xp02;
945 L[curInd][nbPose6 + 1] = k2du * up0 * yp0 * inv_py;
946 L[curInd][nbPose6 + 2] = X + k2du * xp02 * xp0;
947 L[curInd][nbPose6 + 3] = k2du * up0 * yp02 * inv_py;
948 L[curInd][nbPose6 + 4] = -(up0) * (r2du);
949 L[curInd][nbPose6 + 5] = 0;
954 L[curInd][q + 1] = py * (-inv_z);
955 L[curInd][q + 2] = py * Y * inv_z;
956 L[curInd][q + 3] = py * (1 + Y2);
957 L[curInd][q + 4] = -py * XY;
958 L[curInd][q + 5] = -py * X;
961 L[curInd][nbPose6] = k2du * xp0 * vp0 * inv_px;
962 L[curInd][nbPose6 + 1] = 1 + kr2du + k2du * yp02;
963 L[curInd][nbPose6 + 2] = k2du * vp0 * xp02 * inv_px;
964 L[curInd][nbPose6 + 3] = Y + k2du * yp02 * yp0;
965 L[curInd][nbPose6 + 4] = -vp0 * r2du;
966 L[curInd][nbPose6 + 5] = 0;
971 L[curInd][q] = Axx * (-inv_z);
972 L[curInd][q + 1] = Axy * (-inv_z);
973 L[curInd][q + 2] = Axx * (X * inv_z) + Axy * (Y * inv_z);
974 L[curInd][q + 3] = Axx * X * Y + Axy * (1 + Y2);
975 L[curInd][q + 4] = -Axx * (1 + X2) - Axy * XY;
976 L[curInd][q + 5] = Axx * Y - Axy * X;
979 L[curInd][nbPose6] = 1;
980 L[curInd][nbPose6 + 1] = 0;
981 L[curInd][nbPose6 + 2] = X * kr2ud;
982 L[curInd][nbPose6 + 3] = 0;
983 L[curInd][nbPose6 + 4] = 0;
984 L[curInd][nbPose6 + 5] = px * X * r2ud;
988 L[curInd][q] = Ayx * (-inv_z);
989 L[curInd][q + 1] = Ayy * (-inv_z);
990 L[curInd][q + 2] = Ayx * (X * inv_z) + Ayy * (Y * inv_z);
991 L[curInd][q + 3] = Ayx * XY + Ayy * (1 + Y2);
992 L[curInd][q + 4] = -Ayx * (1 + X2) - Ayy * XY;
993 L[curInd][q + 5] = Ayx * Y - Ayy * X;
996 L[curInd][nbPose6] = 0;
997 L[curInd][nbPose6 + 1] = 1;
998 L[curInd][nbPose6 + 2] = 0;
999 L[curInd][nbPose6 + 3] = Y * kr2ud;
1000 L[curInd][nbPose6 + 4] = 0;
1001 L[curInd][nbPose6 + 5] = py * Y * r2ud;
1014 L.pseudoInverse(Lp, 1e-10);
1019 for (
unsigned int i = 0; i < 6 * nbPose; i++)
1023 v0 + Tc[nbPose6 + 1], kud + Tc[nbPose6 + 5], kdu + Tc[nbPose6 + 4]);
1026 for (
unsigned int p = 0; p < nbPose; p++) {
1027 for (
unsigned int i = 0; i < 6; i++)
1028 Tc_v_Tmp[i] = Tc_v[6 * p + i];
1033 std::cout <<
" std dev: " << sqrt(r / nbPointTotal) << std::endl;
1036 if (iter == nbIterMax) {
1037 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)", nbIterMax);
1044 for (
unsigned int p = 0; p < nbPose; p++) {
1045 table_cal[p].cam_dist = cam_est;
1047 table_cal[p].computeStdDeviation_dist(table_cal[p].
cMo_dist, cam_est);
1051 globalReprojectionError = sqrt(r / (nbPointTotal));
1054 std::cout.flags(original_flags);
1060 std::ios::fmtflags original_flags(std::cout.flags());
1061 std::cout.precision(10);
1062 unsigned int nbPoint[256];
1063 unsigned int nbPointTotal = 0;
1065 unsigned int nbPose6 = 6 * nbPose;
1067 for (
unsigned int i = 0; i < nbPose; i++) {
1068 nbPoint[i] = table_cal[i].npt;
1069 nbPointTotal += nbPoint[i];
1072 if (nbPointTotal < 4) {
1087 unsigned int curPoint = 0;
1088 for (
unsigned int p = 0; p < nbPose; p++) {
1089 std::list<double>::const_iterator it_LoX = table_cal[p].LoX.begin();
1090 std::list<double>::const_iterator it_LoY = table_cal[p].LoY.begin();
1091 std::list<double>::const_iterator it_LoZ = table_cal[p].LoZ.begin();
1092 std::list<vpImagePoint>::const_iterator it_Lip = table_cal[p].Lip.begin();
1094 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
1095 oX[curPoint] = *it_LoX;
1096 oY[curPoint] = *it_LoY;
1097 oZ[curPoint] = *it_LoZ;
1100 u[curPoint] = ip.
get_u();
1101 v[curPoint] = ip.
get_v();
1112 unsigned int iter = 0;
1114 double residu_1 = 1e12;
1115 double r = 1e12 - 1;
1116 while (
vpMath::equal(residu_1, r, threshold) ==
false && iter < nbIterMax) {
1121 double px = cam_est.
get_px();
1122 double py = cam_est.
get_py();
1123 double u0 = cam_est.
get_u0();
1124 double v0 = cam_est.
get_v0();
1128 for (
unsigned int p = 0; p < nbPose; p++) {
1130 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
1131 unsigned int curPoint2 = 2 * curPoint;
1134 oX[curPoint] * cMoTmp[0][0] + oY[curPoint] * cMoTmp[0][1] + oZ[curPoint] * cMoTmp[0][2] + cMoTmp[0][3];
1136 oX[curPoint] * cMoTmp[1][0] + oY[curPoint] * cMoTmp[1][1] + oZ[curPoint] * cMoTmp[1][2] + cMoTmp[1][3];
1138 oX[curPoint] * cMoTmp[2][0] + oY[curPoint] * cMoTmp[2][1] + oZ[curPoint] * cMoTmp[2][2] + cMoTmp[2][3];
1140 Pd[curPoint2] = u[curPoint];
1141 Pd[curPoint2 + 1] = v[curPoint];
1143 P[curPoint2] = cX[curPoint] / cZ[curPoint] * px + u0;
1144 P[curPoint2 + 1] = cY[curPoint] / cZ[curPoint] * py + v0;
1155 vpMatrix L(nbPointTotal * 2, nbPose6 + 4);
1157 for (
unsigned int p = 0; p < nbPose; p++) {
1158 unsigned int q = 6 * p;
1159 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
1160 unsigned int curPoint2 = 2 * curPoint;
1161 unsigned int curPoint21 = curPoint2 + 1;
1163 double x = cX[curPoint];
1164 double y = cY[curPoint];
1165 double z = cZ[curPoint];
1167 double inv_z = 1 / z;
1169 double X = x * inv_z;
1170 double Y = y * inv_z;
1175 L[curPoint2][q] = px * (-inv_z);
1176 L[curPoint2][q + 1] = 0;
1177 L[curPoint2][q + 2] = px * (X * inv_z);
1178 L[curPoint2][q + 3] = px * X * Y;
1179 L[curPoint2][q + 4] = -px * (1 + X * X);
1180 L[curPoint2][q + 5] = px * Y;
1183 L[curPoint2][nbPose6] = 1;
1184 L[curPoint2][nbPose6 + 1] = 0;
1185 L[curPoint2][nbPose6 + 2] = X;
1186 L[curPoint2][nbPose6 + 3] = 0;
1189 L[curPoint21][q] = 0;
1190 L[curPoint21][q + 1] = py * (-inv_z);
1191 L[curPoint21][q + 2] = py * (Y * inv_z);
1192 L[curPoint21][q + 3] = py * (1 + Y * Y);
1193 L[curPoint21][q + 4] = -py * X * Y;
1194 L[curPoint21][q + 5] = -py * X;
1197 L[curPoint21][nbPose6] = 0;
1198 L[curPoint21][nbPose6 + 1] = 1;
1199 L[curPoint21][nbPose6 + 2] = 0;
1200 L[curPoint21][nbPose6 + 3] = Y;
1207 Lp = L.pseudoInverse(1e-10);
1216 for (
unsigned int i = 0; i < nbPose6; i++)
1220 v0 + Tc[nbPose6 + 1]);
1225 for (
unsigned int p = 0; p < nbPose; p++) {
1226 for (
unsigned int i = 0; i < 6; i++)
1227 Tc_v_Tmp[i] = Tc_v[6 * p + i];
1232 std::cout <<
" std dev " << sqrt(r / nbPointTotal) << std::endl;
1234 if (iter == nbIterMax) {
1235 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)", nbIterMax);
1238 for (
unsigned int p = 0; p < nbPose; p++) {
1240 table_cal[p].
cam = cam_est;
1242 double deviation, deviation_dist;
1246 std::cout <<
" Global std dev " << sqrt(r / nbPointTotal) << std::endl;
1249 std::cout.flags(original_flags);
1252 void vpCalibration::calibVVSWithDistortionMulti(
unsigned int nbPose,
vpCalibration table_cal[],
1255 std::ios::fmtflags original_flags(std::cout.flags());
1256 std::cout.precision(10);
1257 unsigned int nbPoint[1024];
1258 unsigned int nbPointTotal = 0;
1260 unsigned int nbPose6 = 6 * nbPose;
1261 for (
unsigned int i = 0; i < nbPose; i++) {
1262 nbPoint[i] = table_cal[i].npt;
1263 nbPointTotal += nbPoint[i];
1266 if (nbPointTotal < 4) {
1281 unsigned int curPoint = 0;
1282 for (
unsigned int p = 0; p < nbPose; p++) {
1283 std::list<double>::const_iterator it_LoX = table_cal[p].LoX.begin();
1284 std::list<double>::const_iterator it_LoY = table_cal[p].LoY.begin();
1285 std::list<double>::const_iterator it_LoZ = table_cal[p].LoZ.begin();
1286 std::list<vpImagePoint>::const_iterator it_Lip = table_cal[p].Lip.begin();
1288 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
1289 oX[curPoint] = *it_LoX;
1290 oY[curPoint] = *it_LoY;
1291 oZ[curPoint] = *it_LoZ;
1294 u[curPoint] = ip.
get_u();
1295 v[curPoint] = ip.
get_v();
1305 unsigned int iter = 0;
1307 double residu_1 = 1e12;
1308 double r = 1e12 - 1;
1309 while (
vpMath::equal(residu_1, r, threshold) ==
false && iter < nbIterMax) {
1315 for (
unsigned int p = 0; p < nbPose; p++) {
1317 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
1319 oX[curPoint] * cMoTmp[0][0] + oY[curPoint] * cMoTmp[0][1] + oZ[curPoint] * cMoTmp[0][2] + cMoTmp[0][3];
1321 oX[curPoint] * cMoTmp[1][0] + oY[curPoint] * cMoTmp[1][1] + oZ[curPoint] * cMoTmp[1][2] + cMoTmp[1][3];
1323 oX[curPoint] * cMoTmp[2][0] + oY[curPoint] * cMoTmp[2][1] + oZ[curPoint] * cMoTmp[2][2] + cMoTmp[2][3];
1329 vpMatrix L(nbPointTotal * 4, nbPose6 + 6);
1331 double px = cam_est.
get_px();
1332 double py = cam_est.
get_py();
1333 double u0 = cam_est.
get_u0();
1334 double v0 = cam_est.
get_v0();
1336 double inv_px = 1 / px;
1337 double inv_py = 1 / py;
1339 double kud = cam_est.
get_kud();
1340 double kdu = cam_est.
get_kdu();
1342 double k2ud = 2 * kud;
1343 double k2du = 2 * kdu;
1345 for (
unsigned int p = 0; p < nbPose; p++) {
1346 unsigned int q = 6 * p;
1347 for (
unsigned int i = 0; i < nbPoint[p]; i++) {
1348 unsigned int curPoint4 = 4 * curPoint;
1349 double x = cX[curPoint];
1350 double y = cY[curPoint];
1351 double z = cZ[curPoint];
1353 double inv_z = 1 / z;
1354 double X = x * inv_z;
1355 double Y = y * inv_z;
1361 double up = u[curPoint];
1362 double vp = v[curPoint];
1365 Pd[curPoint4 + 1] = vp;
1367 double up0 = up - u0;
1368 double vp0 = vp - v0;
1370 double xp0 = up0 * inv_px;
1371 double xp02 = xp0 * xp0;
1373 double yp0 = vp0 * inv_py;
1374 double yp02 = yp0 * yp0;
1376 double r2du = xp02 + yp02;
1377 double kr2du = kdu * r2du;
1379 P[curPoint4] = u0 + px * X - kr2du * (up0);
1380 P[curPoint4 + 1] = v0 + py * Y - kr2du * (vp0);
1382 double r2ud = X2 + Y2;
1383 double kr2ud = 1 + kud * r2ud;
1385 double Axx = px * (kr2ud + k2ud * X2);
1386 double Axy = px * k2ud * XY;
1387 double Ayy = py * (kr2ud + k2ud * Y2);
1388 double Ayx = py * k2ud * XY;
1390 Pd[curPoint4 + 2] = up;
1391 Pd[curPoint4 + 3] = vp;
1393 P[curPoint4 + 2] = u0 + px * X * kr2ud;
1394 P[curPoint4 + 3] = v0 + py * Y * kr2ud;
1400 unsigned int curInd = curPoint4;
1404 L[curInd][q] = px * (-inv_z);
1405 L[curInd][q + 1] = 0;
1406 L[curInd][q + 2] = px * X * inv_z;
1407 L[curInd][q + 3] = px * X * Y;
1408 L[curInd][q + 4] = -px * (1 + X2);
1409 L[curInd][q + 5] = px * Y;
1412 L[curInd][nbPose6] = 1 + kr2du + k2du * xp02;
1413 L[curInd][nbPose6 + 1] = k2du * up0 * yp0 * inv_py;
1414 L[curInd][nbPose6 + 2] = X + k2du * xp02 * xp0;
1415 L[curInd][nbPose6 + 3] = k2du * up0 * yp02 * inv_py;
1416 L[curInd][nbPose6 + 4] = -(up0) * (r2du);
1417 L[curInd][nbPose6 + 5] = 0;
1422 L[curInd][q + 1] = py * (-inv_z);
1423 L[curInd][q + 2] = py * Y * inv_z;
1424 L[curInd][q + 3] = py * (1 + Y2);
1425 L[curInd][q + 4] = -py * XY;
1426 L[curInd][q + 5] = -py * X;
1429 L[curInd][nbPose6] = k2du * xp0 * vp0 * inv_px;
1430 L[curInd][nbPose6 + 1] = 1 + kr2du + k2du * yp02;
1431 L[curInd][nbPose6 + 2] = k2du * vp0 * xp02 * inv_px;
1432 L[curInd][nbPose6 + 3] = Y + k2du * yp02 * yp0;
1433 L[curInd][nbPose6 + 4] = -vp0 * r2du;
1434 L[curInd][nbPose6 + 5] = 0;
1439 L[curInd][q] = Axx * (-inv_z);
1440 L[curInd][q + 1] = Axy * (-inv_z);
1441 L[curInd][q + 2] = Axx * (X * inv_z) + Axy * (Y * inv_z);
1442 L[curInd][q + 3] = Axx * X * Y + Axy * (1 + Y2);
1443 L[curInd][q + 4] = -Axx * (1 + X2) - Axy * XY;
1444 L[curInd][q + 5] = Axx * Y - Axy * X;
1447 L[curInd][nbPose6] = 1;
1448 L[curInd][nbPose6 + 1] = 0;
1449 L[curInd][nbPose6 + 2] = X * kr2ud;
1450 L[curInd][nbPose6 + 3] = 0;
1451 L[curInd][nbPose6 + 4] = 0;
1452 L[curInd][nbPose6 + 5] = px * X * r2ud;
1456 L[curInd][q] = Ayx * (-inv_z);
1457 L[curInd][q + 1] = Ayy * (-inv_z);
1458 L[curInd][q + 2] = Ayx * (X * inv_z) + Ayy * (Y * inv_z);
1459 L[curInd][q + 3] = Ayx * XY + Ayy * (1 + Y2);
1460 L[curInd][q + 4] = -Ayx * (1 + X2) - Ayy * XY;
1461 L[curInd][q + 5] = Ayx * Y - Ayy * X;
1464 L[curInd][nbPose6] = 0;
1465 L[curInd][nbPose6 + 1] = 1;
1466 L[curInd][nbPose6 + 2] = 0;
1467 L[curInd][nbPose6 + 3] = Y * kr2ud;
1468 L[curInd][nbPose6 + 4] = 0;
1469 L[curInd][nbPose6 + 5] = py * Y * r2ud;
1482 L.pseudoInverse(Lp, 1e-10);
1487 for (
unsigned int i = 0; i < 6 * nbPose; i++)
1491 v0 + Tc[nbPose6 + 1], kud + Tc[nbPose6 + 5], kdu + Tc[nbPose6 + 4]);
1494 for (
unsigned int p = 0; p < nbPose; p++) {
1495 for (
unsigned int i = 0; i < 6; i++)
1496 Tc_v_Tmp[i] = Tc_v[6 * p + i];
1501 std::cout <<
" std dev: " << sqrt(r / nbPointTotal) << std::endl;
1504 if (iter == nbIterMax) {
1505 vpERROR_TRACE(
"Iterations number exceed the maximum allowed (%d)", nbIterMax);
1509 for (
unsigned int p = 0; p < nbPose; p++) {
1514 std::cout <<
" Global std dev " << sqrt(r / (nbPointTotal)) << std::endl;
1517 std::cout.flags(original_flags);
1520 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS) 1522 #include <visp3/vision/vpHandEyeCalibration.h> 1564 unsigned int nbPose = (
unsigned int)table_cal.size();
1566 std::vector<vpHomogeneousMatrix> table_cMo(nbPose);
1567 std::vector<vpHomogeneousMatrix> table_cMo_dist(nbPose);
1568 std::vector<vpHomogeneousMatrix> table_rMe(nbPose);
1570 for (
unsigned int i = 0; i < nbPose; i++) {
1571 table_cMo[i] = table_cal[i].cMo;
1572 table_cMo_dist[i] = table_cal[i].cMo_dist;
1573 table_rMe[i] = table_cal[i].rMe;
1584 #endif //#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS) void svd(vpColVector &w, vpMatrix &V)
Implementation of a matrix and operations on matrices.
Error that can be emited by the vpCalibration class.
Implementation of an homogeneous matrix and operations on such kind of matrices.
static int calibrate(const std::vector< vpHomogeneousMatrix > &cMo, const std::vector< vpHomogeneousMatrix > &rMe, vpHomogeneousMatrix &eMc)
static bool equal(double x, double y, double s=0.001)
error that can be emited by ViSP classes.
Tools for perspective camera calibration.
void initPersProjWithDistortion(double px, double py, double u0, double v0, double kud, double kdu)
vpHomogeneousMatrix cMo
(as a 3x4 matrix [R T])
something is not initialized
static vp_deprecated int computeCalibrationTsai(const std::vector< vpCalibration > &table_cal, vpHomogeneousMatrix &eMc, vpHomogeneousMatrix &eMc_dist)
static double sqr(double x)
vpHomogeneousMatrix cMo_dist
Generic class defining intrinsic camera parameters.
vpHomogeneousMatrix eMc_dist
Position of the camera in end-effector frame using camera parameters with distorsion.
vpHomogeneousMatrix rMe
reference coordinates (manipulator base coordinates)
void initPersProjWithoutDistortion(double px, double py, double u0, double v0)
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 vp_deprecated void calibrationTsai(const std::vector< vpHomogeneousMatrix > &cMo, const std::vector< vpHomogeneousMatrix > &rMe, vpHomogeneousMatrix &eMc)
vpHomogeneousMatrix inverse() const
iterative algorithm doesn't converge
static vpHomogeneousMatrix direct(const vpColVector &v)
vpHomogeneousMatrix eMc
Position of the camera in end-effector frame using camera parameters without distorsion.
vpMatrix pseudoInverse(double svThreshold=1e-6) const
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