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;
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.
vpMatrix pseudoInverse(double svThreshold=1e-6) const
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.
vpHomogeneousMatrix inverse() const
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)
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.
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