53 lines
1.6 KiB
Python
53 lines
1.6 KiB
Python
import cv2
|
|
import numpy as np
|
|
from PIL import Image
|
|
|
|
def is_blurry(image: np.ndarray, threshold: float = 100.0) -> bool:
|
|
"""
|
|
Checks if an image is blurry using the Laplacian variance method.
|
|
|
|
Args:
|
|
image (np.ndarray): The image to check (BGR format).
|
|
threshold (float): The variance threshold below which the image is considered blurry.
|
|
|
|
Returns:
|
|
bool: True if blurry, False otherwise.
|
|
"""
|
|
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
|
variance = cv2.Laplacian(gray, cv2.CV_64F).var()
|
|
return variance < threshold
|
|
|
|
def crop_image(frame: np.ndarray, bbox: list[float], padding_percent: float = 0.1) -> np.ndarray:
|
|
"""
|
|
Crops an image based on a bounding box with optional padding.
|
|
|
|
Args:
|
|
frame (np.ndarray): The full image frame.
|
|
bbox (list): [x1, y1, x2, y2]
|
|
padding_percent (float): Percentage of padding to add around the box.
|
|
|
|
Returns:
|
|
np.ndarray: The cropped image.
|
|
"""
|
|
h, w, _ = frame.shape
|
|
x1, y1, x2, y2 = bbox
|
|
|
|
width = x2 - x1
|
|
height = y2 - y1
|
|
|
|
pad_w = width * padding_percent
|
|
pad_h = height * padding_percent
|
|
|
|
# Apply padding ensuring we stay within frame boundaries
|
|
new_x1 = max(0, int(x1 - pad_w))
|
|
new_y1 = max(0, int(y1 - pad_h))
|
|
new_x2 = min(w, int(x2 + pad_w))
|
|
new_y2 = min(h, int(y2 + pad_h))
|
|
|
|
return frame[new_y1:new_y2, new_x1:new_x2]
|
|
|
|
def convert_cv2_to_pil(cv2_image: np.ndarray) -> Image.Image:
|
|
"""Conventional cv2 BGR to PIL RGB conversion."""
|
|
color_converted = cv2.cvtColor(cv2_image, cv2.COLOR_BGR2RGB)
|
|
return Image.fromarray(color_converted)
|