Spaces:
Runtime error
Runtime error
| """Garment detection package with pluggable backends. | |
| Public API: | |
| detect_garments(image_path, backend=None) -> list[BoundingBox] | |
| crop_garments(image_path, boxes, max_size=512) -> list[bytes] | |
| detect_and_crop(image_path, backend=None) -> list[bytes] | |
| """ | |
| import io | |
| import logging | |
| from PIL import Image | |
| from ._types import BoundingBox, DetectorBackend | |
| from ._registry import get_backend, list_available, list_registered, register | |
| from .. import settings | |
| logger = logging.getLogger(__name__) | |
| MIN_CROP_SIZE = 50 | |
| # Import backends to trigger registration | |
| from .backends import yolos, yolov8, grounding_dino # noqa: F401, E402 | |
| def detect_garments(image_path: str, backend: str | None = None) -> list[BoundingBox]: | |
| """Detect garment regions in an image. | |
| Uses the configured backend (from settings) unless overridden. | |
| Returns a list of BoundingBox — does NOT classify garments. | |
| """ | |
| if backend is None: | |
| backend = settings.get("detection_backend") | |
| detector = get_backend(backend) | |
| boxes = detector.detect(image_path) | |
| valid = [b for b in boxes if b.width >= MIN_CROP_SIZE and b.height >= MIN_CROP_SIZE] | |
| logger.info( | |
| "Detected %d regions (%d valid, %d too small) via '%s' in: %s", | |
| len(boxes), len(valid), len(boxes) - len(valid), backend, image_path, | |
| ) | |
| return valid | |
| def crop_garments( | |
| image_path: str, | |
| boxes: list[BoundingBox], | |
| max_size: int = 512, | |
| ) -> list[bytes]: | |
| """Crop each bounding box from the image as JPEG bytes. | |
| Pure PIL logic — no model involved. Each crop is resized to fit | |
| within max_size pixels (longest side). | |
| """ | |
| img = Image.open(image_path).convert("RGB") | |
| crops = [] | |
| for box in boxes: | |
| cropped = img.crop((box.x1, box.y1, box.x2, box.y2)) | |
| cropped.thumbnail((max_size, max_size), Image.LANCZOS) | |
| buffer = io.BytesIO() | |
| cropped.save(buffer, format="JPEG", quality=85) | |
| crops.append(buffer.getvalue()) | |
| return crops | |
| def detect_and_crop(image_path: str, backend: str | None = None) -> list[bytes]: | |
| """Convenience: detect + crop in one call. | |
| Maintains backward compatibility with vision.py imports. | |
| """ | |
| boxes = detect_garments(image_path, backend) | |
| return crop_garments(image_path, boxes) | |
| __all__ = [ | |
| "BoundingBox", | |
| "DetectorBackend", | |
| "detect_garments", | |
| "crop_garments", | |
| "detect_and_crop", | |
| "list_available", | |
| "register", | |
| ] | |