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:
@@ -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())
|
||||||
|
Reference in New Issue
Block a user