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:
2025-09-26 14:19:42 +02:00
parent 80fb35cced
commit e813be2890

View File

@@ -202,15 +202,21 @@ class FeatureTracker:
def get_tracking_position(self, frame_number: int) -> Optional[Tuple[float, float]]: def get_tracking_position(self, frame_number: int) -> Optional[Tuple[float, float]]:
"""Get the average tracking position for a frame""" """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 return None
positions = self.features[frame_number]['positions'] positions = self.features[frame_number]['positions']
if not positions: if not positions:
return None return None
# Calculate average position
avg_x = sum(pos[0] for pos in positions) / len(positions) avg_x = sum(pos[0] for pos in positions) / len(positions)
avg_y = sum(pos[1] for pos in positions) / len(positions) avg_y = sum(pos[1] for pos in positions) / len(positions)
return (avg_x, avg_y) return (avg_x, avg_y)
@@ -1334,9 +1340,20 @@ class VideoEditor:
def seek_to_frame(self, frame_number: int): def seek_to_frame(self, frame_number: int):
"""Seek to specific frame""" """Seek to specific frame"""
old_frame = self.current_frame
self.current_frame = max(0, min(frame_number, self.total_frames - 1)) self.current_frame = max(0, min(frame_number, self.total_frames - 1))
self.load_current_frame() 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 # 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}") 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): def _interpolate_features_between_frames(self, start_frame, end_frame):
"""Interpolate features between two frames using linear interpolation""" """Interpolate features between two frames using linear interpolation"""
try: 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: 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 return
start_features = self.feature_tracker.features[start_frame]['positions'] start_features = self.feature_tracker.features[start_frame]['positions']
end_features = self.feature_tracker.features[end_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): if len(start_features) != len(end_features):
print(f"DEBUG: Feature count mismatch between frames {start_frame} and {end_frame}") print(f"DEBUG: Feature count mismatch between frames {start_frame} and {end_frame} ({len(start_features)} vs {len(end_features)})")
return 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 # Interpolate for all frames between start and end
frames_to_interpolate = []
for frame_num in range(start_frame + 1, end_frame): for frame_num in range(start_frame + 1, end_frame):
if frame_num in self.feature_tracker.features: if frame_num in self.feature_tracker.features:
print(f"DEBUG: Frame {frame_num} already has features, skipping")
continue # Skip if already has features 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 # Linear interpolation
alpha = (frame_num - start_frame) / (end_frame - start_frame) alpha = (frame_num - start_frame) / (end_frame - start_frame)
interpolated_positions = [] interpolated_positions = []
@@ -1966,6 +1999,8 @@ class VideoEditor:
} }
print(f"DEBUG: Interpolated {len(interpolated_positions)} features for frame {frame_num}") 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: except Exception as e:
print(f"Error interpolating features: {e}") print(f"Error interpolating features: {e}")
@@ -1973,6 +2008,9 @@ class VideoEditor:
def _fill_all_gaps_with_interpolation(self): def _fill_all_gaps_with_interpolation(self):
"""Fill all gaps between existing features with linear interpolation""" """Fill all gaps between existing features with linear interpolation"""
try: try:
print("=== FILLING ALL GAPS WITH INTERPOLATION ===")
print(f"DEBUG: Total features stored: {len(self.feature_tracker.features)}")
if not self.feature_tracker.features: if not self.feature_tracker.features:
print("DEBUG: No features to interpolate between") print("DEBUG: No features to interpolate between")
return return
@@ -1993,7 +2031,8 @@ class VideoEditor:
print(f"DEBUG: Interpolating between frame {start_frame} and {end_frame}") print(f"DEBUG: Interpolating between frame {start_frame} and {end_frame}")
self._interpolate_features_between_frames(start_frame, 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: except Exception as e:
print(f"Error filling all gaps: {e}") print(f"Error filling all gaps: {e}")