diff --git a/croppa/main.py b/croppa/main.py index 163a384..885be61 100644 --- a/croppa/main.py +++ b/croppa/main.py @@ -929,7 +929,10 @@ class VideoEditor: 'is_playing': getattr(self, 'is_playing', False), 'tracking_enabled': self.tracking_enabled, 'tracking_points': {str(k): v for k, v in self.tracking_points.items()}, - 'feature_tracker': self.feature_tracker.get_state_dict() + 'feature_tracker': self.feature_tracker.get_state_dict(), + 'template_matching_enabled': self.template_matching_enabled, + 'tracking_template': self.tracking_template, + 'template_region': self.template_region } with open(state_file, 'w') as f: @@ -1016,6 +1019,14 @@ class VideoEditor: if 'feature_tracker' in state: self.feature_tracker.load_state_dict(state['feature_tracker']) print(f"Loaded feature tracker state") + + # Load template matching state + if 'template_matching_enabled' in state: + self.template_matching_enabled = state['template_matching_enabled'] + if 'tracking_template' in state and state['tracking_template'] is not None: + self.tracking_template = state['tracking_template'] + if 'template_region' in state: + self.template_region = state['template_region'] # Validate cut markers against current video length if self.cut_start_frame is not None and self.cut_start_frame >= self.total_frames: @@ -1831,21 +1842,22 @@ class VideoEditor: orig_x + orig_w <= self.frame_width and orig_y + orig_h <= self.frame_height): - region_frame = self.current_display_frame[orig_y:orig_y+orig_h, orig_x:orig_x+orig_w] - if region_frame.size > 0: - # Map coordinates from region to rotated frame coordinates - def coord_mapper(px, py): - # Map from region coordinates to rotated frame coordinates - if self.rotation_angle == 90: - rot_x = orig_x + py - rot_y = self.frame_height - (orig_y + px) - elif self.rotation_angle == 270: - rot_x = self.frame_width - (orig_y + py) - rot_y = orig_x + px - else: - rot_x = orig_x + px - rot_y = orig_y + py - return (int(rot_x), int(rot_y)) + if self.current_display_frame is not None: + region_frame = self.current_display_frame[orig_y:orig_y+orig_h, orig_x:orig_x+orig_w] + if region_frame is not None and region_frame.size > 0: + # Map coordinates from region to rotated frame coordinates + def coord_mapper(px, py): + # Map from region coordinates to rotated frame coordinates + if self.rotation_angle == 90: + rot_x = orig_x + py + rot_y = self.frame_height - (orig_y + px) + elif self.rotation_angle == 270: + rot_x = self.frame_width - (orig_y + py) + rot_y = orig_x + px + else: + rot_x = orig_x + px + rot_y = orig_y + py + return (int(rot_x), int(rot_y)) # Extract features and add them to existing features success = self.feature_tracker.extract_features_from_region(region_frame, self.current_frame, coord_mapper) @@ -2143,7 +2155,7 @@ class VideoEditor: # Template matching result = cv2.matchTemplate(gray_frame, gray_template, cv2.TM_CCOEFF_NORMED) - min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) + _, max_val, _, max_loc = cv2.minMaxLoc(result) # Only accept matches above threshold if max_val > 0.6: # Adjust threshold as needed @@ -3055,21 +3067,21 @@ class VideoEditor: self.selective_feature_deletion_start = None self.selective_feature_deletion_rect = None - # Handle Alt+Right-click+drag for template region selection - if event == cv2.EVENT_RBUTTONDOWN and (flags & cv2.EVENT_FLAG_ALTKEY): + # Handle Ctrl+Left-click+drag for template region selection + if event == cv2.EVENT_LBUTTONDOWN and (flags & cv2.EVENT_FLAG_CTRLKEY): if not self.is_image_mode: self.template_selection_start = (x, y) self.template_selection_rect = None print(f"DEBUG: Started template selection at ({x}, {y})") - # Handle Alt+Right-click+drag for template region selection - if event == cv2.EVENT_MOUSEMOVE and (flags & cv2.EVENT_FLAG_ALTKEY) and self.template_selection_start: + # Handle Ctrl+Left-click+drag for template region selection + if event == cv2.EVENT_MOUSEMOVE and (flags & cv2.EVENT_FLAG_CTRLKEY) and self.template_selection_start: if not self.is_image_mode: start_x, start_y = self.template_selection_start self.template_selection_rect = (min(start_x, x), min(start_y, y), abs(x - start_x), abs(y - start_y)) - # Handle Alt+Right-click release for template region selection - if event == cv2.EVENT_RBUTTONUP and (flags & cv2.EVENT_FLAG_ALTKEY) and self.template_selection_start: + # Handle Ctrl+Left-click release for template region selection + if event == cv2.EVENT_LBUTTONUP and (flags & cv2.EVENT_FLAG_CTRLKEY) and self.template_selection_start: if not self.is_image_mode and self.template_selection_rect: self._set_template_from_region(self.template_selection_rect) self.template_selection_start = None @@ -3927,7 +3939,7 @@ class VideoEditor: print(" m: Toggle template matching tracking") print(" Shift+Right-click+drag: Extract features from selected region") print(" Ctrl+Right-click+drag: Delete features from selected region") - print(" Alt+Right-click+drag: Set template region for tracking") + print(" Ctrl+Left-click+drag: Set template region for tracking") if len(self.video_files) > 1: print(" N: Next video") print(" n: Previous video")