From 47ec7fed044d62c290a7130be5394bb19c315eaa Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Wed, 17 Sep 2025 10:39:55 +0200 Subject: [PATCH] Enhance VideoEditor with previous and next frame tracking point visualization This commit adds functionality to the VideoEditor class to render tracking points from the previous and next frames with 50% alpha blending. Red circles indicate previous frame points, while green circles represent next frame points, improving the visual feedback during video editing. Additionally, the feedback message duration has been reduced for a more responsive user experience. --- croppa/main.py | 36 ++++++++++++++++++++++++++++++------ croppa/spec.md | 1 + 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/croppa/main.py b/croppa/main.py index d8ddc81..7523421 100644 --- a/croppa/main.py +++ b/croppa/main.py @@ -7,10 +7,10 @@ from pathlib import Path from typing import List import time import re -import json import threading -import queue +import json import subprocess +import queue import ctypes class Cv2BufferedCap: @@ -581,7 +581,7 @@ class VideoEditor: # Feedback message state self.feedback_message = "" self.feedback_message_time = None - self.feedback_message_duration = 0.5 # seconds to show message + self.feedback_message_duration = 0.2 # seconds to show message # Crop adjustment settings self.crop_size_step = self.CROP_SIZE_STEP @@ -1997,8 +1997,32 @@ class VideoEditor: pts = self.tracking_points.get(self.current_frame, []) if not self.is_image_mode else [] for (rx, ry) in pts: sx, sy = self._map_rotated_to_screen(rx, ry) - cv2.circle(canvas, (sx, sy), 6, (0, 255, 0), -1) + cv2.circle(canvas, (sx, sy), 6, (255, 0, 0), -1) cv2.circle(canvas, (sx, sy), 6, (255, 255, 255), 1) + + # Draw previous and next frame tracking points with 50% alpha + if not self.is_image_mode and self.tracking_points: + # Previous frame tracking points (red) + prev_frame = self.current_frame - 1 + if prev_frame in self.tracking_points: + prev_pts = self.tracking_points[prev_frame] + for (rx, ry) in prev_pts: + sx, sy = self._map_rotated_to_screen(rx, ry) + # Create overlay for alpha blending + 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) + + # Next frame tracking points (green) + next_frame = self.current_frame + 1 + if next_frame in self.tracking_points: + next_pts = self.tracking_points[next_frame] + for (rx, ry) in next_pts: + sx, sy = self._map_rotated_to_screen(rx, ry) + # Create overlay for alpha blending + 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) if self.tracking_enabled and not self.is_image_mode: interp = self._get_interpolated_tracking_position(self.current_frame) if interp: @@ -2089,12 +2113,12 @@ class VideoEditor: del self.tracking_points[self.current_frame][idx] if not self.tracking_points[self.current_frame]: del self.tracking_points[self.current_frame] - self.show_feedback_message("Tracking point removed") + # self.show_feedback_message("Tracking point removed") removed = True break if not removed: self.tracking_points.setdefault(self.current_frame, []).append((int(rx), int(ry))) - self.show_feedback_message("Tracking point added") + # self.show_feedback_message("Tracking point added") self.clear_transformation_cache() self.save_state() diff --git a/croppa/spec.md b/croppa/spec.md index 58d9135..2ebff37 100644 --- a/croppa/spec.md +++ b/croppa/spec.md @@ -55,6 +55,7 @@ That coordinate is to be mapped to the bottom left corner of the original raw un - **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 dots are rendered on each frame for each dot on the previous (in red) and next (in green) frame ### Markers and Looping - **1**: Set cut start marker at current frame