Enhance VideoEditor with motion path visualization for tracking points

This commit updates the VideoEditor class to visualize the motion path between previous and next tracking points using yellow arrows. The rendering of tracking points has been modified, with previous points displayed as red circles and next points as magenta circles, both with white borders for better visibility. The specification has been updated to reflect these changes in the display of tracking points and their motion direction.
This commit is contained in:
2025-09-17 14:31:35 +02:00
parent 615a3dce0d
commit 8c45b30bca
2 changed files with 45 additions and 11 deletions

View File

@@ -2090,29 +2090,63 @@ class VideoEditor:
cv2.circle(canvas, (sx, sy), 6, (255, 0, 0), -1)
cv2.circle(canvas, (sx, sy), 6, (255, 255, 255), 1)
# Draw previous and next tracking points with 50% alpha
# Draw previous and next tracking points with motion path visualization
if not self.is_image_mode and self.tracking_points:
# Previous tracking point (red) - from the most recent frame with tracking points before current
prev_result = self._get_previous_tracking_point()
next_result = self._get_next_tracking_point()
# Draw motion path if we have both previous and next points
if prev_result and next_result:
prev_frame, prev_pts = prev_result
next_frame, next_pts = next_result
# Draw lines between corresponding tracking points
for i, (prev_rx, prev_ry) in enumerate(prev_pts):
if i < len(next_pts):
next_rx, next_ry = next_pts[i]
prev_sx, prev_sy = self._map_rotated_to_screen(prev_rx, prev_ry)
next_sx, next_sy = self._map_rotated_to_screen(next_rx, next_ry)
# Draw motion path line with arrow (thin and transparent)
overlay = canvas.copy()
cv2.line(overlay, (prev_sx, prev_sy), (next_sx, next_sy), (255, 255, 0), 1) # Thin yellow line
# Draw arrow head pointing from previous to next
angle = np.arctan2(next_sy - prev_sy, next_sx - prev_sx)
arrow_length = 12
arrow_angle = np.pi / 6 # 30 degrees
# Calculate arrow head points
arrow_x1 = int(next_sx - arrow_length * np.cos(angle - arrow_angle))
arrow_y1 = int(next_sy - arrow_length * np.sin(angle - arrow_angle))
arrow_x2 = int(next_sx - arrow_length * np.cos(angle + arrow_angle))
arrow_y2 = int(next_sy - arrow_length * np.sin(angle + arrow_angle))
cv2.line(overlay, (next_sx, next_sy), (arrow_x1, arrow_y1), (255, 255, 0), 1)
cv2.line(overlay, (next_sx, next_sy), (arrow_x2, arrow_y2), (255, 255, 0), 1)
cv2.addWeighted(overlay, 0.3, canvas, 0.7, 0, canvas) # Very transparent
# Previous tracking point (red) - from the most recent frame with tracking points before current
if prev_result:
prev_frame, prev_pts = prev_result
for (rx, ry) in prev_pts:
sx, sy = self._map_rotated_to_screen(rx, ry)
# Create overlay for alpha blending
# Create overlay for alpha blending (more transparent)
overlay = canvas.copy()
cv2.circle(overlay, (sx, sy), 4, (0, 0, 255), -1) # Red circle
cv2.addWeighted(overlay, 0.5, canvas, 0.5, 0, canvas)
cv2.circle(overlay, (sx, sy), 5, (0, 0, 255), -1) # Red circle
cv2.circle(overlay, (sx, sy), 5, (255, 255, 255), 1) # White border
cv2.addWeighted(overlay, 0.4, canvas, 0.6, 0, canvas) # More transparent
# Next tracking point (green) - from the next frame with tracking points after current
next_result = self._get_next_tracking_point()
# Next tracking point (magenta/purple) - from the next frame with tracking points after current
if next_result:
next_frame, next_pts = next_result
for (rx, ry) in next_pts:
sx, sy = self._map_rotated_to_screen(rx, ry)
# Create overlay for alpha blending
# Create overlay for alpha blending (more transparent)
overlay = canvas.copy()
cv2.circle(overlay, (sx, sy), 4, (0, 255, 0), -1) # Green circle
cv2.addWeighted(overlay, 0.5, canvas, 0.5, 0, canvas)
cv2.circle(overlay, (sx, sy), 5, (255, 0, 255), -1) # Magenta circle
cv2.circle(overlay, (sx, sy), 5, (255, 255, 255), 1) # White border
cv2.addWeighted(overlay, 0.4, canvas, 0.6, 0, canvas) # More transparent
if self.tracking_enabled and not self.is_image_mode:
interp = self._get_interpolated_tracking_position(self.current_frame)
if interp:

View File

@@ -63,7 +63,7 @@ Be careful to save and load settings when navigating this way
- **Blue cross**: Shows computed tracking position
- **Automatic interpolation**: Tracks between keyframes
- **Crop follows**: Crop area centers on tracked object
- **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
- **Display** Points are rendered as blue dots per frame, in addition the previous tracking point (red) and next tracking point (magenta) are shown with yellow arrows indicating motion direction
#### Motion Tracking Navigation
- **,**: Jump to previous tracking marker (previous frame that has one or more tracking points). Wrap-around supported.