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.
This commit is contained in:
@@ -7,10 +7,10 @@ from pathlib import Path
|
|||||||
from typing import List
|
from typing import List
|
||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
import json
|
|
||||||
import threading
|
import threading
|
||||||
import queue
|
import json
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import queue
|
||||||
import ctypes
|
import ctypes
|
||||||
|
|
||||||
class Cv2BufferedCap:
|
class Cv2BufferedCap:
|
||||||
@@ -581,7 +581,7 @@ class VideoEditor:
|
|||||||
# Feedback message state
|
# Feedback message state
|
||||||
self.feedback_message = ""
|
self.feedback_message = ""
|
||||||
self.feedback_message_time = None
|
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
|
# Crop adjustment settings
|
||||||
self.crop_size_step = self.CROP_SIZE_STEP
|
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 []
|
pts = self.tracking_points.get(self.current_frame, []) if not self.is_image_mode else []
|
||||||
for (rx, ry) in pts:
|
for (rx, ry) in pts:
|
||||||
sx, sy = self._map_rotated_to_screen(rx, ry)
|
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)
|
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:
|
if self.tracking_enabled and not self.is_image_mode:
|
||||||
interp = self._get_interpolated_tracking_position(self.current_frame)
|
interp = self._get_interpolated_tracking_position(self.current_frame)
|
||||||
if interp:
|
if interp:
|
||||||
@@ -2089,12 +2113,12 @@ class VideoEditor:
|
|||||||
del self.tracking_points[self.current_frame][idx]
|
del self.tracking_points[self.current_frame][idx]
|
||||||
if not self.tracking_points[self.current_frame]:
|
if not self.tracking_points[self.current_frame]:
|
||||||
del 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
|
removed = True
|
||||||
break
|
break
|
||||||
if not removed:
|
if not removed:
|
||||||
self.tracking_points.setdefault(self.current_frame, []).append((int(rx), int(ry)))
|
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.clear_transformation_cache()
|
||||||
self.save_state()
|
self.save_state()
|
||||||
|
|
||||||
|
@@ -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
|
- **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
|
||||||
|
|
||||||
### Markers and Looping
|
### Markers and Looping
|
||||||
- **1**: Set cut start marker at current frame
|
- **1**: Set cut start marker at current frame
|
||||||
|
Reference in New Issue
Block a user