mirror of
https://github.com/SikongJueluo/Mini-Nav.git
synced 2026-07-12 20:15:31 +08:00
- 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
74 lines
1.9 KiB
Python
74 lines
1.9 KiB
Python
"""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 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.
|
|
|
|
Args:
|
|
rgb: Numpy array of shape (H, W, C) with dtype uint8 or compatible.
|
|
|
|
Returns:
|
|
PIL Image in RGB mode.
|
|
"""
|
|
rgb3 = rgb[..., :3] if rgb.shape[-1] > 3 else rgb
|
|
return Image.fromarray(rgb3.astype(np.uint8))
|