Refactor template matching in VideoEditor to use raw frame coordinates for improved accuracy. This update simplifies the tracking logic by directly utilizing the raw display frame, eliminating unnecessary transformations. Additionally, it enhances the template setting process by ensuring the selected region is correctly mapped to raw frame coordinates, improving usability and feedback during template selection. Debug messages have been updated to reflect these changes.

This commit is contained in:
2025-09-26 14:34:48 +02:00
parent e6616ed1b1
commit 5400592afd

View File

@@ -1640,47 +1640,17 @@ class VideoEditor:
# First try template matching if enabled (much better than optical flow)
if self.template_matching_enabled and self.tracking_template is not None:
if self.current_display_frame is not None:
# Use only the cropped region for much faster template matching
if self.crop_rect:
crop_x, crop_y, crop_w, crop_h = self.crop_rect
# Extract only the cropped region
cropped_frame = self.current_display_frame[crop_y:crop_y+crop_h, crop_x:crop_x+crop_w]
if cropped_frame is not None and cropped_frame.size > 0:
# Track template in cropped frame (much faster!)
result = self.track_template(cropped_frame)
if result:
center_x, center_y, confidence = result
print(f"DEBUG: Template match found at ({center_x}, {center_y}) with confidence {confidence:.2f}")
# Map from cropped frame coordinates to rotated frame coordinates
# Add crop offset back
rot_x = center_x + crop_x
rot_y = center_y + crop_y
return (rot_x, rot_y)
else:
# No crop - use full frame
raw_frame = self.current_display_frame.copy()
if raw_frame is not None:
result = self.track_template(raw_frame)
if result:
center_x, center_y, confidence = result
print(f"DEBUG: Template match found at ({center_x}, {center_y}) with confidence {confidence:.2f}")
# Map from raw frame coordinates to rotated frame coordinates
if self.rotation_angle == 90:
rot_x = self.frame_height - center_y
rot_y = center_x
elif self.rotation_angle == 180:
rot_x = self.frame_width - center_x
rot_y = self.frame_height - center_y
elif self.rotation_angle == 270:
rot_x = center_y
rot_y = self.frame_width - center_x
else:
rot_x, rot_y = center_x, center_y
return (rot_x, rot_y)
# Use the raw frame for template matching (template_region is in raw frame coordinates)
raw_frame = self.current_display_frame.copy()
if raw_frame is not None:
result = self.track_template(raw_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 matching returns coordinates in raw frame space
# No additional transformation needed since template_region is in raw frame coordinates
return (center_x, center_y)
# Fall back to feature tracking if enabled - but use smooth interpolation instead of averaging
if self.feature_tracker.tracking_enabled:
@@ -2231,37 +2201,35 @@ class VideoEditor:
print(f"DEBUG: Setting template from region ({x}, {y}, {w}, {h})")
if self.current_display_frame is not None:
# Apply transformations to get the display frame
display_frame = self.apply_crop_zoom_and_rotation(self.current_display_frame)
if display_frame is not None:
# Map screen coordinates to display frame coordinates
frame_height, frame_width = display_frame.shape[:2]
available_height = self.window_height - (0 if self.is_image_mode else self.TIMELINE_HEIGHT)
start_y = (available_height - frame_height) // 2
start_x = (self.window_width - frame_width) // 2
# Map screen coordinates to rotated frame coordinates (raw frame)
# This is what we need for template matching during rendering
rot_x, rot_y = self._map_screen_to_rotated(x, y)
rot_x2, rot_y2 = self._map_screen_to_rotated(x + w, y + h)
# Calculate region in rotated frame coordinates
raw_x = min(rot_x, rot_x2)
raw_y = min(rot_y, rot_y2)
raw_w = abs(rot_x2 - rot_x)
raw_h = abs(rot_y2 - rot_y)
print(f"DEBUG: Mapped to raw frame coordinates ({raw_x}, {raw_y}, {raw_w}, {raw_h})")
# Ensure region is within raw frame bounds
if (raw_x >= 0 and raw_y >= 0 and
raw_x + raw_w <= self.frame_width and
raw_y + raw_h <= self.frame_height):
# Convert screen coordinates to display frame coordinates
display_x = x - start_x
display_y = y - start_y
display_w = w
display_h = h
# Ensure region is within frame bounds
if (display_x >= 0 and display_y >= 0 and
display_x + display_w <= frame_width and
display_y + display_h <= frame_height):
# Extract template from display frame
template = display_frame[display_y:display_y+display_h, display_x:display_x+display_w]
if template.size > 0:
self.tracking_template = template.copy()
self.template_region = (display_x, display_y, display_w, display_h)
self.show_feedback_message(f"Template set from region ({display_w}x{display_h})")
print(f"DEBUG: Template set with size {template.shape}")
else:
self.show_feedback_message("Template region too small")
# Extract template from raw frame
template = self.current_display_frame[raw_y:raw_y+raw_h, raw_x:raw_x+raw_w]
if template.size > 0:
self.tracking_template = template.copy()
self.template_region = (raw_x, raw_y, raw_w, raw_h)
self.show_feedback_message(f"Template set from region ({raw_w}x{raw_h})")
print(f"DEBUG: Template set with size {template.shape}")
else:
self.show_feedback_message("Template region outside frame bounds")
self.show_feedback_message("Template region too small")
else:
self.show_feedback_message("Template region outside frame bounds")
def apply_rotation(self, frame):