from typing import Any import numpy as np from PIL import Image def segment_image( mask_generator: Any, image: Image.Image, min_area: int = 32 * 32, max_masks: int = 5, points_per_batch=64, ) -> list[dict[str, Any]]: """Segment image using SAM to extract object masks. Args: mask_generator: SAM2 mask generator. image: PIL Image to segment. min_area: Minimum mask area threshold in pixels. max_masks: Maximum number of masks to return. points_per_batch: Number of prompt points to process in each batch. Returns: List of mask dictionaries with keys: - segment: Binary mask (numpy array) - area: Mask area in pixels - bbox: Bounding box [x, y, width, height] - predicted_iou: Model's confidence in the mask - stability_score: Stability score for the mask """ # Convert PIL Image to numpy array image_np = np.array(image.convert("RGB")) # Generate masks masks = mask_generator(image_np, points_per_batch=points_per_batch)["masks"] if not masks: return [] # Filter by minimum area filtered_masks = [m for m in masks if m["area"] >= min_area] if not filtered_masks: return [] # Sort by area (largest first) and limit to max_masks sorted_masks = sorted(filtered_masks, key=lambda x: x["area"], reverse=True) return sorted_masks[:max_masks] def extract_masked_region( image: Image.Image, mask: np.ndarray, ) -> Image.Image: """Extract masked region from image. Args: image: Original PIL Image. mask: Binary mask as numpy array (True = keep). Returns: PIL Image with only the masked region visible. """ image_np = np.array(image.convert("RGB")) # Apply mask masked_np = image_np * mask[:, :, np.newaxis] return Image.fromarray(masked_np.astype(np.uint8))