Improve feature tracking logic and debugging in VideoEditor
This commit refines the feature tracking process by enhancing the get_tracking_position method to handle cases where frame features are missing. It also adds detailed debug messages throughout the VideoEditor class, particularly during frame seeking and feature interpolation, to provide better insights into the feature availability and interpolation process. These changes improve the robustness and user experience of the feature tracking functionality.
This commit is contained in:
@@ -202,15 +202,21 @@ class FeatureTracker:
|
||||
|
||||
def get_tracking_position(self, frame_number: int) -> Optional[Tuple[float, float]]:
|
||||
"""Get the average tracking position for a frame"""
|
||||
if frame_number not in self.features or not self.features[frame_number]['positions']:
|
||||
if frame_number not in self.features:
|
||||
return None
|
||||
|
||||
if not self.features[frame_number]['positions']:
|
||||
return None
|
||||
|
||||
positions = self.features[frame_number]['positions']
|
||||
|
||||
if not positions:
|
||||
return None
|
||||
|
||||
# Calculate average position
|
||||
avg_x = sum(pos[0] for pos in positions) / len(positions)
|
||||
avg_y = sum(pos[1] for pos in positions) / len(positions)
|
||||
|
||||
return (avg_x, avg_y)
|
||||
|
||||
|
||||
@@ -1334,9 +1340,20 @@ class VideoEditor:
|
||||
|
||||
def seek_to_frame(self, frame_number: int):
|
||||
"""Seek to specific frame"""
|
||||
old_frame = self.current_frame
|
||||
self.current_frame = max(0, min(frame_number, self.total_frames - 1))
|
||||
self.load_current_frame()
|
||||
|
||||
# Only log when we actually change frames
|
||||
if old_frame != self.current_frame:
|
||||
print(f"DEBUG: === LOADED NEW FRAME {self.current_frame} ===")
|
||||
print(f"DEBUG: Features available for frames: {sorted(self.feature_tracker.features.keys())}")
|
||||
if self.current_frame in self.feature_tracker.features:
|
||||
feature_count = len(self.feature_tracker.features[self.current_frame]['positions'])
|
||||
print(f"DEBUG: Frame {self.current_frame} has {feature_count} features")
|
||||
else:
|
||||
print(f"DEBUG: Frame {self.current_frame} has NO features")
|
||||
|
||||
# Auto-extract features if feature tracking is enabled and auto-tracking is on
|
||||
print(f"DEBUG: seek_to_frame {frame_number}: is_image_mode={self.is_image_mode}, tracking_enabled={self.feature_tracker.tracking_enabled}, auto_tracking={self.feature_tracker.auto_tracking}, display_frame={self.current_display_frame is not None}")
|
||||
|
||||
@@ -1930,21 +1947,37 @@ class VideoEditor:
|
||||
def _interpolate_features_between_frames(self, start_frame, end_frame):
|
||||
"""Interpolate features between two frames using linear interpolation"""
|
||||
try:
|
||||
print(f"DEBUG: Starting interpolation between frame {start_frame} and {end_frame}")
|
||||
|
||||
if start_frame not in self.feature_tracker.features or end_frame not in self.feature_tracker.features:
|
||||
print(f"DEBUG: Missing features on start_frame={start_frame} or end_frame={end_frame}")
|
||||
return
|
||||
|
||||
start_features = self.feature_tracker.features[start_frame]['positions']
|
||||
end_features = self.feature_tracker.features[end_frame]['positions']
|
||||
|
||||
print(f"DEBUG: Start frame {start_frame} has {len(start_features)} features")
|
||||
print(f"DEBUG: End frame {end_frame} has {len(end_features)} features")
|
||||
|
||||
if len(start_features) != len(end_features):
|
||||
print(f"DEBUG: Feature count mismatch between frames {start_frame} and {end_frame}")
|
||||
return
|
||||
print(f"DEBUG: Feature count mismatch between frames {start_frame} and {end_frame} ({len(start_features)} vs {len(end_features)})")
|
||||
print(f"DEBUG: Using minimum count for interpolation")
|
||||
# Use the minimum count to avoid index errors
|
||||
min_count = min(len(start_features), len(end_features))
|
||||
start_features = start_features[:min_count]
|
||||
end_features = end_features[:min_count]
|
||||
|
||||
# Interpolate for all frames between start and end
|
||||
frames_to_interpolate = []
|
||||
for frame_num in range(start_frame + 1, end_frame):
|
||||
if frame_num in self.feature_tracker.features:
|
||||
print(f"DEBUG: Frame {frame_num} already has features, skipping")
|
||||
continue # Skip if already has features
|
||||
frames_to_interpolate.append(frame_num)
|
||||
|
||||
print(f"DEBUG: Will interpolate {len(frames_to_interpolate)} frames: {frames_to_interpolate}")
|
||||
|
||||
for frame_num in frames_to_interpolate:
|
||||
# Linear interpolation
|
||||
alpha = (frame_num - start_frame) / (end_frame - start_frame)
|
||||
interpolated_positions = []
|
||||
@@ -1967,12 +2000,17 @@ class VideoEditor:
|
||||
|
||||
print(f"DEBUG: Interpolated {len(interpolated_positions)} features for frame {frame_num}")
|
||||
|
||||
print(f"DEBUG: Finished interpolation between frame {start_frame} and {end_frame}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error interpolating features: {e}")
|
||||
|
||||
def _fill_all_gaps_with_interpolation(self):
|
||||
"""Fill all gaps between existing features with linear interpolation"""
|
||||
try:
|
||||
print("=== FILLING ALL GAPS WITH INTERPOLATION ===")
|
||||
print(f"DEBUG: Total features stored: {len(self.feature_tracker.features)}")
|
||||
|
||||
if not self.feature_tracker.features:
|
||||
print("DEBUG: No features to interpolate between")
|
||||
return
|
||||
@@ -1993,7 +2031,8 @@ class VideoEditor:
|
||||
print(f"DEBUG: Interpolating between frame {start_frame} and {end_frame}")
|
||||
self._interpolate_features_between_frames(start_frame, end_frame)
|
||||
|
||||
print("DEBUG: Finished filling all gaps with interpolation")
|
||||
print(f"DEBUG: After interpolation, total features stored: {len(self.feature_tracker.features)}")
|
||||
print("=== FINISHED FILLING ALL GAPS ===")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error filling all gaps: {e}")
|
||||
|
Reference in New Issue
Block a user