Refactor template matching logic in VideoEditor to support full frame and cropped modes

This commit introduces a toggle for template matching modes in the VideoEditor, allowing users to choose between full frame and cropped region matching. The logic has been updated to handle both modes effectively, improving flexibility and performance during template tracking. Additionally, the multi-scale template matching feature has been removed, streamlining the template matching process. Debug messages and feedback have been enhanced to reflect the current mode, ensuring better user experience during video editing sessions.
This commit is contained in:
2025-09-26 18:20:12 +02:00
parent 151744d144
commit 44ed4220b9

View File

@@ -882,7 +882,7 @@ class VideoEditor:
self.tracking_template = None self.tracking_template = None
self.template_region = None self.template_region = None
self.template_match_history = [] # Store recent match confidences for adaptive thresholding self.template_match_history = [] # Store recent match confidences for adaptive thresholding
self.multi_scale_template_matching = False # Disable multi-scale by default # (x, y, w, h) in rotated frame coordinates # (x, y, w, h) in rotated frame coordinates
self.template_selection_start = None self.template_selection_start = None
self.template_selection_rect = None self.template_selection_rect = None
@@ -891,6 +891,9 @@ class VideoEditor:
self.current_template_id = None self.current_template_id = None
self.template_id_counter = 0 self.template_id_counter = 0
# Template matching modes
self.template_matching_full_frame = False # Toggle for full frame vs cropped template matching
# Project view mode # Project view mode
self.project_view_mode = False self.project_view_mode = False
self.project_view = None self.project_view = None
@@ -939,7 +942,7 @@ class VideoEditor:
'feature_tracker': self.feature_tracker.get_state_dict(), 'feature_tracker': self.feature_tracker.get_state_dict(),
'template_matching_enabled': self.template_matching_enabled, 'template_matching_enabled': self.template_matching_enabled,
'template_region': self.template_region, 'template_region': self.template_region,
'multi_scale_template_matching': self.multi_scale_template_matching, 'template_matching_full_frame': self.template_matching_full_frame,
'templates': {str(k): { 'templates': {str(k): {
'template': None, # Don't save template images (too large) 'template': None, # Don't save template images (too large)
'region': v['region'], 'region': v['region'],
@@ -1042,8 +1045,8 @@ class VideoEditor:
self.template_region = state['template_region'] self.template_region = state['template_region']
# Recreate template from region when needed # Recreate template from region when needed
self.tracking_template = None self.tracking_template = None
if 'multi_scale_template_matching' in state: if 'template_matching_full_frame' in state:
self.multi_scale_template_matching = state['multi_scale_template_matching'] # Will be recreated on first use self.template_matching_full_frame = state['template_matching_full_frame']
# Load multiple templates state # Load multiple templates state
if 'templates' in state: if 'templates' in state:
@@ -1683,7 +1686,15 @@ class VideoEditor:
template_offset = None template_offset = None
if self.template_matching_enabled and self.tracking_template is not None: if self.template_matching_enabled and self.tracking_template is not None:
if self.current_display_frame is not None: if self.current_display_frame is not None:
# Use only the cropped region for much faster template matching if self.template_matching_full_frame:
# Full frame mode - use the entire original frame
result = self.track_template(self.current_display_frame)
if result:
center_x, center_y, confidence = result
print(f"DEBUG: Template match found at ({center_x}, {center_y}) with confidence {confidence:.2f}")
template_offset = (center_x, center_y)
else:
# Cropped mode - use only the cropped region for faster template matching
if self.crop_rect: if self.crop_rect:
crop_x, crop_y, crop_w, crop_h = self.crop_rect crop_x, crop_y, crop_w, crop_h = self.crop_rect
# Extract only the cropped region from raw frame # Extract only the cropped region from raw frame
@@ -1850,7 +1861,14 @@ class VideoEditor:
# Get base position for motion tracking offset # Get base position for motion tracking offset
base_pos = self._get_manual_tracking_position(frame_number) base_pos = self._get_manual_tracking_position(frame_number)
# Use only the cropped region for much faster template matching if self.template_matching_full_frame:
# Full frame mode - use the entire original frame
result = self.track_template(self.current_display_frame)
if result:
center_x, center_y, confidence = result
return (center_x, center_y, confidence)
else:
# Cropped mode - use only the cropped region for faster template matching
if self.crop_rect: if self.crop_rect:
crop_x, crop_y, crop_w, crop_h = self.crop_rect crop_x, crop_y, crop_w, crop_h = self.crop_rect
# Extract only the cropped region from raw frame # Extract only the cropped region from raw frame
@@ -2312,7 +2330,7 @@ class VideoEditor:
gray_frame, gray_template = self._improve_template_matching(frame, self.tracking_template) gray_frame, gray_template = self._improve_template_matching(frame, self.tracking_template)
# Multi-scale template matching for better tracking (if enabled) # Multi-scale template matching for better tracking (if enabled)
if self.multi_scale_template_matching: if False: # Multi-scale template matching removed
scales = [0.8, 0.9, 1.0, 1.1, 1.2] # Different scales to try scales = [0.8, 0.9, 1.0, 1.1, 1.2] # Different scales to try
best_match = None best_match = None
best_confidence = 0.0 best_confidence = 0.0
@@ -3231,10 +3249,11 @@ class VideoEditor:
feature_text = f" | Features: {feature_count} pts" feature_text = f" | Features: {feature_count} pts"
if self.optical_flow_enabled: if self.optical_flow_enabled:
feature_text += " (OPTICAL FLOW)" feature_text += " (OPTICAL FLOW)"
template_text = ( template_text = ""
f" | Template: {self.template_matching_enabled}" if self.template_matching_enabled else "" if self.template_matching_enabled:
) mode = "Full Frame" if self.template_matching_full_frame else "Cropped"
if self.template_matching_enabled and self.multi_scale_template_matching: template_text = f" | Template: {mode}"
if False: # Multi-scale template matching removed
template_text += " (MULTI-SCALE)" template_text += " (MULTI-SCALE)"
autorepeat_text = ( autorepeat_text = (
f" | Loop: ON" if self.looping_between_markers else "" f" | Loop: ON" if self.looping_between_markers else ""
@@ -4799,9 +4818,9 @@ class VideoEditor:
self.show_feedback_message(f"Template matching {'ON' if self.template_matching_enabled else 'OFF'}") self.show_feedback_message(f"Template matching {'ON' if self.template_matching_enabled else 'OFF'}")
self.save_state() self.save_state()
elif key == ord("M"): # Shift+M - Toggle multi-scale template matching elif key == ord("M"): # Shift+M - Toggle multi-scale template matching
self.multi_scale_template_matching = not self.multi_scale_template_matching self.template_matching_full_frame = not self.template_matching_full_frame
print(f"DEBUG: Multi-scale template matching toggled to {self.multi_scale_template_matching}") print(f"DEBUG: Template matching full frame toggled to {self.template_matching_full_frame}")
self.show_feedback_message(f"Multi-scale template matching {'ON' if self.multi_scale_template_matching else 'OFF'}") self.show_feedback_message(f"Template matching: {'Full Frame' if self.template_matching_full_frame else 'Cropped'}")
self.save_state() self.save_state()
elif key == ord(";"): # Semicolon - Jump to previous template marker elif key == ord(";"): # Semicolon - Jump to previous template marker
self.jump_to_previous_template() self.jump_to_previous_template()