27 #ifdef USE_NUMERIC_JACOBIANS 53 ASSERT_(
p.check_squares_length_X_meters>0)
54 ASSERT_(
p.check_squares_length_Y_meters>0)
56 const bool user_wants_use_robust =
p.use_robust_kernel;
60 std::cout <<
"ERROR: No input images." << std::endl;
64 const unsigned CORNERS_COUNT =
p.check_size_x *
p.check_size_y;
73 vector<size_t> valid_image_pair_indices;
75 for (
size_t i=0;i<images.size();i++)
79 bool corners_found[2]={
false,
false };
81 for (
int lr=0;lr<2;lr++)
91 imgSize[lr] = img_gray.
getSize();
103 if (imgSize[lr].
y != (
int)img_gray.
getHeight() || imgSize[lr].
x != (int)img_gray.
getWidth())
105 std::cout <<
"ERROR: All the images in each left/right channel must have the same size." << std::endl;
114 p.check_size_x,
p.check_size_y,
119 corners_found[lr] =
false;
121 if (
p.verbose) cout <<
format(
"%s img #%u: %s\n", lr==0 ?
"LEFT":
"RIGHT", static_cast<unsigned int>(i), corners_found[lr] ?
"DETECTED" :
"NOT DETECTED" );
130 (*
p.callback)(cbPars,
p.callback_user_param);
133 if( corners_found[lr] )
148 if( corners_found[0] && corners_found[1] )
150 valid_image_pair_indices.push_back(i);
158 bool has_to_redraw_corners =
false;
161 pt_l0 = images[i].left.detected_corners[0],
162 pt_l1 = images[i].left.detected_corners[1],
163 pt_r0 = images[i].right.detected_corners[0],
164 pt_r1 = images[i].right.detected_corners[1];
169 if (Al.
x*Ar.
x+Al.
y*Ar.
y < 0)
171 has_to_redraw_corners =
true;
173 std::reverse( images[i].right.detected_corners.begin(), images[i].right.detected_corners.end() );
177 if (has_to_redraw_corners)
180 images[i].right.img_original.colorImage( images[i].right.img_checkboard );
181 images[i].right.img_checkboard.drawChessboardCorners( images[i].right.detected_corners,check_size.
x,check_size.
y);
187 if (
p.verbose) std::cout << valid_image_pair_indices.size() <<
" valid image pairs." << std::endl;
188 if (valid_image_pair_indices.empty() )
190 std::cout <<
"ERROR: No valid images. Perhaps the checkerboard size is incorrect?" << std::endl;
196 vector<TPoint3D> obj_points;
197 obj_points.reserve(CORNERS_COUNT);
198 for(
unsigned int y = 0;
y <
p.check_size_y;
y++ )
199 for(
unsigned int x = 0;
x <
p.check_size_x;
x++ )
201 p.check_squares_length_X_meters *
x,
202 p.check_squares_length_Y_meters *
y,
213 const size_t N = valid_image_pair_indices.size();
214 const size_t nObs = 2 * N * CORNERS_COUNT;
216 const double tau = 0.3;
217 const double t1 = 1e-8;
218 const double t2 = 1e-8;
219 const double MAX_LAMBDA = 1e20;
223 lm_stat_t lm_stat(images,valid_image_pair_indices,obj_points);
245 size_t nUnknownsCamParams=0;
251 for (
int calibRound=0; calibRound<2;calibRound++)
255 cout << ((calibRound==0) ?
256 "LM calibration round #0: WITHOUT distortion ----------\n" 258 "LM calibration round #1: ALL parameters --------------\n");
263 vars_to_optimize.clear();
264 vars_to_optimize.push_back(0);
265 vars_to_optimize.push_back(1);
266 vars_to_optimize.push_back(2);
267 vars_to_optimize.push_back(3);
270 if (
p.optimize_k1) vars_to_optimize.push_back(4);
271 if (
p.optimize_k2) vars_to_optimize.push_back(5);
272 if (
p.optimize_t1) vars_to_optimize.push_back(6);
273 if (
p.optimize_t2) vars_to_optimize.push_back(7);
274 if (
p.optimize_k3) vars_to_optimize.push_back(8);
277 nUnknownsCamParams = vars_to_optimize.size();
283 const size_t nUnknowns = N*6 + 6+ 2*nUnknownsCamParams;
290 Eigen::VectorXd minus_g;
297 double lambda = tau * H.diagonal().array().maxCoeff();
298 bool done = (minus_g.array().abs().maxCoeff() < t1);
299 int numItersImproving = 0;
300 bool use_robust =
false;
304 while (iter<
p.maxIters && !done)
311 (*
p.callback)(cbPars,
p.callback_user_param);
315 Eigen::MatrixXd HH = H;
316 for (
size_t i=0;i<nUnknowns;i++)
320 Eigen::LLT<Eigen::MatrixXd> llt( HH.selfadjointView<Eigen::Lower>() );
321 if (llt.info()!=Eigen::Success)
325 done = (lambda>MAX_LAMBDA);
327 if (
p.verbose && !done) cout <<
"LM iter#"<<iter<<
": Couldn't solve LLt, retrying with larger lambda=" << lambda << endl;
330 const Eigen::VectorXd
eps = llt.solve(minus_g);
332 const double eps_norm =
eps.norm();
333 if (eps_norm < t2*(eps_norm+t2))
335 if (
p.verbose) cout <<
"Termination criterion: eps_norm < t2*(eps_norm+t2): "<<eps_norm <<
" < " << t2*(eps_norm+t2) <<endl;
353 if (numItersImproving++>5)
354 use_robust = user_wants_use_robust;
357 if (
p.verbose) cout <<
"LM iter#"<<iter<<
": Avr.err(px):"<< std::sqrt(err/nObs) <<
"->" << std::sqrt(err_new/nObs) <<
" lambda:" << lambda << endl;
360 lm_stat.
swap( new_lm_stat );
361 res_jacob.swap( new_res_jacob );
367 done = (minus_g.array().abs().maxCoeff() < t1);
370 lambda = std::max(lambda, 1e-100);
378 if (
p.verbose) cout <<
"LM iter#"<<iter<<
": No update: err=" << err <<
" -> err_new=" << err_new <<
" retrying with larger lambda=" << lambda << endl;
380 done = (lambda>MAX_LAMBDA);
425 for (
size_t i=0;i<valid_image_pair_indices.size();i++)
436 const size_t base_idx_H_CPs = H.cols()-2*nUnknownsCamParams;
437 for (
size_t i=0;i<nUnknownsCamParams;i++)
440 out.
right_params_inv_variance[ vars_to_optimize[i] ] = H(base_idx_H_CPs+nUnknownsCamParams+i,base_idx_H_CPs+nUnknownsCamParams+i);
444 for (
size_t i=0;i<valid_image_pair_indices.size();i++)
449 const size_t idx = valid_image_pair_indices[i];
473 catch(std::exception &e)
475 std::cout << e.what() << std::endl;
493 Eigen::Matrix<double,2,3> &G)
495 const double pz_ = 1/
p.z;
496 const double pz_2 = pz_*pz_;
500 G(0,2) = -
p.x * pz_2;
504 G(1,2) = -
p.y * pz_2;
526 const Eigen::Matrix<double,9,1> &
c,
527 Eigen::Matrix<double,2,2> & Hb,
528 Eigen::Matrix<double,2,9> & Hc
531 const double x = nP.
x/nP.
z;
532 const double y = nP.
y/nP.
z;
534 const double r2 =
x*
x +
y*
y;
535 const double r = std::sqrt(r2);
536 const double r6 = r2*r2*r2;
539 const double fx=
c[0], fy=
c[1];
541 const double k1=
c[4], k2=
c[5], k3=
c[6];
542 const double t1=
c[7], t2=
c[8];
545 Hb(0,0) = fx*(k2*r2 + k3*r6 + 6*t2*
x + 2*t1*
y +
x*(2*k1*
x + 4*k2*
x*
r + 6*k3*
x*r2) + k1*
r + 1);
546 Hb(0,1) = fx*(2*t1*
x + 2*t2*
y +
x*(2*k1*
y + 4*k2*
y*
r + 6*k3*
y*r2));
548 Hb(1,0) = fy*(2*t1*
x + 2*t2*
y +
y*(2*k1*
x + 4*k2*
x*
r + 6*k3*
x*r2));
549 Hb(1,1) = fy*(k2*r2 + k3*r6 + 2*t2*
x + 6*t1*
y +
y*(2*k1*
y + 4*k2*
y*
r + 6*k3*
y*r2) + k1*
r + 1);
553 Hc(0,0) = t2*(3*
x*
x +
y*
y) +
x*(k2*r2 + k3*r6 + k1*
r + 1) + 2*t1*
x*
y;
561 Hc(0,8) = fx*(3*
x*
x +
y*
y);
564 Hc(1,1) = t1*(
x*
x + 3*
y*
y) +
y*(k2*r2 + k3*r6 + k1*
r + 1) + 2*t2*
x*
y;
570 Hc(1,7) = fy*(
x*
x + 3*
y*
y);
578 Eigen::Matrix<double,3,6> &dpl_del)
581 dpl_del.block<3,3>(0,0).setIdentity();
589 Eigen::Matrix<double,3,6> &dp_deps)
592 const Eigen::Matrix<double,1,3> P(
p.x,
p.y,
p.z);
597 const Eigen::Matrix<double,1,3>
v( P.dot(dr1)+D.
x(), P.dot(dr2)+D.
y(), P.dot(dr3)+D.z() );
599 Eigen::Matrix<double,3,6> H;
600 H.block<3,3>(0,0).setIdentity();
619 const double x = nP.
x/nP.
z;
620 const double y = nP.
y/nP.
z;
624 const double r4 =
square(r2);
625 const double r6 = r2*r4;
627 const double B = 2*
x*
y;
642 Eigen::VectorXd &minus_g,
645 const size_t N = res_jac.size();
646 const size_t nMaxUnknowns = N*6+6+9+9;
649 Eigen::VectorXd minus_g_tot = Eigen::VectorXd::Zero(nMaxUnknowns);
650 Eigen::MatrixXd H_tot = Eigen::MatrixXd::Zero(nMaxUnknowns,nMaxUnknowns);
653 for (
size_t i=0;i<N;i++)
655 const size_t nObs = res_jac[i].size();
656 for (
size_t j=0;j<nObs;j++)
661 const Eigen::Matrix<double,30,30> Hij = rje.
J.transpose() * rje.
J;
662 const Eigen::Matrix<double,30,1> gij = rje.
J.transpose() * rje.
residual;
665 minus_g_tot.block<6,1>(i*6,0) -= gij.block<6,1>(0,0);
666 minus_g_tot.block<6+9+9,1>(N*6,0) -= gij.block<6+9+9,1>(6,0);
668 H_tot.block<6,6>(i*6,i*6) += Hij.block<6,6>(0,0);
670 H_tot.block<6+9+9,6+9+9>(N*6,N*6) += Hij.block<6+9+9,6+9+9>(6,6);
671 H_tot.block<6,6+9+9>(i*6,N*6) += Hij.block<6,6+9+9>(0,6);
672 H_tot.block<6+9+9,6>(N*6,i*6) += Hij.block<6+9+9,6>(6,0);
680 const double cost_lr_angular = 1e10;
681 H_tot.block<3,3>(N*6+3,N*6+3) += Eigen::Matrix<double,3,3>::Identity() * cost_lr_angular;
686 const size_t N_Cs = var_indxs.size();
687 const size_t nUnknowns = N*6 + 6 + 2*N_Cs;
688 const size_t nUnkPoses = N*6 + 6;
690 minus_g.setZero(nUnknowns);
691 H.setZero(nUnknowns,nUnknowns);
693 minus_g.block(0,0, nUnkPoses,1 ) = minus_g_tot.block(0,0, nUnkPoses,1);
694 H.block(0,0, nUnkPoses,nUnkPoses) = H_tot.block(0,0, nUnkPoses,nUnkPoses);
697 for (
size_t i=0;i<N_Cs;i++)
699 minus_g[nUnkPoses+i] = minus_g_tot[nUnkPoses + var_indxs[i] ];
700 minus_g[nUnkPoses+N_Cs+i] = minus_g_tot[nUnkPoses + 9 + var_indxs[i] ];
703 for (
size_t k=0;k<nUnkPoses;k++)
705 for (
size_t i=0;i<N_Cs;i++)
707 H(nUnkPoses+i,k) = H(k,nUnkPoses+i) = H_tot(k,nUnkPoses+var_indxs[i]);
708 H(nUnkPoses+i+N_Cs,k) = H(k,nUnkPoses+i+N_Cs) = H_tot(k,nUnkPoses+9+var_indxs[i]);
712 for (
size_t i=0;i<N_Cs;i++)
714 for (
size_t j=0;j<N_Cs;j++)
716 H(nUnkPoses+i,nUnkPoses+j) = H_tot( nUnkPoses + var_indxs[i], nUnkPoses + var_indxs[j] );
717 H(nUnkPoses+N_Cs+i,nUnkPoses+N_Cs+j) = H_tot( nUnkPoses +9+var_indxs[i], nUnkPoses +9+ var_indxs[j] );
725 M1.saveToTextFile(
"H1.txt");
726 g1.saveToTextFile(
"g1.txt");
730 M2.saveToTextFile(
"H2.txt");
731 g2.saveToTextFile(
"g2.txt");
744 const Eigen::VectorXd &
eps,
750 for (
size_t i=0;i<N;i++)
756 const CPose3D incrPose = CPose3D::exp(incr);
767 const CPose3D incrPose = CPose3D::exp(incr);
775 const size_t idx=6*N+6;
776 const size_t nPC = var_indxs.size();
777 for (
size_t i=0;i<nPC;i++)
786 #ifdef USE_NUMERIC_JACOBIANS 796 const Eigen::Matrix<double,4,1> & real_obs;
803 const Eigen::Matrix<double,4,1> &_real_obs
804 ) : lm_stat(_lm_stat), obj_point(_obj_point), left_cam(_left_cam), right2left(_right2left), real_obs(_real_obs)
810 void numeric_jacob_eval_function(
812 const TNumJacobData &dat,
817 const CPose3D incrPose_l = CPose3D::exp(incr_l);
819 const CPose3D incrPose_rl = CPose3D::exp(incr_rl);
849 project_point( dat.obj_point,cam_params.
rightCamera, incrPose_rl + dat.right2left + incrPose_l + dat.left_cam, px_r );
851 const Eigen::Matrix<double,4,1> predicted_obs( px_l.
x,px_l.
y, px_r.
x,px_r.
y );
863 const double x = X[0],
y=X[1];
865 const double r4 =
square(r2);
866 const double r6 = r2*r4;
868 const double B = 2*
x*
y;
891 const CPose3D incrPose = CPose3D::exp(incr);
894 for (
int i=0;i<3;i++) out[i]=D_p_out[i];
897 struct TEvalData_A_eps_D_p
903 void eval_dA_eps_D_p(
905 const TEvalData_A_eps_D_p &dat,
909 const CPose3D incrPose = CPose3D::exp(incr);
910 const CPose3D A_eps_D = dat.A + (incrPose + dat.D);
913 for (
int i=0;i<3;i++) out[i]=pt[i];
928 bool use_robust_kernel,
929 double kernel_param )
948 for (
size_t k=0;k<N;k++)
951 const size_t nPts = lm_stat.
obj_points.size();
952 res_jac[k].resize(nPts);
954 for (
size_t i=0;i<nPts;i++)
959 const Eigen::Matrix<double,4,1> obs(px_obs_l.
x,px_obs_l.
y,px_obs_r.
x,px_obs_r.
y);
974 const double err_sqr_norm = rje.
residual.squaredNorm();
975 if (use_robust_kernel)
978 rk.param_sq = kernel_param;
980 double kernel_1st_deriv,kernel_2nd_deriv;
981 const double scaled_err = rk.eval(err_sqr_norm, kernel_1st_deriv,kernel_2nd_deriv );
984 total_err += scaled_err;
986 else total_err += err_sqr_norm;
992 #if !defined(USE_NUMERIC_JACOBIANS) || defined(COMPARE_NUMERIC_JACOBIANS) 994 Eigen::Matrix<double,2,6> dhl_del, dhr_del, dhr_der;
995 Eigen::Matrix<double,2,9> dhl_dcl, dhr_dcr;
1003 Eigen::Matrix<double,2,2> dhl_dbl, dhr_dbr;
1016 x_incrs.setConstant(1e-6);
1018 Eigen::Matrix<double,2,2> num_dhl_dbl, num_dhr_dbr;
1026 cout <<
"num_dhl_dbl:\n" << num_dhl_dbl <<
"\ndiff dhl_dbl:\n" << dhl_dbl-num_dhl_dbl << endl << endl;
1027 cout <<
"num_dhr_dbr:\n" << num_dhr_dbr <<
"\ndiff dhr_dbr:\n" << dhr_dbr-num_dhr_dbr << endl << endl;
1032 Eigen::Matrix<double,2,3> dbl_dpl, dbr_dpr;
1040 x0[0]=pt_wrt_left.
x;
1041 x0[1]=pt_wrt_left.
y;
1042 x0[2]=pt_wrt_left.
z;
1045 x_incrs.setConstant(1e-8);
1047 Eigen::Matrix<double,2,3> num_dbl_dpl, num_dbr_dpr;
1051 x0[0]=pt_wrt_right.
x;
1052 x0[1]=pt_wrt_right.
y;
1053 x0[2]=pt_wrt_right.
z;
1056 cout <<
"num_dbl_dpl:\n" << num_dbl_dpl <<
"\ndbl_dpl:\n" << dbl_dpl << endl << endl;
1057 cout <<
"num_dbr_dpr:\n" << num_dbr_dpr <<
"\ndbr_dpr:\n" << dbr_dpr << endl << endl;
1064 Eigen::Matrix<double,3,6> dpl_del, dpr_del, dpr_der;
1077 x_incrs.setConstant(1e-8);
1079 Eigen::Matrix<double,3,6> num_dpl_del, num_dpr_der;
1083 cout <<
"num_dpl_del:\n" << num_dpl_del <<
"\ndiff dpl_del:\n" << dpl_del-num_dpl_del << endl << endl;
1084 cout <<
"num_dpr_der:\n" << num_dpr_der <<
"\ndiff dpr_der:\n" << dpr_der-num_dpr_der << endl << endl;
1096 x_incrs.setConstant(1e-8);
1098 TEvalData_A_eps_D_p dat;
1103 Eigen::Matrix<double,3,6> num_dpr_del;
1106 cout <<
"num_dpr_del:\n" << num_dpr_del <<
"\ndiff dpr_del:\n" << num_dpr_del-dpr_del << endl << endl;
1111 dhl_del = dhl_dbl * dbl_dpl * dpl_del;
1112 dhr_del = dhr_dbr * dbr_dpr * dpr_del;
1113 dhr_der = dhr_dbr * dbr_dpr * dpr_der;
1115 rje.
J.setZero(4,30);
1116 rje.
J.block<2,6>(0,0) = dhl_del;
1117 rje.
J.block<2,6>(2,0) = dhr_del;
1118 rje.
J.block<2,6>(2,6) = dhr_der;
1119 rje.
J.block<2,9>(0,12) = dhl_dcl;
1120 rje.
J.block<2,9>(2,21) = dhr_dcr;
1122 # if defined(COMPARE_NUMERIC_JACOBIANS) 1123 const Eigen::Matrix<double,4,30> J_theor=rje.
J;
1128 #if defined(USE_NUMERIC_JACOBIANS) || defined(COMPARE_NUMERIC_JACOBIANS) 1136 const double x_incrs_val[30] = {
1137 1e-6,1e-6,1e-6, 1e-7,1e-7,1e-7,
1138 1e-6,1e-6,1e-6, 1e-7,1e-7,1e-7,
1139 1e-3,1e-3,1e-3,1e-3, 1e-8,1e-8,1e-8,1e-8, 1e-4,
1140 1e-3,1e-3,1e-3,1e-3, 1e-8,1e-8,1e-8,1e-8, 1e-4
1147 # if defined(COMPARE_NUMERIC_JACOBIANS) 1148 const Eigen::Matrix<double,4,30> J_num=rje.
J;
1150 #endif // ---- end of numeric Jacobians ---- 1153 #if defined(COMPARE_NUMERIC_JACOBIANS) 1157 f.open(
"dbg.txt", ios_base::out | ios_base::app);
1158 f <<
"J_num:\n" << J_num << endl
1159 <<
"J_theor:\n" << J_theor << endl
1160 <<
"diff:\n" << J_num - J_theor << endl
1161 <<
"diff (ratio):\n" << (J_num - J_theor).cwiseQuotient(J_num) << endl << endl;
1173 check_size_x(7),check_size_y(9),
1174 check_squares_length_X_meters(0.02),check_squares_length_Y_meters(0.02),
1175 normalize_image(true),
1176 skipDrawDetectedImgs(false),
1179 optimize_k1(true), optimize_k2(true), optimize_k3(false),
1180 optimize_t1(false),optimize_t2(false),
1181 use_robust_kernel(false),
1182 robust_kernel_param(10),
1184 callback_user_param(NULL)
1191 final_number_good_image_pairs(0)
#define ASSERT_EQUAL_(__A, __B)
double final_rmse
Final reprojection square Root Mean Square Error (in pixels).
A pair (x,y) of pixel coordinates (subpixel resolution).
double x() const
Common members of all points & poses classes.
std::vector< TImageStereoCalibData > TCalibrationStereoImageList
A list of images, used in checkerBoardStereoCalibration.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
mrpt::utils::TStereoCamera cam_params
Recovered parameters of the stereo camera.
double p1() const
Get the value of the p1 distortion parameter.
std::vector< bool > image_pair_was_used
true if a checkerboard was correctly detected in both left/right images. false if it wasn't...
mrpt::utils::CImage img_original
This image will be automatically loaded from the file name passed to checkerBoardCameraCalibration.
A class for storing images as grayscale or RGB bitmaps.
unsigned int nImgsToProcess
Info for calibRound==-1.
bool VISION_IMPEXP findChessboardCorners(const mrpt::utils::CImage &img, std::vector< mrpt::utils::TPixelCoordf > &cornerCoords, unsigned int check_size_x, unsigned int check_size_y, bool normalize_image=true, bool useScaramuzzaMethod=false)
Look for the corners of a chessboard in the image using one of two different methods.
size_t final_number_good_image_pairs
Number of image pairs in which valid checkerboards were correctly detected.
void getSize(TImageSize &s) const
Return the size of the image.
void BASE_IMPEXP pause(const std::string &msg=std::string("Press any key to continue...")) MRPT_NO_THROWS
Shows the message "Press any key to continue" (or other custom message) to the current standard outpu...
A pair (x,y) of pixel coordinates (integer resolution).
double cy() const
Get the value of the principal point y-coordinate (in pixels).
mrpt::aligned_containers< mrpt::poses::CPose3D >::vector_t left_cam_poses
size_t final_iters
Final number of optimization iterations executed.
Eigen::Matrix< double, 4, 30 > J
Jacobian. 4=the two predicted pixels; 30=Read below for the meaning of these 30 variables.
void VISION_IMPEXP projectPoints_with_distortion(const std::vector< mrpt::math::TPoint3D > &in_points_3D, const mrpt::poses::CPose3D &cameraPose, const mrpt::math::CMatrixDouble33 &intrinsicParams, const std::vector< double > &distortionParams, std::vector< mrpt::utils::TPixelCoordf > &projectedPoints, bool accept_points_behind=false)
Project a set of 3D points into a camera at an arbitrary 6D pose using its calibration matrix and dis...
std::vector< mrpt::utils::TPixelCoordf > detected_corners
At output, the detected corners (x,y) in pixel units.
void jacob_dh_db_and_dh_dc(const TPoint3D &nP, const Eigen::Matrix< double, 9, 1 > &c, Eigen::Matrix< double, 2, 2 > &Hb, Eigen::Matrix< double, 2, 9 > &Hc)
double z
X,Y,Z coordinates.
const TCalibrationStereoImageList & images
Eigen::Matrix< double, 4, 1 > residual
= predicted_obs - observations
Data associated to each observation in the Lev-Marq.
void project_point(const mrpt::math::TPoint3D &P, const mrpt::utils::TCamera ¶ms, const CPose3D &cameraPose, mrpt::utils::TPixelCoordf &px)
mrpt::poses::CPose3D right2left_pose
Structure to hold the parameters of a pinhole stereo camera model.
T square(const T x)
Inline function for the square of a number.
double fx() const
Get the value of the focal length x-value (in pixels).
void skew_symmetric3_neg(const VECTOR &v, MATRIX &M)
Computes the negative version of a 3x3 skew symmetric matrix from a 3-vector or 3-array: ...
double fy() const
Get the value of the focal length y-value (in pixels).
void composePoint(double lx, double ly, double lz, double &gx, double &gy, double &gz, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacobian_df_dpoint=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dpose=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dse3=NULL, bool use_small_rot_approx=false) const
An alternative, slightly more efficient way of doing with G and L being 3D points and P this 6D pose...
Data associated to each image in the calibration process mrpt::vision::checkerBoardCameraCalibration ...
Eigen::Array< double, 9, 1 > right_params_inv_variance
This base provides a set of functions for maths stuff.
void build_linear_system(const TResidualJacobianList &res_jac, const vector_size_t &var_indxs, Eigen::VectorXd &minus_g, Eigen::MatrixXd &H)
double k1() const
Get the value of the k1 distortion parameter.
Input parameters for mrpt::vision::checkerBoardStereoCalibration.
mrpt::utils::CImage img_checkboard
At output, this will contain the detected checkerboard overprinted to the image.
mrpt::aligned_containers< mrpt::poses::CPose3D >::vector_t left_cam_poses
Poses of the origin of coordinates of the pattern wrt the left camera (i.e.
Params of the optional callback provided by the user.
void composeFrom(const CPose3D &A, const CPose3D &B)
Makes "this = A (+) B"; this method is slightly more efficient than "this= A + B;" since it avoids th...
double p2() const
Get the value of the p2 distortion parameter.
std::vector< mrpt::utils::TPixelCoordf > projectedPoints_distorted
At output, only will have an empty vector if the checkerboard was not found in this image...
TCamera rightCamera
Intrinsic and distortion parameters of the left and right cameras.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Classes for computer vision, detectors, features, etc.
bool isExternallyStored() const MRPT_NO_THROWS
See setExternalStorage().
const std::vector< mrpt::math::TPoint3D > & obj_points
A class used to store a 3D pose as a translation (x,y,z) and a quaternion (qr,qx,qy,qz).
void jacob_dA_eps_D_p_deps(const CPose3D &A, const CPose3D &D, const TPoint3D &p, Eigen::Matrix< double, 3, 6 > &dp_deps)
void jacob_deps_D_p_deps(const TPoint3D &p_D, Eigen::Matrix< double, 3, 6 > &dpl_del)
double cx() const
Get the value of the principal point x-coordinate (in pixels).
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
double recompute_errors_and_Jacobians(const lm_stat_t &lm_stat, TResidualJacobianList &res_jac, bool use_robust_kernel, double kernel_param)
const std::vector< size_t > & valid_image_pair_indices
Eigen::Matrix< double, 4, 1 > predicted_obs
[u_l v_l u_r v_r]: left/right camera pixels
bool VISION_IMPEXP checkerBoardStereoCalibration(TCalibrationStereoImageList &images, const TStereoCalibParams ¶ms, TStereoCalibResults &out_results)
Optimize the calibration parameters of a stereo camera or a RGB+D (Kinect) camera.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void jacob_db_dp(const TPoint3D &p, Eigen::Matrix< double, 2, 3 > &G)
double current_rmse
Current root-mean square reprojection error (in pixels)
GLdouble GLdouble GLdouble r
double k3() const
Get the value of the k3 distortion parameter.
unsigned int nImgsProcessed
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
mrpt::math::CArrayDouble< 9 > right_cam_params
uint32_t nrows
Camera resolution.
bool drawChessboardCorners(std::vector< TPixelCoordf > &cornerCoords, unsigned int check_size_x, unsigned int check_size_y, unsigned int lines_width=1, unsigned int circles_radius=4)
Draw onto this image the detected corners of a chessboard.
void add_lm_increment(const Eigen::VectorXd &eps, const vector_size_t &var_indxs, lm_stat_t &new_lm_stat)
A partial specialization of CArrayNumeric for double numbers.
mrpt::poses::CPose3D right2left_camera_pose
The pose of the left camera as seen from the right camera.
mrpt::math::CArrayDouble< 9 > left_cam_params
std::vector< size_t > vector_size_t
void jacob_numeric_estimate(const VECTORLIKE &x, void(*functor)(const VECTORLIKE &x, const USERPARAM &y, VECTORLIKE3 &out), const VECTORLIKE2 &increments, const USERPARAM &userParam, MATRIXLIKE &out_Jacobian)
Numerical estimation of the Jacobian of a user-supplied function - this template redirects to mrpt::m...
TPixelCoord TImageSize
A type for image sizes.
Eigen::Array< double, 9, 1 > left_params_inv_variance
The inverse variance (information/precision) of each of the 9 left/right camera parameters [fx fy cx ...
mrpt::utils::CImage img_rectified
At output, this will be the rectified image.
void colorImage(CImage &ret) const
Returns a RGB version of the grayscale image, or itself if it is already a RGB image.
double k2() const
Get the value of the k2 distortion parameter.
Output results for mrpt::vision::checkerBoardStereoCalibration.
void getRotationMatrix(mrpt::math::CMatrixDouble33 &ROT) const
Get the 3x3 rotation matrix.
std::vector< mrpt::aligned_containers< TResidJacobElement >::vector_t > TResidualJacobianList
mrpt::poses::CPose3D reconstructed_camera_pose
At output, the reconstructed pose of the camera.
int calibRound
=-1:Processing images; =0: Initial calib without distortion, =1: Calib of all parameters ...
GLenum const GLfloat * params
size_t getWidth() const MRPT_OVERRIDE
Returns the width of the image in pixels.
Structure to hold the parameters of a pinhole camera model.
size_t getHeight() const MRPT_OVERRIDE
Returns the height of the image in pixels.