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