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):
"""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:
feature_pos = self.feature_tracker.get_tracking_position(frame_number)
if feature_pos:
# Features are stored in rotated frame coordinates (like existing motion tracking)
# We can use them directly for the tracking system
return (feature_pos[0], feature_pos[1])
# Get the nearest frames with features for smooth interpolation
feature_frames = sorted(self.feature_tracker.features.keys())
if feature_frames:
# Find the two nearest frames for interpolation
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
if not self.tracking_points:
@@ -2037,6 +2049,37 @@ class VideoEditor:
except Exception as 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):
"""Apply rotation to frame"""