diff --git a/croppa/main.py b/croppa/main.py index 7026ccd..e56e65b 100644 --- a/croppa/main.py +++ b/croppa/main.py @@ -3772,29 +3772,29 @@ class VideoEditor: if flags & cv2.EVENT_FLAG_CTRLKEY and event == cv2.EVENT_LBUTTONDOWN: self.zoom_center = (x, y) - # Handle Shift+Right-click+drag for selective feature extraction - if event == cv2.EVENT_RBUTTONDOWN and (flags & cv2.EVENT_FLAG_SHIFTKEY): + # Handle shift+right-click for placing tracking point at previous tracking point position + if event == cv2.EVENT_RBUTTONDOWN and (flags & cv2.EVENT_FLAG_SHIFTKEY) and not (flags & cv2.EVENT_FLAG_CTRLKEY): if not self.is_image_mode: - # Enable feature tracking if not already enabled - if not self.feature_tracker.tracking_enabled: - self.feature_tracker.tracking_enabled = True - self.show_feedback_message("Feature tracking enabled") - self.selective_feature_extraction_start = (x, y) - self.selective_feature_extraction_rect = None - print(f"DEBUG: Started selective feature extraction at ({x}, {y})") + # Get previous tracking point position + prev_result = self._get_previous_tracking_point() + if prev_result: + prev_frame, prev_points = prev_result + if prev_points: + # Use the first tracking point from the previous frame + prev_x, prev_y = prev_points[0] - # Handle Shift+Right-click+drag for selective feature extraction - if event == cv2.EVENT_MOUSEMOVE and (flags & cv2.EVENT_FLAG_SHIFTKEY) and self.selective_feature_extraction_start: - if not self.is_image_mode: - start_x, start_y = self.selective_feature_extraction_start - self.selective_feature_extraction_rect = (min(start_x, x), min(start_y, y), abs(x - start_x), abs(y - start_y)) + # Add tracking point at same position on current frame + self.tracking_points.setdefault(self.current_frame, []).append((int(prev_x), int(prev_y))) + print(f"DEBUG: Added tracking point at previous position ({prev_x}, {prev_y}) on frame {self.current_frame}") + self.show_feedback_message("Tracking point added at previous position") - # Handle Shift+Right-click release for selective feature extraction - if event == cv2.EVENT_RBUTTONUP and (flags & cv2.EVENT_FLAG_SHIFTKEY) and self.selective_feature_extraction_start: - if not self.is_image_mode and self.selective_feature_extraction_rect: - self._extract_features_from_region(self.selective_feature_extraction_rect) - self.selective_feature_extraction_start = None - self.selective_feature_extraction_rect = None + self.clear_transformation_cache() + self.save_state() + self.display_current_frame() + else: + self.show_feedback_message("No previous tracking points found") + else: + self.show_feedback_message("No previous tracking points found") # Handle Ctrl+Right-click+drag for selective feature deletion if event == cv2.EVENT_RBUTTONDOWN and (flags & cv2.EVENT_FLAG_CTRLKEY): @@ -3851,6 +3851,30 @@ class VideoEditor: self.display_needs_update = True + # Handle right-click for selective feature extraction when mode is active + if event == cv2.EVENT_RBUTTONDOWN and not (flags & (cv2.EVENT_FLAG_CTRLKEY | cv2.EVENT_FLAG_SHIFTKEY)): + if not self.is_image_mode and hasattr(self, 'selective_feature_extraction_mode') and self.selective_feature_extraction_mode: + # Start selective feature extraction + self.selective_feature_extraction_start = (x, y) + self.selective_feature_extraction_rect = None + print(f"DEBUG: Started selective feature extraction at ({x}, {y})") + return # Don't process regular right-click functionality + + # Handle mouse move for selective feature extraction + if event == cv2.EVENT_MOUSEMOVE and hasattr(self, 'selective_feature_extraction_start') and self.selective_feature_extraction_start: + if not self.is_image_mode: + start_x, start_y = self.selective_feature_extraction_start + self.selective_feature_extraction_rect = (min(start_x, x), min(start_y, y), abs(x - start_x), abs(y - start_y)) + self.display_needs_update = True + + # Handle mouse release for selective feature extraction + if event == cv2.EVENT_RBUTTONUP and hasattr(self, 'selective_feature_extraction_start') and self.selective_feature_extraction_start: + if not self.is_image_mode and self.selective_feature_extraction_rect: + self._extract_features_from_region(self.selective_feature_extraction_rect) + self.selective_feature_extraction_start = None + self.selective_feature_extraction_rect = None + self.display_needs_update = True + # Handle right-click for tracking points (no modifiers) if event == cv2.EVENT_RBUTTONDOWN and not (flags & (cv2.EVENT_FLAG_CTRLKEY | cv2.EVENT_FLAG_SHIFTKEY)): if not self.is_image_mode: @@ -5124,17 +5148,21 @@ class VideoEditor: self.show_feedback_message(f"Detector switched to {new_type}") self.save_state() elif key == ord("z"): - # Switch detector type (SIFT -> ORB -> SIFT) - SURF not available - current_type = self.feature_tracker.detector_type - if current_type == 'SIFT': - new_type = 'ORB' - elif current_type == 'ORB': - new_type = 'SIFT' - else: - new_type = 'SIFT' - self.feature_tracker.set_detector_type(new_type) - self.show_feedback_message(f"Detector switched to {new_type}") - self.save_state() + # Toggle selective feature extraction mode + if not self.is_image_mode: + if not hasattr(self, 'selective_feature_extraction_mode'): + self.selective_feature_extraction_mode = False + + self.selective_feature_extraction_mode = not self.selective_feature_extraction_mode + if self.selective_feature_extraction_mode: + self.show_feedback_message("Selective feature extraction mode ON - Right-click and drag to select region") + # Enable feature tracking if not already enabled + if not self.feature_tracker.tracking_enabled: + self.feature_tracker.tracking_enabled = True + self.show_feedback_message("Feature tracking enabled") + else: + self.show_feedback_message("Selective feature extraction mode OFF") + self.save_state() elif key == ord("o"): # Toggle optical flow tracking self.optical_flow_enabled = not self.optical_flow_enabled