Enhance template management in VideoEditor by including template images

This commit updates the template management system in the VideoEditor to store template images alongside their start frames and regions. The changes include modifications to the loading and saving processes, ensuring that template images are recreated when needed. Additionally, the logic for adding and retrieving templates has been refined to accommodate the new structure, improving the overall efficiency and clarity of template handling during video editing sessions.
This commit is contained in:
2025-09-26 19:35:13 +02:00
parent 1ac8cd04b3
commit b5a0811cbd

View File

@@ -865,8 +865,8 @@ class VideoEditor:
self.template_selection_start = None
self.template_selection_rect = None
# Simple template system - list of (start_frame, region) tuples sorted by start_frame
self.templates = [] # [(start_frame, region), ...] sorted by start_frame
# Simple template system - list of (start_frame, region, template_image) tuples sorted by start_frame
self.templates = [] # [(start_frame, region, template_image), ...] sorted by start_frame
# Template matching modes
self.template_matching_full_frame = False # Toggle for full frame vs cropped template matching
@@ -921,7 +921,7 @@ class VideoEditor:
'templates': [{
'start_frame': start_frame,
'region': region
} for start_frame, region in self.templates]
} for start_frame, region, template_image in self.templates]
}
with open(state_file, 'w') as f:
@@ -1017,10 +1017,16 @@ class VideoEditor:
if 'templates' in state:
self.templates = []
for template_data in state['templates']:
self.templates.append((template_data['start_frame'], template_data['region']))
start_frame = template_data['start_frame']
region = template_data['region']
# We'll recreate the template image when needed
self.templates.append((start_frame, region, None))
# Sort by start_frame
self.templates.sort(key=lambda x: x[0])
print(f"Loaded {len(self.templates)} templates")
# Recreate template images by seeking to capture frames
self._recreate_template_images()
# Validate cut markers against current video length
if self.cut_start_frame is not None and self.cut_start_frame >= self.total_frames:
@@ -2274,14 +2280,10 @@ class VideoEditor:
if template_index is None:
return None
start_frame, region = self.templates[template_index]
x, y, w, h = region
start_frame, region, template_image = self.templates[template_index]
# Extract template from current frame
if (y + h <= frame.shape[0] and x + w <= frame.shape[1]):
tracking_template = frame[y:y+h, x:x+w]
else:
return None
# Use the stored template image from when it was captured
tracking_template = template_image
try:
# Apply image preprocessing for better template matching
@@ -2392,8 +2394,8 @@ class VideoEditor:
if start_frame is None:
start_frame = self.current_frame
# Add template to list
self.templates.append((start_frame, region))
# Add template to list with the actual template image
self.templates.append((start_frame, region, template.copy()))
# Sort by start_frame
self.templates.sort(key=lambda x: x[0])
@@ -2410,7 +2412,7 @@ class VideoEditor:
current_frame = self.current_frame
template_to_remove = None
for i, (start_frame, region) in enumerate(self.templates):
for i, (start_frame, region, template_image) in enumerate(self.templates):
if start_frame > current_frame:
# Found template with start_frame > current_frame
# Remove the previous one (if it exists)
@@ -2432,7 +2434,7 @@ class VideoEditor:
return None
# Find template with start_frame > current_frame
for i, (start_frame, region) in enumerate(self.templates):
for i, (start_frame, region, template_image) in enumerate(self.templates):
if start_frame > frame_number:
# Found template with start_frame > current_frame
# Use the previous one (if it exists)
@@ -2449,6 +2451,35 @@ class VideoEditor:
template_index = self.get_template_for_frame(frame_number)
return template_index is not None
def _recreate_template_images(self):
"""Recreate template images by seeking to their capture frames"""
if not self.templates:
return
current_frame_backup = self.current_frame
for i, (start_frame, region, template_image) in enumerate(self.templates):
if template_image is None: # Only recreate if missing
try:
# Seek to the capture frame
self.seek_to_frame(start_frame)
# Extract template from current frame
x, y, w, h = region
if (y + h <= self.current_display_frame.shape[0] and
x + w <= self.current_display_frame.shape[1]):
template_image = self.current_display_frame[y:y+h, x:x+w].copy()
# Update the template in the list
self.templates[i] = (start_frame, region, template_image)
print(f"DEBUG: Recreated template {i} from frame {start_frame}")
else:
print(f"DEBUG: Failed to recreate template {i} - region outside frame bounds")
except Exception as e:
print(f"DEBUG: Failed to recreate template {i}: {e}")
# Restore original frame
self.seek_to_frame(current_frame_backup)
def jump_to_previous_template(self):
"""Jump to the previous template marker (frame where template was created)."""
@@ -2459,7 +2490,7 @@ class VideoEditor:
print("DEBUG: No template markers; prev jump ignored")
return
current = self.current_frame
candidates = [start_frame for start_frame, region in self.templates if start_frame < current]
candidates = [start_frame for start_frame, region, template_image in self.templates if start_frame < current]
if candidates:
target = candidates[-1]
print(f"DEBUG: Jump prev template from {current} -> {target}")
@@ -2478,7 +2509,7 @@ class VideoEditor:
print("DEBUG: No template markers; next jump ignored")
return
current = self.current_frame
for start_frame, region in self.templates:
for start_frame, region, template_image in self.templates:
if start_frame > current:
print(f"DEBUG: Jump next template from {current} -> {start_frame}")
self.seek_to_frame(start_frame)
@@ -2942,14 +2973,14 @@ class VideoEditor:
)
# Draw template markers
for start_frame, region in self.templates:
for start_frame, region, template_image in self.templates:
# Draw template start point
start_progress = start_frame / max(1, self.total_frames - 1)
start_x = bar_x_start + int(bar_width * start_progress)
# Template color (green for active, red for inactive)
template_index = self.get_template_for_frame(self.current_frame)
is_active = (template_index is not None and self.templates[template_index] == (start_frame, region))
is_active = (template_index is not None and self.templates[template_index][0] == start_frame)
template_color = (0, 255, 0) if is_active else (255, 0, 0) # Green if active, red if inactive
# Draw template start marker
@@ -3421,7 +3452,7 @@ class VideoEditor:
screen_x, screen_y = x, y
raw_x, raw_y = self._map_screen_to_rotated(screen_x, screen_y)
for i, (start_frame, region) in enumerate(self.templates):
for i, (start_frame, region, template_image) in enumerate(self.templates):
tx, ty, tw, th = region
center_x = tx + tw // 2
center_y = ty + th // 2