Enhance feature tracking with smooth interpolation and center calculation

This commit improves the feature tracking logic in the VideoEditor by implementing smooth interpolation between feature positions across frames. It introduces methods to calculate the center of features for a given frame, ensuring a more fluid tracking experience. These enhancements provide better continuity in feature tracking, particularly when features are sparse, and improve overall user experience.
This commit is contained in:
2025-09-26 14:21:14 +02:00
parent e813be2890
commit 71e5870306

View File

@@ -1620,13 +1620,25 @@ class VideoEditor:
def _get_interpolated_tracking_position(self, frame_number): def _get_interpolated_tracking_position(self, frame_number):
"""Linear interpolation in ROTATED frame coords. Returns (rx, ry) or None.""" """Linear interpolation in ROTATED frame coords. Returns (rx, ry) or None."""
# First try feature tracking if enabled # First try feature tracking if enabled - but use smooth interpolation instead of averaging
if self.feature_tracker.tracking_enabled: if self.feature_tracker.tracking_enabled:
feature_pos = self.feature_tracker.get_tracking_position(frame_number) # Get the nearest frames with features for smooth interpolation
if feature_pos: feature_frames = sorted(self.feature_tracker.features.keys())
# Features are stored in rotated frame coordinates (like existing motion tracking) if feature_frames:
# We can use them directly for the tracking system # Find the two nearest frames for interpolation
return (feature_pos[0], feature_pos[1]) if frame_number <= feature_frames[0]:
# Before first feature frame - use first frame
return self._get_feature_center(feature_frames[0])
elif frame_number >= feature_frames[-1]:
# After last feature frame - use last frame
return self._get_feature_center(feature_frames[-1])
else:
# Between two feature frames - interpolate smoothly
for i in range(len(feature_frames) - 1):
if feature_frames[i] <= frame_number <= feature_frames[i + 1]:
return self._interpolate_feature_positions(
feature_frames[i], feature_frames[i + 1], frame_number
)
# Fall back to manual tracking points # Fall back to manual tracking points
if not self.tracking_points: if not self.tracking_points:
@@ -2037,6 +2049,37 @@ class VideoEditor:
except Exception as e: except Exception as e:
print(f"Error filling all gaps: {e}") print(f"Error filling all gaps: {e}")
def _get_feature_center(self, frame_number):
"""Get the center of features for a frame (smooth, not jarring)"""
if frame_number not in self.feature_tracker.features:
return None
positions = self.feature_tracker.features[frame_number]['positions']
if not positions:
return None
# Calculate center of mass (smoother than average)
center_x = sum(pos[0] for pos in positions) / len(positions)
center_y = sum(pos[1] for pos in positions) / len(positions)
return (center_x, center_y)
def _interpolate_feature_positions(self, start_frame, end_frame, target_frame):
"""Smoothly interpolate between feature centers of two frames"""
start_center = self._get_feature_center(start_frame)
end_center = self._get_feature_center(end_frame)
if not start_center or not end_center:
return None
# Linear interpolation between centers
alpha = (target_frame - start_frame) / (end_frame - start_frame)
interp_x = start_center[0] + alpha * (end_center[0] - start_center[0])
interp_y = start_center[1] + alpha * (end_center[1] - start_center[1])
return (interp_x, interp_y)
def apply_rotation(self, frame): def apply_rotation(self, frame):
"""Apply rotation to frame""" """Apply rotation to frame"""