-
Notifications
You must be signed in to change notification settings - Fork 0
Detect and center focus object in images #227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
WalkthroughThe changes introduce documentation and updates to image processing functionality. In Changes
Sequence Diagram(s)Image Processing FlowsequenceDiagram
participant U as User
participant G as generate_image_with_context
participant C as center_shoes_in_image
participant CV as OpenCV
U->>G: Request image generation
alt Activity data present
G->>G: Extract activity attributes
else Activity data missing
G->>G: Substitute default values ('N/A')
end
G->>C: Call center_shoes_in_image(original image, target_size)
C->>CV: Convert PIL image to OpenCV format
CV-->>C: Return OpenCV image
C->>CV: Perform contour detection & ROI extraction
CV-->>C: Return contour/ROI details
C->>C: Center ROI on a black background
C->>G: Return processed PIL image
G->>U: Return image with context
Video Generation FlowsequenceDiagram
participant U as User
participant V as generate_category_video
participant VW as VideoWriter
U->>V: Call generate_category_video(category, [optional output_path])
alt Output path provided
V->>VW: Initialize video writer with provided output_path
else No output path provided
V->>VW: Initialize video writer with auto-generated filename
end
V->>VW: Generate and save category video
VW-->>V: Confirm video saved
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
libraries/strava.py (1)
1-3: Docstring could be more descriptiveWhile adding the Strava API documentation URL is helpful, consider enhancing the docstring with a brief description of the module's purpose, such as "Strava API interaction module for retrieving athlete activities and gear data."
""" https://developers.strava.com/docs/reference/ + +A module for interacting with the Strava API, providing functions to retrieve +athlete data, activities, and manage authentication flows. """tracker/apps/photos/utils.py (2)
27-96: Image processing implementation looks good but could be more robustThe new shoe detection and centering function is well-documented and logically implemented, but there are a few areas that could be improved:
- The function assumes that shoes are the largest object in the image, which may not always be true
- The threshold value (200) is hardcoded, which might not work well for all lighting conditions
- Some type annotations (lines 63-67, 73-75) are redundant since they're immediately assigned
Consider these improvements:
def center_shoes_in_image(image: Image.Image, target_size: tuple[int, int]) -> Image.Image: """ Detects shoes in the image, centers them, and resizes the image to the target size with a black background. Args: image (Image.Image): The input PIL Image. target_size (Tuple[int, int]): Desired output size (width, height). Returns: Image.Image: The centered and resized PIL Image. """ # Convert PIL Image to OpenCV format (numpy array) img_array = np.array(image) if len(img_array.shape) == 2: # Grayscale image img_array = cv2.cvtColor(img_array, cv2.COLOR_GRAY2BGR) elif img_array.shape[2] == 4: # RGBA image img_array = cv2.cvtColor(img_array, cv2.COLOR_RGBA2BGR) # Convert to grayscale for contour detection gray = cv2.cvtColor(img_array, cv2.COLOR_BGR2GRAY) # Apply a binary threshold to separate the shoes from the background - _, thresh = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) + # Use adaptive thresholding for better handling of different lighting conditions + thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, + cv2.THRESH_BINARY_INV, 11, 2) # Find contours in the thresholded image contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: # If no contours are found, return the original image resized to target size img_array = cv2.resize(img_array, target_size, interpolation=cv2.INTER_AREA) return Image.fromarray(cv2.cvtColor(img_array, cv2.COLOR_BGR2RGB)) # Find the largest contour (assuming the shoes are the largest object) - largest_contour = max(contours, key=cv2.contourArea) + # Filter contours by minimum area to avoid small noise + min_area = img_array.shape[0] * img_array.shape[1] * 0.05 # At least 5% of image + valid_contours = [c for c in contours if cv2.contourArea(c) > min_area] + if not valid_contours: + # If no valid contours, return resized original + img_array = cv2.resize(img_array, target_size, interpolation=cv2.INTER_AREA) + return Image.fromarray(cv2.cvtColor(img_array, cv2.COLOR_BGR2RGB)) + largest_contour = max(valid_contours, key=cv2.contourArea) # Get the bounding box of the largest contour - x: int - y: int - w: int - h: int x, y, w, h = cv2.boundingRect(largest_contour) # Extract the region of interest (ROI) containing the shoes roi = img_array[y:y+h, x:x+w] # Calculate the scaling factor to fit the ROI into the target size while maintaining aspect ratio - roi_h: int - roi_w: int roi_h, roi_w = roi.shape[:2] scale: float = min(target_size[0] / roi_w, target_size[1] / roi_h) new_w: int = int(roi_w * scale) new_h: int = int(roi_h * scale)
156-178: Enhanced flexibility with optional output path parameterAdding the optional
output_pathparameter makes the function more flexible and reusable. The function now correctly returns the output path, which could be helpful for the caller.One minor issue: The return type annotation in the function signature is
None, but the function now returns a string (the output path).-def generate_category_video(category: PhotoCategory, output_path: Optional[str] = None) -> None: +def generate_category_video(category: PhotoCategory, output_path: Optional[str] = None) -> str:
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
libraries/strava.py(1 hunks)tracker/apps/photos/utils.py(4 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
tracker/apps/photos/utils.py (1)
tracker/apps/activities/models.py (3)
get_shoe_distance_display(99-107)get_distance_display(109-117)average_pace(83-97)
🔇 Additional comments (3)
tracker/apps/photos/utils.py (3)
6-6: LGTM: NumPy import added for image processingThe NumPy import is correctly added to support the new image processing functionality.
98-117: Good error handling for missing activity dataThe changes to handle cases where
photo.activityisNoneimprove the robustness of the code and prevent failures. The integration of thecenter_shoes_in_imagefunction is also well implemented.
132-144: LGTM: Improved text layout calculationsThe text box sizing and positioning calculations are more precise now, leading to better visual output.
|
/review |



Summary by CodeRabbit