139 FilterZeroWeightMarkersFromTracks(_tracks, &filtered_tracks);
141 int max_image = filtered_tracks.
MaxImage();
142 int next_keyframe = 1;
149 const double Tmin = 0.8;
150 const double Tmax = 1.0;
152 Mat3 N = IntrinsicsNormalizationMatrix(intrinsics);
153 Mat3 N_inverse =
N.inverse();
155 double Sc_best = std::numeric_limits<double>::max();
156 double success_intersects_factor_best = 0.0f;
158 while (next_keyframe != -1) {
159 int current_keyframe = next_keyframe;
160 double Sc_best_candidate = std::numeric_limits<double>::max();
162 LG <<
"Found keyframe " << next_keyframe;
166 for (
int candidate_image = current_keyframe + 1;
167 candidate_image <= max_image;
171 current_keyframe, candidate_image);
183 LG <<
"Found " << x1.cols() <<
" correspondences between "
184 << current_keyframe <<
" and " << candidate_image;
187 if (x1.cols() < 8 || x2.cols() < 8) {
192 int Tc = tracked_markers.size();
193 int Tf = all_markers.size();
194 double Rc =
static_cast<double>(Tc) / Tf;
196 LG <<
"Correspondence between " << current_keyframe <<
" and "
197 << candidate_image <<
": " << Rc;
199 if (Rc < Tmin || Rc > Tmax) {
208 x1, x2, estimate_homography_options, &
H);
211 H = N_inverse *
H *
N;
215 x1, x2, estimate_fundamental_options, &F);
218 F = N_inverse * F *
N;
226 H_e.resize(x1.cols());
227 F_e.resize(x1.cols());
228 for (
int i = 0; i < x1.cols(); i++) {
229 Vec2 current_x1, current_x2;
232 x1(0, i), x1(1, i), ¤t_x1(0), ¤t_x1(1));
235 x2(0, i), x2(1, i), ¤t_x2(0), ¤t_x2(1));
241 LG <<
"H_e: " << H_e.transpose();
242 LG <<
"F_e: " << F_e.transpose();
245 double GRIC_H = GRIC(H_e, 2, 8, 4);
246 double GRIC_F = GRIC(F_e, 3, 7, 4);
248 LG <<
"GRIC values for frames " << current_keyframe <<
" and "
249 << candidate_image <<
", H-GRIC: " << GRIC_H <<
", F-GRIC: " << GRIC_F;
251 if (GRIC_H <= GRIC_F) {
276 Mat3 F_normal =
N * F * N_inverse;
285 Mat3 K = Mat3::Identity();
288 E,
K, x1.col(0),
K, x2.col(0), &
R, &t)) {
289 LG <<
"Failed to compute R and t from E and K";
293 LG <<
"Camera transform between frames " << current_keyframe <<
" and "
294 << candidate_image <<
":\nR:\n"
295 <<
R <<
"\nt:" << t.transpose();
299 current_keyframe, Mat3::Identity(), Vec3::Zero());
303 int intersects_total = 0, intersects_success = 0;
304 for (
int i = 0; i < tracked_markers.size(); i++) {
308 int track = tracked_markers[i].track;
310 reconstructed_markers.push_back(tracked_markers[i]);
318 for (
int j = i + 1; j < tracked_markers.size(); j++) {
319 if (tracked_markers[j].track == track) {
320 reconstructed_markers.push_back(tracked_markers[j]);
328 LG <<
"Ran Intersect() for track " << track;
329 intersects_success++;
331 LG <<
"Filed to intersect track " << track;
336 double success_intersects_factor =
337 double(intersects_success) / intersects_total;
339 if (success_intersects_factor < success_intersects_factor_best) {
340 LG <<
"Skip keyframe candidate because of "
341 "lower successful intersections ratio";
346 success_intersects_factor_best = success_intersects_factor;
348 Tracks two_frames_tracks(tracked_markers);
360 Mat& jacobian = evaluation.jacobian;
362 Mat JT_J = jacobian.transpose() * jacobian;
364 Mat JT_J_inv = PseudoInverseWithClampedEigenvalues(JT_J, 7);
366 Mat temp_derived = JT_J * JT_J_inv * JT_J;
367 bool is_inversed = (temp_derived - JT_J).cwiseAbs2().sum() <
368 1
e-4 * std::min(temp_derived.cwiseAbs2().sum(),
369 JT_J.cwiseAbs2().sum());
371 LG <<
"Check on inversed: " << (is_inversed ?
"true" :
"false")
372 <<
", det(JT_J): " << JT_J.determinant();
375 LG <<
"Ignoring candidature due to poor jacobian stability";
380 Sigma_P = JT_J_inv.bottomRightCorner(evaluation.num_points * 3,
381 evaluation.num_points * 3);
383 int I = evaluation.num_points;
386 double Sc =
static_cast<double>(
I +
A) /
Square(3 *
I) * Sigma_P.trace();
388 LG <<
"Expected estimation error between " << current_keyframe <<
" and "
389 << candidate_image <<
": " << Sc;
392 if (Sc > Sc_best_candidate) {
396 Sc_best_candidate = Sc;
398 next_keyframe = candidate_image;
409 if (next_keyframe == -1) {
410 next_keyframe = current_keyframe + 10;
412 if (next_keyframe >= max_image) {
416 LG <<
"Starting searching for keyframes starting from " << next_keyframe;
425 if (Sc_best > Sc_best_candidate) {
427 keyframes.push_back(current_keyframe);
428 keyframes.push_back(next_keyframe);
429 Sc_best = Sc_best_candidate;