From c82f65b096b90d80ea50be40afa826e7368d87a2 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 15 Mar 2021 15:48:15 +0100 Subject: Fix T86262: Tracking backwards fails after gap in track The issue was caused by a prediction algorithm detecting tracking the wrong way. Solved by passing tracking direction explicitly, so that prediction will always happen correctly regardless of the state of the Tracks context. --- intern/libmv/intern/track_region.cc | 14 ++++++++++++++ intern/libmv/intern/track_region.h | 6 ++++++ intern/libmv/libmv/autotrack/autotrack.cc | 15 ++++++++++++++- intern/libmv/libmv/autotrack/predict_tracks.cc | 18 ++++++++++++++---- intern/libmv/libmv/autotrack/predict_tracks.h | 20 +++++++++++++++++++- intern/libmv/libmv/tracking/track_region.cc | 3 ++- intern/libmv/libmv/tracking/track_region.h | 6 ++++++ 7 files changed, 75 insertions(+), 7 deletions(-) (limited to 'intern/libmv') diff --git a/intern/libmv/intern/track_region.cc b/intern/libmv/intern/track_region.cc index 334e331c7a8..f434906407b 100644 --- a/intern/libmv/intern/track_region.cc +++ b/intern/libmv/intern/track_region.cc @@ -39,6 +39,19 @@ using libmv::TrackRegionResult; namespace { +TrackRegionOptions::Direction convertDirection( + libmv_TrackRegionDirection direction) { + switch (direction) { + case LIBMV_TRACK_REGION_FORWARD: return TrackRegionOptions::FORWARD; + case LIBMV_TRACK_REGION_BACKWARD: return TrackRegionOptions::BACKWARD; + } + + LOG(FATAL) << "Unhandled tracking direction " << direction + << ", should never happen."; + + return TrackRegionOptions::FORWARD; +} + TrackRegionOptions::Mode convertMotionModelToMode(int motion_model) { switch (motion_model) { #define LIBMV_CONVERT(the_model) \ @@ -65,6 +78,7 @@ TrackRegionOptions::Mode convertMotionModelToMode(int motion_model) { void libmv_configureTrackRegionOptions( const libmv_TrackRegionOptions& options, TrackRegionOptions* track_region_options) { + track_region_options->direction = convertDirection(options.direction); track_region_options->mode = convertMotionModelToMode(options.motion_model); track_region_options->minimum_correlation = options.minimum_correlation; track_region_options->max_iterations = options.num_iterations; diff --git a/intern/libmv/intern/track_region.h b/intern/libmv/intern/track_region.h index 4566fe9bf0f..2f10105ccd5 100644 --- a/intern/libmv/intern/track_region.h +++ b/intern/libmv/intern/track_region.h @@ -24,7 +24,13 @@ extern "C" { #endif +typedef enum libmv_TrackRegionDirection { + LIBMV_TRACK_REGION_FORWARD, + LIBMV_TRACK_REGION_BACKWARD, +} libmv_TrackRegionDirection; + typedef struct libmv_TrackRegionOptions { + libmv_TrackRegionDirection direction; int motion_model; int num_iterations; int use_brute; diff --git a/intern/libmv/libmv/autotrack/autotrack.cc b/intern/libmv/libmv/autotrack/autotrack.cc index c18567a5f28..afdf48912e5 100644 --- a/intern/libmv/libmv/autotrack/autotrack.cc +++ b/intern/libmv/libmv/autotrack/autotrack.cc @@ -115,14 +115,27 @@ FrameAccessor::Key GetMaskForMarker(const Marker& marker, marker.clip, marker.frame, marker.track, ®ion, mask); } +PredictDirection getPredictDirection(const TrackRegionOptions* track_options) { + switch (track_options->direction) { + case TrackRegionOptions::FORWARD: return PredictDirection::FORWARD; + case TrackRegionOptions::BACKWARD: return PredictDirection::BACKWARD; + } + + LOG(FATAL) << "Unhandled tracking direction " << track_options->direction + << ", should never happen."; + + return PredictDirection::AUTO; +} + } // namespace bool AutoTrack::TrackMarker(Marker* tracked_marker, TrackRegionResult* result, const TrackRegionOptions* track_options) { // Try to predict the location of the second marker. + const PredictDirection predict_direction = getPredictDirection(track_options); bool predicted_position = false; - if (PredictMarkerPosition(tracks_, tracked_marker)) { + if (PredictMarkerPosition(tracks_, predict_direction, tracked_marker)) { LG << "Successfully predicted!"; predicted_position = true; } else { diff --git a/intern/libmv/libmv/autotrack/predict_tracks.cc b/intern/libmv/libmv/autotrack/predict_tracks.cc index d78b5b340f9..f3411066a07 100644 --- a/intern/libmv/libmv/autotrack/predict_tracks.cc +++ b/intern/libmv/libmv/autotrack/predict_tracks.cc @@ -225,7 +225,9 @@ void RunPrediction(const vector previous_markers, } // namespace -bool PredictMarkerPosition(const Tracks& tracks, Marker* marker) { +bool PredictMarkerPosition(const Tracks& tracks, + const PredictDirection direction, + Marker* marker) { // Get all markers for this clip and track. vector markers; tracks.GetMarkersForTrackInClip(marker->clip, marker->track, &markers); @@ -290,9 +292,17 @@ bool PredictMarkerPosition(const Tracks& tracks, Marker* marker) { } bool predict_forward = false; - if (backward_scan_end <= backward_scan_begin) { - // TODO(keir): Add smarter handling and detecting of consecutive frames! - predict_forward = true; + switch (direction) { + case PredictDirection::AUTO: + if (backward_scan_end <= backward_scan_begin) { + // TODO(keir): Add smarter handling and detecting of consecutive frames! + predict_forward = true; + } + break; + + case PredictDirection::FORWARD: predict_forward = true; break; + + case PredictDirection::BACKWARD: predict_forward = false; break; } const int max_frames_to_predict_from = 20; diff --git a/intern/libmv/libmv/autotrack/predict_tracks.h b/intern/libmv/libmv/autotrack/predict_tracks.h index 0a176d08378..108846ebc96 100644 --- a/intern/libmv/libmv/autotrack/predict_tracks.h +++ b/intern/libmv/libmv/autotrack/predict_tracks.h @@ -28,9 +28,27 @@ namespace mv { class Tracks; struct Marker; +enum class PredictDirection { + // Detect direction in which to predict marker position based on an existing + // Tracks context. Prediction will happen in the preferred direction of a + // missing information. + // If markers exists to the both sides of the given one the prediction + // direction is preferred to be forward. + AUTO, + + // Predict position of the marker from the past to the future (used for + // forward tracking). + FORWARD, + + // Predict position from the future to the past (used for backward tracking). + BACKWARD, +}; + // Predict the position of the given marker, and update it accordingly. The // existing position will be overwritten. -bool PredictMarkerPosition(const Tracks& tracks, Marker* marker); +bool PredictMarkerPosition(const Tracks& tracks, + const PredictDirection direction, + Marker* marker); } // namespace mv diff --git a/intern/libmv/libmv/tracking/track_region.cc b/intern/libmv/libmv/tracking/track_region.cc index 403b4088174..b9bd70e1405 100644 --- a/intern/libmv/libmv/tracking/track_region.cc +++ b/intern/libmv/libmv/tracking/track_region.cc @@ -116,7 +116,8 @@ using ceres::Jet; using ceres::JetOps; TrackRegionOptions::TrackRegionOptions() - : mode(TRANSLATION), + : direction(FORWARD), + mode(TRANSLATION), minimum_correlation(0), max_iterations(20), use_esm(true), diff --git a/intern/libmv/libmv/tracking/track_region.h b/intern/libmv/libmv/tracking/track_region.h index c4469f67b81..61d81413a29 100644 --- a/intern/libmv/libmv/tracking/track_region.h +++ b/intern/libmv/libmv/tracking/track_region.h @@ -30,6 +30,12 @@ namespace libmv { struct TrackRegionOptions { TrackRegionOptions(); + enum Direction { + FORWARD, + BACKWARD, + }; + Direction direction; + enum Mode { TRANSLATION, TRANSLATION_ROTATION, -- cgit v1.2.3