110 lines
2.6 KiB
Python
110 lines
2.6 KiB
Python
"""Image quality assessment utilities."""
|
|
|
|
import numpy as np
|
|
from PIL import Image as PILImage
|
|
from scipy import ndimage
|
|
|
|
|
|
def calculate_blur_score(image_path: str) -> float:
|
|
"""
|
|
Calculate blur score using Laplacian variance.
|
|
Higher score = sharper image.
|
|
|
|
Args:
|
|
image_path: Path to image file
|
|
|
|
Returns:
|
|
Variance of Laplacian (higher = sharper)
|
|
"""
|
|
try:
|
|
img = PILImage.open(image_path).convert("L")
|
|
img_array = np.array(img)
|
|
laplacian = ndimage.laplace(img_array)
|
|
return float(np.var(laplacian))
|
|
except Exception:
|
|
return 0.0
|
|
|
|
|
|
def is_too_blurry(image_path: str, threshold: float = 100.0) -> bool:
|
|
"""
|
|
Check if image is too blurry for training.
|
|
|
|
Args:
|
|
image_path: Path to image file
|
|
threshold: Minimum acceptable blur score (default 100)
|
|
|
|
Returns:
|
|
True if image is too blurry
|
|
"""
|
|
score = calculate_blur_score(image_path)
|
|
return score < threshold
|
|
|
|
|
|
def get_image_dimensions(image_path: str) -> tuple[int, int]:
|
|
"""
|
|
Get image dimensions.
|
|
|
|
Args:
|
|
image_path: Path to image file
|
|
|
|
Returns:
|
|
Tuple of (width, height)
|
|
"""
|
|
try:
|
|
with PILImage.open(image_path) as img:
|
|
return img.size
|
|
except Exception:
|
|
return (0, 0)
|
|
|
|
|
|
def is_too_small(image_path: str, min_size: int = 256) -> bool:
|
|
"""
|
|
Check if image is too small for training.
|
|
|
|
Args:
|
|
image_path: Path to image file
|
|
min_size: Minimum dimension size (default 256)
|
|
|
|
Returns:
|
|
True if image is too small
|
|
"""
|
|
width, height = get_image_dimensions(image_path)
|
|
return width < min_size or height < min_size
|
|
|
|
|
|
def resize_image(
|
|
image_path: str,
|
|
output_path: str = None,
|
|
max_size: int = 512,
|
|
quality: int = 95,
|
|
) -> bool:
|
|
"""
|
|
Resize image to max dimension while preserving aspect ratio.
|
|
|
|
Args:
|
|
image_path: Path to input image
|
|
output_path: Path for output (defaults to overwriting input)
|
|
max_size: Maximum dimension size (default 512)
|
|
quality: JPEG quality (default 95)
|
|
|
|
Returns:
|
|
True if successful
|
|
"""
|
|
try:
|
|
output_path = output_path or image_path
|
|
|
|
with PILImage.open(image_path) as img:
|
|
# Only resize if larger than max_size
|
|
if max(img.size) > max_size:
|
|
img.thumbnail((max_size, max_size), PILImage.Resampling.LANCZOS)
|
|
|
|
# Convert to RGB if necessary (for JPEG)
|
|
if img.mode in ("RGBA", "P"):
|
|
img = img.convert("RGB")
|
|
|
|
img.save(output_path, "JPEG", quality=quality)
|
|
|
|
return True
|
|
except Exception:
|
|
return False
|