Implement methods for retrieving previous and next tracking points in VideoEditor

This commit introduces two new methods, _get_previous_tracking_point and _get_next_tracking_point, to the VideoEditor class. These methods allow for the retrieval of tracking points from the previous and next frames that contain tracking data, enhancing navigation capabilities. The rendering logic has been updated to utilize these methods, ensuring that the previous (red) and next (green) tracking points are displayed correctly during video playback. Additionally, the specification has been updated to reflect these changes in the display of tracking points.
This commit is contained in:
2025-09-17 14:29:11 +02:00
parent 1ce05d33ba
commit 615a3dce0d
2 changed files with 44 additions and 10 deletions

View File

@@ -1102,6 +1102,40 @@ class VideoEditor:
print(f"DEBUG: Jump next tracking wrap from {current} -> {tracking_frames[0]}; tracking_frames={tracking_frames}") print(f"DEBUG: Jump next tracking wrap from {current} -> {tracking_frames[0]}; tracking_frames={tracking_frames}")
self.seek_to_frame(tracking_frames[0]) self.seek_to_frame(tracking_frames[0])
def _get_previous_tracking_point(self):
"""Get the tracking point from the previous frame that has tracking points."""
if self.is_image_mode or not self.tracking_points:
return None
tracking_frames = sorted(k for k, v in self.tracking_points.items() if v and 0 <= k < self.total_frames)
if not tracking_frames:
return None
# Find the last frame with tracking points that's before current frame
prev_frames = [f for f in tracking_frames if f < self.current_frame]
if not prev_frames:
return None
prev_frame = max(prev_frames)
return prev_frame, self.tracking_points[prev_frame]
def _get_next_tracking_point(self):
"""Get the tracking point from the next frame that has tracking points."""
if self.is_image_mode or not self.tracking_points:
return None
tracking_frames = sorted(k for k, v in self.tracking_points.items() if v and 0 <= k < self.total_frames)
if not tracking_frames:
return None
# Find the first frame with tracking points that's after current frame
next_frames = [f for f in tracking_frames if f > self.current_frame]
if not next_frames:
return None
next_frame = min(next_frames)
return next_frame, self.tracking_points[next_frame]
def advance_frame(self) -> bool: def advance_frame(self) -> bool:
"""Advance to next frame - handles playback speed and marker looping""" """Advance to next frame - handles playback speed and marker looping"""
if not self.is_playing: if not self.is_playing:
@@ -2056,12 +2090,12 @@ class VideoEditor:
cv2.circle(canvas, (sx, sy), 6, (255, 0, 0), -1) cv2.circle(canvas, (sx, sy), 6, (255, 0, 0), -1)
cv2.circle(canvas, (sx, sy), 6, (255, 255, 255), 1) cv2.circle(canvas, (sx, sy), 6, (255, 255, 255), 1)
# Draw previous and next frame tracking points with 50% alpha # Draw previous and next tracking points with 50% alpha
if not self.is_image_mode and self.tracking_points: if not self.is_image_mode and self.tracking_points:
# Previous frame tracking points (red) # Previous tracking point (red) - from the most recent frame with tracking points before current
prev_frame = self.current_frame - 1 prev_result = self._get_previous_tracking_point()
if prev_frame in self.tracking_points: if prev_result:
prev_pts = self.tracking_points[prev_frame] prev_frame, prev_pts = prev_result
for (rx, ry) in prev_pts: for (rx, ry) in prev_pts:
sx, sy = self._map_rotated_to_screen(rx, ry) sx, sy = self._map_rotated_to_screen(rx, ry)
# Create overlay for alpha blending # Create overlay for alpha blending
@@ -2069,10 +2103,10 @@ class VideoEditor:
cv2.circle(overlay, (sx, sy), 4, (0, 0, 255), -1) # Red circle cv2.circle(overlay, (sx, sy), 4, (0, 0, 255), -1) # Red circle
cv2.addWeighted(overlay, 0.5, canvas, 0.5, 0, canvas) cv2.addWeighted(overlay, 0.5, canvas, 0.5, 0, canvas)
# Next frame tracking points (green) # Next tracking point (green) - from the next frame with tracking points after current
next_frame = self.current_frame + 1 next_result = self._get_next_tracking_point()
if next_frame in self.tracking_points: if next_result:
next_pts = self.tracking_points[next_frame] next_frame, next_pts = next_result
for (rx, ry) in next_pts: for (rx, ry) in next_pts:
sx, sy = self._map_rotated_to_screen(rx, ry) sx, sy = self._map_rotated_to_screen(rx, ry)
# Create overlay for alpha blending # Create overlay for alpha blending

View File

@@ -63,7 +63,7 @@ Be careful to save and load settings when navigating this way
- **Blue cross**: Shows computed tracking position - **Blue cross**: Shows computed tracking position
- **Automatic interpolation**: Tracks between keyframes - **Automatic interpolation**: Tracks between keyframes
- **Crop follows**: Crop area centers on tracked object - **Crop follows**: Crop area centers on tracked object
- **Display** Points are rendered as blue dots per frame, in addition dots are rendered on each frame for each dot on the previous (in red) and next (in green) frame - **Display** Points are rendered as blue dots per frame, in addition the previous tracking point (red) and next tracking point (green) are shown regardless of which frame they're on
#### Motion Tracking Navigation #### Motion Tracking Navigation
- **,**: Jump to previous tracking marker (previous frame that has one or more tracking points). Wrap-around supported. - **,**: Jump to previous tracking marker (previous frame that has one or more tracking points). Wrap-around supported.