57 #include <opencv2/core/core.hpp> 67 PnPsolver::PnPsolver(
const Frame &F,
const vector<MapPoint*> &vpMapPointMatches):
68 pws(0), us(0), alphas(0), pcs(0), maximum_number_of_correspondences(0), number_of_correspondences(0), mnInliersi(0),
69 mnIterations(0), mnBestInliers(0), N(0)
79 for(
size_t i=0, iend=vpMapPointMatches.size(); i<iend; i++)
81 MapPoint* pMP = vpMapPointMatches[i];
87 const cv::KeyPoint &kp = F.
mvKeysUn[i];
89 mvP2D.push_back(kp.pt);
93 mvP3Dw.push_back(cv::Point3f(Pos.at<
float>(0),Pos.at<
float>(1), Pos.at<
float>(2)));
137 if(nMinInliers<minSet)
150 nIterations = ceil(log(1-
mRansacProb)/log(1-pow(mRansacEpsilon,3)));
155 for(
size_t i=0; i<
mvSigma2.size(); i++)
179 vector<size_t> vAvailableIndices;
181 int nCurrentIterations = 0;
184 nCurrentIterations++;
195 int idx = vAvailableIndices[randi];
199 vAvailableIndices[randi] = vAvailableIndices.back();
200 vAvailableIndices.pop_back();
217 cv::Mat Rcw(3,3,CV_64F,
mRi);
218 cv::Mat tcw(3,1,CV_64F,
mti);
219 Rcw.convertTo(Rcw,CV_32F);
220 tcw.convertTo(tcw,CV_32F);
221 mBestTcw = cv::Mat::eye(4,4,CV_32F);
222 Rcw.copyTo(
mBestTcw.rowRange(0,3).colRange(0,3));
223 tcw.copyTo(
mBestTcw.rowRange(0,3).col(3));
230 for(
int i=0; i<
N; i++)
248 for(
int i=0; i<
N; i++)
262 vector<int> vIndices;
269 vIndices.push_back(i);
277 for(
size_t i=0; i<vIndices.size(); i++)
279 int idx = vIndices[i];
294 cv::Mat Rcw(3,3,CV_64F,
mRi);
295 cv::Mat tcw(3,1,CV_64F,
mti);
296 Rcw.convertTo(Rcw,CV_32F);
297 tcw.convertTo(tcw,CV_32F);
299 Rcw.copyTo(
mRefinedTcw.rowRange(0,3).colRange(0,3));
312 for(
int i=0; i<
N; i++)
314 cv::Point3f P3Dw =
mvP3Dw[i];
315 cv::Point2f P2D =
mvP2D[i];
317 float Xc =
mRi[0][0]*P3Dw.x+
mRi[0][1]*P3Dw.y+
mRi[0][2]*P3Dw.z+
mti[0];
318 float Yc =
mRi[1][0]*P3Dw.x+
mRi[1][1]*P3Dw.y+
mRi[1][2]*P3Dw.z+
mti[1];
319 float invZc = 1/(
mRi[2][0]*P3Dw.x+
mRi[2][1]*P3Dw.y+
mRi[2][2]*P3Dw.z+
mti[2]);
321 double ue =
uc +
fu * Xc * invZc;
322 double ve =
vc +
fv * Yc * invZc;
324 float distX = P2D.x-ue;
325 float distY = P2D.y-ve;
327 float error2 = distX*distX+distY*distY;
345 if (
pws != 0)
delete []
pws;
346 if (
us != 0)
delete []
us;
348 if (
pcs != 0)
delete []
pcs;
380 for(
int j = 0; j < 3; j++)
381 cws[0][j] +=
pws[3 * i + j];
383 for(
int j = 0; j < 3; j++)
384 cws[0][j] /= number_of_correspondences;
388 CvMat * PW0 = cvCreateMat(number_of_correspondences, 3, CV_64F);
390 double pw0tpw0[3 * 3], dc[3], uct[3 * 3];
391 CvMat PW0tPW0 = cvMat(3, 3, CV_64F, pw0tpw0);
392 CvMat DC = cvMat(3, 1, CV_64F, dc);
393 CvMat UCt = cvMat(3, 3, CV_64F, uct);
396 for(
int j = 0; j < 3; j++)
397 PW0->data.db[3 * i + j] =
pws[3 * i + j] -
cws[0][j];
399 cvMulTransposed(PW0, &PW0tPW0, 1);
400 cvSVD(&PW0tPW0, &DC, &UCt, 0, CV_SVD_MODIFY_A | CV_SVD_U_T);
404 for(
int i = 1; i < 4; i++) {
405 double k = sqrt(dc[i - 1] / number_of_correspondences);
406 for(
int j = 0; j < 3; j++)
407 cws[i][j] =
cws[0][j] + k * uct[3 * (i - 1) + j];
413 double cc[3 * 3], cc_inv[3 * 3];
414 CvMat CC = cvMat(3, 3, CV_64F, cc);
415 CvMat CC_inv = cvMat(3, 3, CV_64F, cc_inv);
417 for(
int i = 0; i < 3; i++)
418 for(
int j = 1; j < 4; j++)
419 cc[3 * i + j - 1] =
cws[j][i] -
cws[0][i];
421 cvInvert(&CC, &CC_inv, CV_SVD);
422 double * ci = cc_inv;
424 double * pi =
pws + 3 * i;
425 double * a =
alphas + 4 * i;
427 for(
int j = 0; j < 3; j++)
429 ci[3 * j ] * (pi[0] -
cws[0][0]) +
430 ci[3 * j + 1] * (pi[1] -
cws[0][1]) +
431 ci[3 * j + 2] * (pi[2] -
cws[0][2]);
432 a[0] = 1.0f - a[1] - a[2] - a[3];
437 const int row,
const double * as,
const double u,
const double v)
439 double * M1 = M->data.db + row * 12;
440 double * M2 = M1 + 12;
442 for(
int i = 0; i < 4; i++) {
443 M1[3 * i ] = as[i] *
fu;
445 M1[3 * i + 2] = as[i] * (
uc - u);
448 M2[3 * i + 1] = as[i] *
fv;
449 M2[3 * i + 2] = as[i] * (
vc - v);
455 for(
int i = 0; i < 4; i++)
458 for(
int i = 0; i < 4; i++) {
459 const double * v = ut + 12 * (11 - i);
460 for(
int j = 0; j < 4; j++)
461 for(
int k = 0; k < 3; k++)
462 ccs[j][k] += betas[i] * v[3 * j + k];
469 double * a =
alphas + 4 * i;
470 double * pc =
pcs + 3 * i;
472 for(
int j = 0; j < 3; j++)
473 pc[j] = a[0] *
ccs[0][j] + a[1] *
ccs[1][j] + a[2] *
ccs[2][j] + a[3] *
ccs[3][j];
487 double mtm[12 * 12],
d[12], ut[12 * 12];
488 CvMat MtM = cvMat(12, 12, CV_64F, mtm);
489 CvMat D = cvMat(12, 1, CV_64F, d);
490 CvMat Ut = cvMat(12, 12, CV_64F, ut);
492 cvMulTransposed(M, &MtM, 1);
493 cvSVD(&MtM, &D, &Ut, 0, CV_SVD_MODIFY_A | CV_SVD_U_T);
496 double l_6x10[6 * 10], rho[6];
497 CvMat L_6x10 = cvMat(6, 10, CV_64F, l_6x10);
498 CvMat Rho = cvMat(6, 1, CV_64F, rho);
503 double Betas[4][4], rep_errors[4];
504 double Rs[4][3][3], ts[4][3];
519 if (rep_errors[2] < rep_errors[1]) N = 2;
520 if (rep_errors[3] < rep_errors[N]) N = 3;
524 return rep_errors[
N];
528 double R_dst[3][3],
double t_dst[3])
530 for(
int i = 0; i < 3; i++) {
531 for(
int j = 0; j < 3; j++)
532 R_dst[i][j] = R_src[i][j];
540 (p1[0] - p2[0]) * (p1[0] - p2[0]) +
541 (p1[1] - p2[1]) * (p1[1] - p2[1]) +
542 (p1[2] - p2[2]) * (p1[2] - p2[2]);
547 return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
555 double * pw =
pws + 3 * i;
556 double Xc =
dot(R[0], pw) + t[0];
557 double Yc =
dot(R[1], pw) + t[1];
558 double inv_Zc = 1.0 / (
dot(R[2], pw) + t[2]);
559 double ue =
uc +
fu * Xc * inv_Zc;
560 double ve =
vc +
fv * Yc * inv_Zc;
561 double u =
us[2 * i], v =
us[2 * i + 1];
563 sum2 += sqrt( (u - ue) * (u - ue) + (v - ve) * (v - ve) );
571 double pc0[3], pw0[3];
573 pc0[0] = pc0[1] = pc0[2] = 0.0;
574 pw0[0] = pw0[1] = pw0[2] = 0.0;
577 const double * pc =
pcs + 3 * i;
578 const double * pw =
pws + 3 * i;
580 for(
int j = 0; j < 3; j++) {
585 for(
int j = 0; j < 3; j++) {
590 double abt[3 * 3], abt_d[3], abt_u[3 * 3], abt_v[3 * 3];
591 CvMat ABt = cvMat(3, 3, CV_64F, abt);
592 CvMat ABt_D = cvMat(3, 1, CV_64F, abt_d);
593 CvMat ABt_U = cvMat(3, 3, CV_64F, abt_u);
594 CvMat ABt_V = cvMat(3, 3, CV_64F, abt_v);
598 double * pc =
pcs + 3 * i;
599 double * pw =
pws + 3 * i;
601 for(
int j = 0; j < 3; j++) {
602 abt[3 * j ] += (pc[j] - pc0[j]) * (pw[0] - pw0[0]);
603 abt[3 * j + 1] += (pc[j] - pc0[j]) * (pw[1] - pw0[1]);
604 abt[3 * j + 2] += (pc[j] - pc0[j]) * (pw[2] - pw0[2]);
608 cvSVD(&ABt, &ABt_D, &ABt_U, &ABt_V, CV_SVD_MODIFY_A);
610 for(
int i = 0; i < 3; i++)
611 for(
int j = 0; j < 3; j++)
612 R[i][j] =
dot(abt_u + 3 * i, abt_v + 3 * j);
615 R[0][0] * R[1][1] * R[2][2] + R[0][1] * R[1][2] * R[2][0] + R[0][2] * R[1][0] * R[2][1] -
616 R[0][2] * R[1][1] * R[2][0] - R[0][1] * R[1][0] * R[2][2] - R[0][0] * R[1][2] * R[2][1];
624 t[0] = pc0[0] -
dot(R[0], pw0);
625 t[1] = pc0[1] -
dot(R[1], pw0);
626 t[2] = pc0[2] -
dot(R[2], pw0);
631 cout << R[0][0] <<
" " << R[0][1] <<
" " << R[0][2] <<
" " << t[0] << endl;
632 cout << R[1][0] <<
" " << R[1][1] <<
" " << R[1][2] <<
" " << t[1] << endl;
633 cout << R[2][0] <<
" " << R[2][1] <<
" " << R[2][2] <<
" " << t[2] << endl;
639 for(
int i = 0; i < 4; i++)
640 for(
int j = 0; j < 3; j++)
644 pcs[3 * i ] = -
pcs[3 * i];
645 pcs[3 * i + 1] = -
pcs[3 * i + 1];
646 pcs[3 * i + 2] = -
pcs[3 * i + 2];
652 double R[3][3],
double t[3])
670 double l_6x4[6 * 4], b4[4];
671 CvMat L_6x4 = cvMat(6, 4, CV_64F, l_6x4);
672 CvMat B4 = cvMat(4, 1, CV_64F, b4);
674 for(
int i = 0; i < 6; i++) {
675 cvmSet(&L_6x4, i, 0, cvmGet(L_6x10, i, 0));
676 cvmSet(&L_6x4, i, 1, cvmGet(L_6x10, i, 1));
677 cvmSet(&L_6x4, i, 2, cvmGet(L_6x10, i, 3));
678 cvmSet(&L_6x4, i, 3, cvmGet(L_6x10, i, 6));
681 cvSolve(&L_6x4, Rho, &B4, CV_SVD);
684 betas[0] = sqrt(-b4[0]);
685 betas[1] = -b4[1] / betas[0];
686 betas[2] = -b4[2] / betas[0];
687 betas[3] = -b4[3] / betas[0];
689 betas[0] = sqrt(b4[0]);
690 betas[1] = b4[1] / betas[0];
691 betas[2] = b4[2] / betas[0];
692 betas[3] = b4[3] / betas[0];
702 double l_6x3[6 * 3], b3[3];
703 CvMat L_6x3 = cvMat(6, 3, CV_64F, l_6x3);
704 CvMat B3 = cvMat(3, 1, CV_64F, b3);
706 for(
int i = 0; i < 6; i++) {
707 cvmSet(&L_6x3, i, 0, cvmGet(L_6x10, i, 0));
708 cvmSet(&L_6x3, i, 1, cvmGet(L_6x10, i, 1));
709 cvmSet(&L_6x3, i, 2, cvmGet(L_6x10, i, 2));
712 cvSolve(&L_6x3, Rho, &B3, CV_SVD);
715 betas[0] = sqrt(-b3[0]);
716 betas[1] = (b3[2] < 0) ? sqrt(-b3[2]) : 0.0;
718 betas[0] = sqrt(b3[0]);
719 betas[1] = (b3[2] > 0) ? sqrt(b3[2]) : 0.0;
722 if (b3[1] < 0) betas[0] = -betas[0];
734 double l_6x5[6 * 5], b5[5];
735 CvMat L_6x5 = cvMat(6, 5, CV_64F, l_6x5);
736 CvMat B5 = cvMat(5, 1, CV_64F, b5);
738 for(
int i = 0; i < 6; i++) {
739 cvmSet(&L_6x5, i, 0, cvmGet(L_6x10, i, 0));
740 cvmSet(&L_6x5, i, 1, cvmGet(L_6x10, i, 1));
741 cvmSet(&L_6x5, i, 2, cvmGet(L_6x10, i, 2));
742 cvmSet(&L_6x5, i, 3, cvmGet(L_6x10, i, 3));
743 cvmSet(&L_6x5, i, 4, cvmGet(L_6x10, i, 4));
746 cvSolve(&L_6x5, Rho, &B5, CV_SVD);
749 betas[0] = sqrt(-b5[0]);
750 betas[1] = (b5[2] < 0) ? sqrt(-b5[2]) : 0.0;
752 betas[0] = sqrt(b5[0]);
753 betas[1] = (b5[2] > 0) ? sqrt(b5[2]) : 0.0;
755 if (b5[1] < 0) betas[0] = -betas[0];
756 betas[2] = b5[3] / betas[0];
771 for(
int i = 0; i < 4; i++) {
773 for(
int j = 0; j < 6; j++) {
774 dv[i][j][0] = v[i][3 * a ] - v[i][3 * b];
775 dv[i][j][1] = v[i][3 * a + 1] - v[i][3 * b + 1];
776 dv[i][j][2] = v[i][3 * a + 2] - v[i][3 * b + 2];
786 for(
int i = 0; i < 6; i++) {
787 double * row = l_6x10 + 10 * i;
789 row[0] =
dot(dv[0][i], dv[0][i]);
790 row[1] = 2.0f *
dot(dv[0][i], dv[1][i]);
791 row[2] =
dot(dv[1][i], dv[1][i]);
792 row[3] = 2.0f *
dot(dv[0][i], dv[2][i]);
793 row[4] = 2.0f *
dot(dv[1][i], dv[2][i]);
794 row[5] =
dot(dv[2][i], dv[2][i]);
795 row[6] = 2.0f *
dot(dv[0][i], dv[3][i]);
796 row[7] = 2.0f *
dot(dv[1][i], dv[3][i]);
797 row[8] = 2.0f *
dot(dv[2][i], dv[3][i]);
798 row[9] =
dot(dv[3][i], dv[3][i]);
813 double betas[4], CvMat * A, CvMat * b)
815 for(
int i = 0; i < 6; i++) {
816 const double * rowL = l_6x10 + i * 10;
817 double * rowA = A->data.db + i * 4;
819 rowA[0] = 2 * rowL[0] * betas[0] + rowL[1] * betas[1] + rowL[3] * betas[2] + rowL[6] * betas[3];
820 rowA[1] = rowL[1] * betas[0] + 2 * rowL[2] * betas[1] + rowL[4] * betas[2] + rowL[7] * betas[3];
821 rowA[2] = rowL[3] * betas[0] + rowL[4] * betas[1] + 2 * rowL[5] * betas[2] + rowL[8] * betas[3];
822 rowA[3] = rowL[6] * betas[0] + rowL[7] * betas[1] + rowL[8] * betas[2] + 2 * rowL[9] * betas[3];
824 cvmSet(b, i, 0, rho[i] -
826 rowL[0] * betas[0] * betas[0] +
827 rowL[1] * betas[0] * betas[1] +
828 rowL[2] * betas[1] * betas[1] +
829 rowL[3] * betas[0] * betas[2] +
830 rowL[4] * betas[1] * betas[2] +
831 rowL[5] * betas[2] * betas[2] +
832 rowL[6] * betas[0] * betas[3] +
833 rowL[7] * betas[1] * betas[3] +
834 rowL[8] * betas[2] * betas[3] +
835 rowL[9] * betas[3] * betas[3]
843 const int iterations_number = 5;
845 double a[6*4], b[6],
x[4];
846 CvMat A = cvMat(6, 4, CV_64F, a);
847 CvMat B = cvMat(6, 1, CV_64F, b);
848 CvMat X = cvMat(4, 1, CV_64F, x);
850 for(
int k = 0; k < iterations_number; k++) {
855 for(
int i = 0; i < 4; i++)
862 static int max_nr = 0;
863 static double * A1, * A2;
865 const int nr = A->rows;
866 const int nc = A->cols;
868 if (max_nr != 0 && max_nr < nr) {
878 double * pA = A->data.db, * ppAkk = pA;
879 for(
int k = 0; k < nc; k++) {
880 double * ppAik = ppAkk, eta = fabs(*ppAik);
881 for(
int i = k + 1; i < nr; i++) {
882 double elt = fabs(*ppAik);
883 if (eta < elt) eta = elt;
889 cerr <<
"God damnit, A is singular, this shouldn't happen." << endl;
892 double * ppAik = ppAkk, sum = 0.0, inv_eta = 1. / eta;
893 for(
int i = k; i < nr; i++) {
895 sum += *ppAik * *ppAik;
898 double sigma = sqrt(sum);
902 A1[k] = sigma * *ppAkk;
903 A2[k] = -eta * sigma;
904 for(
int j = k + 1; j < nc; j++) {
905 double * ppAik = ppAkk, sum = 0;
906 for(
int i = k; i < nr; i++) {
907 sum += *ppAik * ppAik[j - k];
910 double tau = sum / A1[k];
912 for(
int i = k; i < nr; i++) {
913 ppAik[j - k] -= tau * *ppAik;
922 double * ppAjj = pA, * pb = b->data.db;
923 for(
int j = 0; j < nc; j++) {
924 double * ppAij = ppAjj, tau = 0;
925 for(
int i = j; i < nr; i++) {
926 tau += *ppAij * pb[i];
931 for(
int i = j; i < nr; i++) {
932 pb[i] -= tau * *ppAij;
939 double * pX = X->data.db;
940 pX[nc - 1] = pb[nc - 1] / A2[nc - 1];
941 for(
int i = nc - 2; i >= 0; i--) {
942 double * ppAij = pA + i * nc + (i + 1), sum = 0;
944 for(
int j = i + 1; j < nc; j++) {
945 sum += *ppAij * pX[j];
948 pX[i] = (pb[i] - sum) / A2[i];
955 const double Rtrue[3][3],
const double ttrue[3],
956 const double Rest[3][3],
const double test[3])
958 double qtrue[4], qest[4];
963 double rot_err1 = sqrt((qtrue[0] - qest[0]) * (qtrue[0] - qest[0]) +
964 (qtrue[1] - qest[1]) * (qtrue[1] - qest[1]) +
965 (qtrue[2] - qest[2]) * (qtrue[2] - qest[2]) +
966 (qtrue[3] - qest[3]) * (qtrue[3] - qest[3]) ) /
967 sqrt(qtrue[0] * qtrue[0] + qtrue[1] * qtrue[1] + qtrue[2] * qtrue[2] + qtrue[3] * qtrue[3]);
969 double rot_err2 = sqrt((qtrue[0] + qest[0]) * (qtrue[0] + qest[0]) +
970 (qtrue[1] + qest[1]) * (qtrue[1] + qest[1]) +
971 (qtrue[2] + qest[2]) * (qtrue[2] + qest[2]) +
972 (qtrue[3] + qest[3]) * (qtrue[3] + qest[3]) ) /
973 sqrt(qtrue[0] * qtrue[0] + qtrue[1] * qtrue[1] + qtrue[2] * qtrue[2] + qtrue[3] * qtrue[3]);
975 rot_err =
min(rot_err1, rot_err2);
978 sqrt((ttrue[0] - test[0]) * (ttrue[0] - test[0]) +
979 (ttrue[1] - test[1]) * (ttrue[1] - test[1]) +
980 (ttrue[2] - test[2]) * (ttrue[2] - test[2])) /
981 sqrt(ttrue[0] * ttrue[0] + ttrue[1] * ttrue[1] + ttrue[2] * ttrue[2]);
986 double tr = R[0][0] + R[1][1] + R[2][2];
990 q[0] = R[1][2] - R[2][1];
991 q[1] = R[2][0] - R[0][2];
992 q[2] = R[0][1] - R[1][0];
995 }
else if ( (R[0][0] > R[1][1]) && (R[0][0] > R[2][2]) ) {
996 q[0] = 1.0f + R[0][0] - R[1][1] - R[2][2];
997 q[1] = R[1][0] + R[0][1];
998 q[2] = R[2][0] + R[0][2];
999 q[3] = R[1][2] - R[2][1];
1001 }
else if (R[1][1] > R[2][2]) {
1002 q[0] = R[1][0] + R[0][1];
1003 q[1] = 1.0f + R[1][1] - R[0][0] - R[2][2];
1004 q[2] = R[2][1] + R[1][2];
1005 q[3] = R[2][0] - R[0][2];
1008 q[0] = R[2][0] + R[0][2];
1009 q[1] = R[2][1] + R[1][2];
1010 q[2] = 1.0f + R[2][2] - R[0][0] - R[1][1];
1011 q[3] = R[0][1] - R[1][0];
1014 double scale = 0.5f / double(sqrt(n4));
void estimate_R_and_t(double R[3][3], double t[3])
void compute_L_6x10(const double *ut, double *l_6x10)
std::vector< MapPoint * > mvpMapPoints
void find_betas_approx_3(const CvMat *L_6x10, const CvMat *Rho, double *betas)
vector< bool > mvbBestInliers
void print_pose(const double R[3][3], const double t[3])
void compute_rho(double *rho)
double compute_R_and_t(const double *ut, const double *betas, double R[3][3], double t[3])
void gauss_newton(const CvMat *L_6x10, const CvMat *Rho, double current_betas[4])
void compute_barycentric_coordinates(void)
cv::Mat iterate(int nIterations, bool &bNoMore, vector< bool > &vbInliers, int &nInliers)
TFSIMD_FORCE_INLINE const tfScalar & y() const
cv::Mat find(vector< bool > &vbInliers, int &nInliers)
std::vector< cv::KeyPoint > mvKeysUn
vector< cv::Point2f > mvP2D
void set_maximum_number_of_correspondences(const int n)
vector< float > mvLevelSigma2
double dist2(const double *p1, const double *p2)
int maximum_number_of_correspondences
TFSIMD_FORCE_INLINE const tfScalar & x() const
double compute_pose(double R[3][3], double T[3])
void find_betas_approx_1(const CvMat *L_6x10, const CvMat *Rho, double *betas)
int number_of_correspondences
vector< float > mvMaxError
double reprojection_error(const double R[3][3], const double t[3])
static int RandomInt(int min, int max)
TFSIMD_FORCE_INLINE const tfScalar & z() const
void relative_error(double &rot_err, double &transl_err, const double Rtrue[3][3], const double ttrue[3], const double Rest[3][3], const double test[3])
vector< cv::Point3f > mvP3Dw
void SetRansacParameters(double probability=0.99, int minInliers=8, int maxIterations=300, int minSet=4, float epsilon=0.4, float th2=5.991)
vector< bool > mvbInliersi
void reset_correspondences(void)
double dot(const double *v1, const double *v2)
void compute_A_and_b_gauss_newton(const double *l_6x10, const double *rho, double cb[4], CvMat *A, CvMat *b)
vector< MapPoint * > mvpMapPointMatches
void copy_R_and_t(const double R_dst[3][3], const double t_dst[3], double R_src[3][3], double t_src[3])
vector< size_t > mvAllIndices
vector< bool > mvbRefinedInliers
void compute_ccs(const double *betas, const double *ut)
void find_betas_approx_2(const CvMat *L_6x10, const CvMat *Rho, double *betas)
void solve_for_sign(void)
void mat_to_quat(const double R[3][3], double q[4])
void add_correspondence(const double X, const double Y, const double Z, const double u, const double v)
void qr_solve(CvMat *A, CvMat *b, CvMat *X)
vector< size_t > mvKeyPointIndices
void choose_control_points(void)
void fill_M(CvMat *M, const int row, const double *alphas, const double u, const double v)