ai-art-director / filters.py
Alexandros Popov
added test image.
fa24889
raw
history blame
5.21 kB
import cv2
import numpy as np
from PIL import Image
from smolagents import tool
import tempfile
import os
def apply_filters(image: np.ndarray) -> list[np.ndarray]:
"""Applies a series of filters to the input image.
Args:
image (np.ndarray): Input image in BGR format.
Returns:
list[np.ndarray]: List of filtered images in BGR format.
"""
filtered_images = []
# Filter 1: Contrast adjustment
filtered_images.append(adjust_contrast(image))
# Filter 2: Saturation boost
filtered_images.append(adjust_saturation(image))
# Filter 3: Exposure adjustment
filtered_images.append(adjust_exposure(image))
# Filter 4: Denoised
filtered_images.append(denoise_image(image))
# Filter 5: Vignette effect
filtered_images.append(apply_vignette(image))
return filtered_images
@tool
def adjust_contrast(image: np.ndarray, alpha: float = 1.5) -> np.ndarray:
"""Adjusts the contrast of the image.
Args:
image (np.ndarray): Input image in BGR format.
alpha (float, optional): Contrast control (1.0-3.0). 1.0 means no change. Defaults to 1.5.
Returns:
np.ndarray: Contrast adjusted image in BGR format.
"""
return cv2.convertScaleAbs(image, alpha=alpha, beta=0)
@tool
def adjust_saturation(image: np.ndarray, saturation_scale: float = 1.0) -> np.ndarray:
"""Adjusts the saturation of the image.
Args:
image (np.ndarray): Input image in BGR format.
saturation_scale (float, optional): Saturation scale factor. 1.0 means no change. Defaults to 1.0.
Returns:
np.ndarray: Saturation adjusted image in BGR format.
"""
hsv_img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV).astype(np.float32)
hsv_img[:, :, 1] *= saturation_scale
hsv_img[:, :, 1] = np.clip(hsv_img[:, :, 1], 0, 255)
return cv2.cvtColor(hsv_img.astype(np.uint8), cv2.COLOR_HSV2BGR)
@tool
def adjust_exposure(image: np.ndarray, beta: int = 50) -> np.ndarray:
"""Adjusts the exposure (brightness) of the image.
Args:
image (np.ndarray): Input image in BGR format.
beta (int, optional): Brightness control. Positive values increase brightness, negative decrease. Defaults to 50.
Returns:
np.ndarray: Exposure adjusted image in BGR format.
"""
return cv2.convertScaleAbs(image, alpha=1.0, beta=beta)
@tool
def denoise_image(image: np.ndarray, h: int = 10) -> np.ndarray:
"""Denoises the image using Non-local Means Denoising algorithm.
Args:
image (np.ndarray): Input image in BGR format.
h (int, optional): Filter strength. Higher h value removes noise better but removes details. Defaults to 10.
Returns:
np.ndarray: Denoised image in BGR format.
"""
return cv2.fastNlMeansDenoisingColored(image, None, h, h, 7, 21)
@tool
def crop_image(image: np.ndarray, x: int, y: int, width: int, height: int) -> np.ndarray:
"""Crops the image to the specified rectangle.
Args:
image (np.ndarray): Input image in BGR format.
x (int): Top-left x-coordinate.
y (int): Top-left y-coordinate.
width (int): Width of the crop rectangle.
height (int): Height of the crop rectangle.
Returns:
np.ndarray: Cropped image in BGR format.
"""
return image[y:y+height, x:x+width]
@tool
def apply_vignette(image: np.ndarray, level: int = 2) -> np.ndarray:
"""Applies a vignette effect to the image.
Args:
image (np.ndarray): Input image in BGR format.
level (int, optional): Intensity of the vignette effect. Defaults to 2.
Returns:
np.ndarray: Image with vignette effect applied in BGR format.
"""
rows, cols = image.shape[:2]
kernel_x = cv2.getGaussianKernel(cols, cols/level)
kernel_y = cv2.getGaussianKernel(rows, rows/level)
kernel = kernel_y * kernel_x.T
mask = kernel / kernel.max()
vignette = np.copy(image)
for i in range(3):
vignette[:, :, i] = vignette[:, :, i] * mask
return vignette
@tool
def load_image_as_bgr(image_path: str) -> np.ndarray:
"""Loads an image from path and converts it to BGR format for OpenCV.
Args:
image_path (str): Path to the image file.
Returns:
np.ndarray: Image in BGR format as numpy array.
"""
image = Image.open(image_path)
image_np = np.array(image)
return cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
@tool
def save_image(image: np.ndarray, image_path: str) -> None:
"""Saves an image to the specified path.
Args:
image (np.ndarray): Image to save.
image_path (str): Path to save the image.
"""
cv2.imwrite(image_path, image)
if __name__ == "__main__":
# Load a test image
test_image_np = load_image_as_bgr("test_image.jpg")
# Apply all filters
filtered_images = apply_filters(test_image_np)
# Save results
dir = tempfile.mkdtemp()
for i, filtered_img in enumerate(filtered_images):
output_path = os.path.join(dir, f"filter_{i+1}.jpg")
rgb_img = cv2.cvtColor(filtered_img, cv2.COLOR_BGR2RGB)
Image.fromarray(rgb_img).save(output_path)
print(f"Saved {output_path}")