Enhance VideoEditor with template matching state management and user interaction updates
This commit adds functionality to manage the state of template matching in the VideoEditor, including loading and saving template matching settings. It also updates user interaction for selecting template regions, changing the control scheme from Alt+Right-click to Ctrl+Left-click for better usability. Additionally, it improves the handling of the current display frame during feature extraction, ensuring robustness in the tracking process.
This commit is contained in:
@@ -929,7 +929,10 @@ class VideoEditor:
|
|||||||
'is_playing': getattr(self, 'is_playing', False),
|
'is_playing': getattr(self, 'is_playing', False),
|
||||||
'tracking_enabled': self.tracking_enabled,
|
'tracking_enabled': self.tracking_enabled,
|
||||||
'tracking_points': {str(k): v for k, v in self.tracking_points.items()},
|
'tracking_points': {str(k): v for k, v in self.tracking_points.items()},
|
||||||
'feature_tracker': self.feature_tracker.get_state_dict()
|
'feature_tracker': self.feature_tracker.get_state_dict(),
|
||||||
|
'template_matching_enabled': self.template_matching_enabled,
|
||||||
|
'tracking_template': self.tracking_template,
|
||||||
|
'template_region': self.template_region
|
||||||
}
|
}
|
||||||
|
|
||||||
with open(state_file, 'w') as f:
|
with open(state_file, 'w') as f:
|
||||||
@@ -1017,6 +1020,14 @@ class VideoEditor:
|
|||||||
self.feature_tracker.load_state_dict(state['feature_tracker'])
|
self.feature_tracker.load_state_dict(state['feature_tracker'])
|
||||||
print(f"Loaded feature tracker state")
|
print(f"Loaded feature tracker state")
|
||||||
|
|
||||||
|
# Load template matching state
|
||||||
|
if 'template_matching_enabled' in state:
|
||||||
|
self.template_matching_enabled = state['template_matching_enabled']
|
||||||
|
if 'tracking_template' in state and state['tracking_template'] is not None:
|
||||||
|
self.tracking_template = state['tracking_template']
|
||||||
|
if 'template_region' in state:
|
||||||
|
self.template_region = state['template_region']
|
||||||
|
|
||||||
# Validate cut markers against current video length
|
# Validate cut markers against current video length
|
||||||
if self.cut_start_frame is not None and self.cut_start_frame >= self.total_frames:
|
if self.cut_start_frame is not None and self.cut_start_frame >= self.total_frames:
|
||||||
print(f"DEBUG: cut_start_frame {self.cut_start_frame} is beyond video length {self.total_frames}, clearing")
|
print(f"DEBUG: cut_start_frame {self.cut_start_frame} is beyond video length {self.total_frames}, clearing")
|
||||||
@@ -1831,21 +1842,22 @@ class VideoEditor:
|
|||||||
orig_x + orig_w <= self.frame_width and
|
orig_x + orig_w <= self.frame_width and
|
||||||
orig_y + orig_h <= self.frame_height):
|
orig_y + orig_h <= self.frame_height):
|
||||||
|
|
||||||
region_frame = self.current_display_frame[orig_y:orig_y+orig_h, orig_x:orig_x+orig_w]
|
if self.current_display_frame is not None:
|
||||||
if region_frame.size > 0:
|
region_frame = self.current_display_frame[orig_y:orig_y+orig_h, orig_x:orig_x+orig_w]
|
||||||
# Map coordinates from region to rotated frame coordinates
|
if region_frame is not None and region_frame.size > 0:
|
||||||
def coord_mapper(px, py):
|
# Map coordinates from region to rotated frame coordinates
|
||||||
# Map from region coordinates to rotated frame coordinates
|
def coord_mapper(px, py):
|
||||||
if self.rotation_angle == 90:
|
# Map from region coordinates to rotated frame coordinates
|
||||||
rot_x = orig_x + py
|
if self.rotation_angle == 90:
|
||||||
rot_y = self.frame_height - (orig_y + px)
|
rot_x = orig_x + py
|
||||||
elif self.rotation_angle == 270:
|
rot_y = self.frame_height - (orig_y + px)
|
||||||
rot_x = self.frame_width - (orig_y + py)
|
elif self.rotation_angle == 270:
|
||||||
rot_y = orig_x + px
|
rot_x = self.frame_width - (orig_y + py)
|
||||||
else:
|
rot_y = orig_x + px
|
||||||
rot_x = orig_x + px
|
else:
|
||||||
rot_y = orig_y + py
|
rot_x = orig_x + px
|
||||||
return (int(rot_x), int(rot_y))
|
rot_y = orig_y + py
|
||||||
|
return (int(rot_x), int(rot_y))
|
||||||
|
|
||||||
# Extract features and add them to existing features
|
# Extract features and add them to existing features
|
||||||
success = self.feature_tracker.extract_features_from_region(region_frame, self.current_frame, coord_mapper)
|
success = self.feature_tracker.extract_features_from_region(region_frame, self.current_frame, coord_mapper)
|
||||||
@@ -2143,7 +2155,7 @@ class VideoEditor:
|
|||||||
|
|
||||||
# Template matching
|
# Template matching
|
||||||
result = cv2.matchTemplate(gray_frame, gray_template, cv2.TM_CCOEFF_NORMED)
|
result = cv2.matchTemplate(gray_frame, gray_template, cv2.TM_CCOEFF_NORMED)
|
||||||
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
|
_, max_val, _, max_loc = cv2.minMaxLoc(result)
|
||||||
|
|
||||||
# Only accept matches above threshold
|
# Only accept matches above threshold
|
||||||
if max_val > 0.6: # Adjust threshold as needed
|
if max_val > 0.6: # Adjust threshold as needed
|
||||||
@@ -3055,21 +3067,21 @@ class VideoEditor:
|
|||||||
self.selective_feature_deletion_start = None
|
self.selective_feature_deletion_start = None
|
||||||
self.selective_feature_deletion_rect = None
|
self.selective_feature_deletion_rect = None
|
||||||
|
|
||||||
# Handle Alt+Right-click+drag for template region selection
|
# Handle Ctrl+Left-click+drag for template region selection
|
||||||
if event == cv2.EVENT_RBUTTONDOWN and (flags & cv2.EVENT_FLAG_ALTKEY):
|
if event == cv2.EVENT_LBUTTONDOWN and (flags & cv2.EVENT_FLAG_CTRLKEY):
|
||||||
if not self.is_image_mode:
|
if not self.is_image_mode:
|
||||||
self.template_selection_start = (x, y)
|
self.template_selection_start = (x, y)
|
||||||
self.template_selection_rect = None
|
self.template_selection_rect = None
|
||||||
print(f"DEBUG: Started template selection at ({x}, {y})")
|
print(f"DEBUG: Started template selection at ({x}, {y})")
|
||||||
|
|
||||||
# Handle Alt+Right-click+drag for template region selection
|
# Handle Ctrl+Left-click+drag for template region selection
|
||||||
if event == cv2.EVENT_MOUSEMOVE and (flags & cv2.EVENT_FLAG_ALTKEY) and self.template_selection_start:
|
if event == cv2.EVENT_MOUSEMOVE and (flags & cv2.EVENT_FLAG_CTRLKEY) and self.template_selection_start:
|
||||||
if not self.is_image_mode:
|
if not self.is_image_mode:
|
||||||
start_x, start_y = self.template_selection_start
|
start_x, start_y = self.template_selection_start
|
||||||
self.template_selection_rect = (min(start_x, x), min(start_y, y), abs(x - start_x), abs(y - start_y))
|
self.template_selection_rect = (min(start_x, x), min(start_y, y), abs(x - start_x), abs(y - start_y))
|
||||||
|
|
||||||
# Handle Alt+Right-click release for template region selection
|
# Handle Ctrl+Left-click release for template region selection
|
||||||
if event == cv2.EVENT_RBUTTONUP and (flags & cv2.EVENT_FLAG_ALTKEY) and self.template_selection_start:
|
if event == cv2.EVENT_LBUTTONUP and (flags & cv2.EVENT_FLAG_CTRLKEY) and self.template_selection_start:
|
||||||
if not self.is_image_mode and self.template_selection_rect:
|
if not self.is_image_mode and self.template_selection_rect:
|
||||||
self._set_template_from_region(self.template_selection_rect)
|
self._set_template_from_region(self.template_selection_rect)
|
||||||
self.template_selection_start = None
|
self.template_selection_start = None
|
||||||
@@ -3927,7 +3939,7 @@ class VideoEditor:
|
|||||||
print(" m: Toggle template matching tracking")
|
print(" m: Toggle template matching tracking")
|
||||||
print(" Shift+Right-click+drag: Extract features from selected region")
|
print(" Shift+Right-click+drag: Extract features from selected region")
|
||||||
print(" Ctrl+Right-click+drag: Delete features from selected region")
|
print(" Ctrl+Right-click+drag: Delete features from selected region")
|
||||||
print(" Alt+Right-click+drag: Set template region for tracking")
|
print(" Ctrl+Left-click+drag: Set template region for tracking")
|
||||||
if len(self.video_files) > 1:
|
if len(self.video_files) > 1:
|
||||||
print(" N: Next video")
|
print(" N: Next video")
|
||||||
print(" n: Previous video")
|
print(" n: Previous video")
|
||||||
|
Reference in New Issue
Block a user