mirror of
https://github.com/SikongJueluo/Mini-Nav.git
synced 2026-07-13 04:25:32 +08:00
feat(compressors): add OWLv2 bbox crop to HashPipeline and refactor image utilities
- Add crop_batch method to HashPipeline for cropping images using OWLv2 detection boxes - Integrate crop_batch into pipeline forward pass (extract_hash and extract_features) - Move extract_masked_region from compressors/proposal/utils.py to utils/image.py - Add crop_image_by_bbox utility function in utils/image.py - Update type annotations to use dict[str, Any] instead of bare dict - Update .justfile to add memory server command - Update marimo dependency to >=0.22.0 - Update nvidia CUDA package markers for platform compatibility
This commit is contained in:
@@ -1,12 +1,64 @@
|
||||
"""Image conversion utilities."""
|
||||
"""Image utilities for conversion, masking, and cropping."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
import numpy as np
|
||||
from numpy.typing import NDArray
|
||||
from PIL import Image
|
||||
|
||||
|
||||
def numpy_to_pil(rgb: np.ndarray) -> Image.Image:
|
||||
def extract_masked_region(
|
||||
image: Image.Image,
|
||||
mask: NDArray[np.bool_],
|
||||
) -> 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"))
|
||||
masked_np = image_np * mask[:, :, np.newaxis]
|
||||
return Image.fromarray(masked_np.astype(np.uint8))
|
||||
|
||||
|
||||
def crop_image_by_bbox(
|
||||
image: Image.Image,
|
||||
bbox: Sequence[float],
|
||||
) -> Image.Image:
|
||||
"""Crop an image by bounding box [x1, y1, x2, y2].
|
||||
|
||||
Args:
|
||||
image: Source PIL image.
|
||||
bbox: OWLv2-style box coordinates [x1, y1, x2, y2].
|
||||
|
||||
Returns:
|
||||
Cropped PIL image. Returns the original image when bbox is invalid.
|
||||
"""
|
||||
if len(bbox) != 4:
|
||||
return image
|
||||
|
||||
x1, y1, x2, y2 = tuple(float(v) for v in bbox)
|
||||
if not np.isfinite([x1, y1, x2, y2]).all():
|
||||
return image
|
||||
|
||||
left = max(0, int(np.floor(x1)))
|
||||
top = max(0, int(np.floor(y1)))
|
||||
right = min(image.width, int(np.ceil(x2)))
|
||||
bottom = min(image.height, int(np.ceil(y2)))
|
||||
|
||||
if right <= left or bottom <= top:
|
||||
return image
|
||||
|
||||
return image.crop((left, top, right, bottom))
|
||||
|
||||
|
||||
def numpy_to_pil(rgb: NDArray[np.uint8]) -> Image.Image:
|
||||
"""Convert an RGB numpy array to a PIL Image.
|
||||
|
||||
Handles arrays with 4 channels (RGBA) by dropping the alpha channel.
|
||||
|
||||
Reference in New Issue
Block a user