diff --git a/croppa/main.py b/croppa/main.py index 7f3a08f..776f233 100644 --- a/croppa/main.py +++ b/croppa/main.py @@ -2432,6 +2432,11 @@ class VideoEditor: if end_frame is None: end_frame = self.total_frames - 1 + # End the previous template at the current frame (if there is one) + if self.current_template_id is not None and self.current_template_id in self.templates: + self.templates[self.current_template_id]['end_frame'] = self.current_frame - 1 + print(f"DEBUG: Ended previous template {self.current_template_id} at frame {self.current_frame - 1}") + self.templates[template_id] = { 'template': template.copy(), 'region': region, @@ -2439,11 +2444,10 @@ class VideoEditor: 'end_frame': end_frame } - # Set as current template if it's the first one or if it covers current frame - if self.current_template_id is None or (start_frame <= self.current_frame <= end_frame): - self.current_template_id = template_id - self.tracking_template = template.copy() - self.template_region = region + # Set as current template + self.current_template_id = template_id + self.tracking_template = template.copy() + self.template_region = region self.show_feedback_message(f"Template {template_id} added (frames {start_frame}-{end_frame})") return template_id @@ -2462,9 +2466,9 @@ class VideoEditor: return False def get_template_for_frame(self, frame_number): - """Get the best template for a given frame number""" + """Get the most recent template that covers this frame""" + # Find the most recent template (highest ID) that covers this frame best_template_id = None - best_priority = -1 for template_id, template_data in self.templates.items(): start_frame = template_data['start_frame'] @@ -2472,21 +2476,29 @@ class VideoEditor: # Check if template covers this frame if start_frame <= frame_number <= end_frame: - # Priority: templates that start earlier and end later are preferred - priority = (end_frame - start_frame) - abs(frame_number - (start_frame + end_frame) // 2) - if priority > best_priority: - best_priority = priority + # Use the template with the highest ID (most recent) + if best_template_id is None or template_id > best_template_id: best_template_id = template_id return best_template_id def _select_best_template_for_frame(self, frame_number): - """Select the best template for the current frame""" + """Select the most recent template for the current frame""" best_template_id = self.get_template_for_frame(frame_number) if best_template_id is not None: self.current_template_id = best_template_id template_data = self.templates[best_template_id] + + # Recreate template if it's None (loaded from state) + if template_data['template'] is None: + if self.current_display_frame is not None: + success = self._recreate_template_from_template_data(best_template_id, self.current_display_frame) + if not success: + return False + else: + return False + self.tracking_template = template_data['template'].copy() self.template_region = template_data['region'] return True @@ -2496,6 +2508,31 @@ class VideoEditor: self.template_region = None return False + def _recreate_template_from_template_data(self, template_id, frame): + """Recreate template from template data region""" + try: + template_data = self.templates[template_id] + x, y, w, h = template_data['region'] + + # Ensure region is within frame bounds + if (x >= 0 and y >= 0 and + x + w <= frame.shape[1] and + y + h <= frame.shape[0]): + + # Extract template from frame + template = frame[y:y+h, x:x+w] + if template.size > 0: + self.templates[template_id]['template'] = template.copy() + return True + else: + return False + else: + return False + + except Exception as e: + print(f"Error recreating template {template_id}: {e}") + return False + def navigate_to_next_template(self): """Navigate to next template (; key)""" if not self.templates: