import cv2 import numpy as np from PIL import Image import matplotlib.pyplot as plt class ImageProcessor: def __init__(self): """ Initialize the image processor for handling image manipulation tasks """ pass @staticmethod def load_image(image_path): """ Load an image from a file path Args: image_path: Path to the image file Returns: Loaded image as numpy array in RGB format """ img = cv2.imread(image_path) if img is None: raise ValueError(f"Could not load image from {image_path}") return cv2.cvtColor(img, cv2.COLOR_BGR2RGB) @staticmethod def save_image(image, output_path): """ Save an image to a file Args: image: Image as numpy array in RGB format output_path: Path to save the image """ # Convert from RGB to BGR for OpenCV if len(image.shape) == 3 and image.shape[2] == 3: image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) cv2.imwrite(output_path, image) @staticmethod def resize_image(image, width=None, height=None): """ Resize an image while maintaining aspect ratio Args: image: Image as numpy array width: Target width (if None, calculated from height) height: Target height (if None, calculated from width) Returns: Resized image """ if width is None and height is None: return image h, w = image.shape[:2] if width is None: aspect = height / float(h) dim = (int(w * aspect), height) elif height is None: aspect = width / float(w) dim = (width, int(h * aspect)) else: dim = (width, height) return cv2.resize(image, dim, interpolation=cv2.INTER_AREA) @staticmethod def normalize_image(image): """ Normalize image values to 0-255 range Args: image: Input image Returns: Normalized image """ return cv2.normalize(image, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8) @staticmethod def apply_color_map(image, colormap=cv2.COLORMAP_JET): """ Apply a colormap to a grayscale image Args: image: Grayscale image colormap: OpenCV colormap type Returns: Color-mapped image """ if len(image.shape) == 3: image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) return cv2.applyColorMap(image, colormap) @staticmethod def overlay_images(background, overlay, alpha=0.5): """ Overlay one image on top of another with transparency Args: background: Background image overlay: Image to overlay alpha: Transparency factor (0-1) Returns: Combined image """ # Ensure images are the same size if background.shape != overlay.shape: overlay = cv2.resize(overlay, (background.shape[1], background.shape[0])) # Blend images return cv2.addWeighted(background, 1-alpha, overlay, alpha, 0) @staticmethod def crop_image(image, x, y, width, height): """ Crop a region from an image Args: image: Input image x, y: Top-left corner coordinates width, height: Dimensions of the crop Returns: Cropped image """ return image[y:y+height, x:x+width] @staticmethod def display_images(images, titles=None, figsize=(15, 10)): """ Display multiple images in a grid Args: images: List of images to display titles: List of titles for each image figsize: Figure size (width, height) """ n = len(images) if titles is None: titles = [f'Image {i+1}' for i in range(n)] fig, axes = plt.subplots(1, n, figsize=figsize) if n == 1: axes = [axes] for i, (img, title) in enumerate(zip(images, titles)): if len(img.shape) == 2 or img.shape[2] == 1: # Grayscale axes[i].imshow(img, cmap='gray') else: # Color axes[i].imshow(img) axes[i].set_title(title) axes[i].axis('off') plt.tight_layout() return fig