Refactor tracking position calculation in VideoEditor to combine manual, template, and feature tracking methods. This update introduces a more robust approach to determine the final tracking position by calculating offsets from both template matching and feature tracking, weighted appropriately against a base position derived from manual tracking points. The logic ensures smoother transitions and improved accuracy in tracking results, with debug messages added for better insight into the combined tracking process.

This commit is contained in:
2025-09-26 14:44:19 +02:00
parent f8acef2da4
commit 5d76681ded

View File

@@ -1637,7 +1637,11 @@ 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 template matching if enabled (much better than optical flow) # Get base position from manual tracking points
base_pos = self._get_manual_tracking_position(frame_number)
# Calculate offset from template matching if enabled
template_offset = None
if self.template_matching_enabled and self.tracking_template is not None: if self.template_matching_enabled and self.tracking_template is not None:
if self.current_display_frame is not None: if self.current_display_frame is not None:
# Use only the cropped region for much faster template matching # Use only the cropped region for much faster template matching
@@ -1657,7 +1661,7 @@ class VideoEditor:
raw_x = center_x + crop_x raw_x = center_x + crop_x
raw_y = center_y + crop_y raw_y = center_y + crop_y
return (raw_x, raw_y) template_offset = (raw_x, raw_y)
else: else:
# No crop - use full frame # No crop - use full frame
raw_frame = self.current_display_frame.copy() raw_frame = self.current_display_frame.copy()
@@ -1668,9 +1672,10 @@ class VideoEditor:
print(f"DEBUG: Template match found at ({center_x}, {center_y}) with confidence {confidence:.2f}") print(f"DEBUG: Template match found at ({center_x}, {center_y}) with confidence {confidence:.2f}")
# Template matching returns coordinates in raw frame space # Template matching returns coordinates in raw frame space
return (center_x, center_y) template_offset = (center_x, center_y)
# Fall back to feature tracking if enabled - but use smooth interpolation instead of averaging # Calculate offset from feature tracking if enabled
feature_offset = None
if self.feature_tracker.tracking_enabled: if self.feature_tracker.tracking_enabled:
# Get the nearest frames with features for smooth interpolation # Get the nearest frames with features for smooth interpolation
feature_frames = sorted(self.feature_tracker.features.keys()) feature_frames = sorted(self.feature_tracker.features.keys())
@@ -1678,19 +1683,55 @@ class VideoEditor:
# Find the two nearest frames for interpolation # Find the two nearest frames for interpolation
if frame_number <= feature_frames[0]: if frame_number <= feature_frames[0]:
# Before first feature frame - use first frame # Before first feature frame - use first frame
return self._get_feature_center(feature_frames[0]) feature_offset = self._get_feature_center(feature_frames[0])
elif frame_number >= feature_frames[-1]: elif frame_number >= feature_frames[-1]:
# After last feature frame - use last frame # After last feature frame - use last frame
return self._get_feature_center(feature_frames[-1]) feature_offset = self._get_feature_center(feature_frames[-1])
else: else:
# Between two feature frames - interpolate smoothly # Between two feature frames - interpolate smoothly
for i in range(len(feature_frames) - 1): for i in range(len(feature_frames) - 1):
if feature_frames[i] <= frame_number <= feature_frames[i + 1]: if feature_frames[i] <= frame_number <= feature_frames[i + 1]:
return self._interpolate_feature_positions( feature_offset = self._interpolate_feature_positions(
feature_frames[i], feature_frames[i + 1], frame_number feature_frames[i], feature_frames[i + 1], frame_number
) )
break
# Fall back to manual tracking points # Combine tracking methods: base + offsets
if base_pos:
base_x, base_y = base_pos
offset_x, offset_y = 0, 0
# Add template matching offset
if template_offset:
template_x, template_y = template_offset
# Calculate offset from base position
offset_x += (template_x - base_x) * 0.5 # Weight template matching
offset_y += (template_y - base_y) * 0.5
# Add feature tracking offset
if feature_offset:
feature_x, feature_y = feature_offset
# Calculate offset from base position
offset_x += (feature_x - base_x) * 0.3 # Weight feature tracking
offset_y += (feature_y - base_y) * 0.3
# Apply combined offset
final_x = base_x + offset_x
final_y = base_y + offset_y
print(f"DEBUG: Combined tracking - Base: ({base_x:.1f}, {base_y:.1f}) + Offset: ({offset_x:.1f}, {offset_y:.1f}) = Final: ({final_x:.1f}, {final_y:.1f})")
return (final_x, final_y)
# Fall back to individual tracking methods if no base position
if template_offset:
return template_offset
elif feature_offset:
return feature_offset
else:
return None
def _get_manual_tracking_position(self, frame_number):
"""Get manual tracking position for a frame"""
if not self.tracking_points: if not self.tracking_points:
return None return None
frames = sorted(self.tracking_points.keys()) frames = sorted(self.tracking_points.keys())