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