# Image Class Usage Guide The `Image` class provides a convenient way to load and work with images in the microscopy object detection application. ## Supported Formats The Image class supports the following image formats: - `.jpg`, `.jpeg` - JPEG images - `.png` - PNG images - `.tif`, `.tiff` - TIFF images (commonly used in microscopy) - `.bmp` - Bitmap images ## Basic Usage ### Loading an Image ```python from src.utils import Image, ImageLoadError # Load an image from a file path try: img = Image("path/to/image.jpg") print(f"Loaded image: {img.width}x{img.height} pixels") except ImageLoadError as e: print(f"Failed to load image: {e}") ``` ### Accessing Image Properties ```python img = Image("microscopy_image.tif") # Basic properties print(f"Width: {img.width} pixels") print(f"Height: {img.height} pixels") print(f"Channels: {img.channels}") print(f"Format: {img.format}") print(f"Shape: {img.shape}") # (height, width, channels) # File information print(f"File size: {img.size_mb:.2f} MB") print(f"File size: {img.size_bytes} bytes") # Image type checks print(f"Is color: {img.is_color()}") print(f"Is grayscale: {img.is_grayscale()}") # String representation print(img) # Shows summary of image properties ``` ### Working with Image Data ```python import numpy as np img = Image("sample.png") # Get image data as numpy array (OpenCV format, BGR) bgr_data = img.data print(f"Data shape: {bgr_data.shape}") print(f"Data type: {bgr_data.dtype}") # Get image as RGB (for display or processing) rgb_data = img.get_rgb() # Get grayscale version gray_data = img.get_grayscale() # Create a copy (for modifications) img_copy = img.copy() img_copy[0, 0] = [255, 255, 255] # Modify copy, original unchanged # Resize image (returns new array, doesn't modify original) resized = img.resize(640, 640) ``` ### Using PIL Image ```python img = Image("photo.jpg") # Access as PIL Image (RGB format) pil_img = img.pil_image # Use PIL methods pil_img.show() # Display image pil_img.save("output.png") # Save with PIL ``` ## Integration with YOLO ```python from src.utils import Image from ultralytics import YOLO # Load model and image model = YOLO("yolov8n.pt") img = Image("microscopy/cell_01.tif") # Run inference (YOLO accepts file paths or numpy arrays) results = model(img.data) # Or use the file path directly results = model(str(img.path)) ``` ## Error Handling ```python from src.utils import Image, ImageLoadError def process_image(image_path): try: img = Image(image_path) # Process the image... return img except ImageLoadError as e: print(f"Cannot load image: {e}") return None ``` ## Advanced Usage ### Batch Processing ```python from pathlib import Path from src.utils import Image, ImageLoadError def process_image_directory(directory): """Process all images in a directory.""" image_paths = Path(directory).glob("*.tif") for path in image_paths: try: img = Image(path) print(f"Processing {img.path.name}: {img.width}x{img.height}") # Process the image... except ImageLoadError as e: print(f"Skipping {path}: {e}") ``` ### Using with OpenCV Operations ```python import cv2 from src.utils import Image img = Image("input.jpg") # Apply OpenCV operations on the data blurred = cv2.GaussianBlur(img.data, (5, 5), 0) edges = cv2.Canny(img.data, 100, 200) # Note: These operations don't modify the original img.data ``` ### Memory Efficient Processing ```python from src.utils import Image # The Image class loads data into memory img = Image("large_image.tif") print(f"Image size in memory: {img.data.nbytes / (1024**2):.2f} MB") # When processing many images, consider loading one at a time # and releasing memory by deleting the object del img ``` ## Best Practices 1. **Always use try-except** when loading images to handle errors gracefully 2. **Check image properties** before processing to ensure compatibility 3. **Use copy()** when you need to modify image data without affecting the original 4. **Path objects work too** - The class accepts both strings and Path objects 5. **Consider memory usage** when working with large images or batches ## Example: Complete Workflow ```python from src.utils import Image, ImageLoadError from src.utils.file_utils import get_image_files def analyze_microscopy_images(directory): """Analyze all microscopy images in a directory.""" # Get all image files image_files = get_image_files(directory, recursive=True) results = [] for image_path in image_files: try: # Load image img = Image(image_path) # Analyze result = { 'filename': img.path.name, 'width': img.width, 'height': img.height, 'channels': img.channels, 'format': img.format, 'size_mb': img.size_mb, 'is_color': img.is_color() } results.append(result) print(f"✓ Analyzed {img.path.name}") except ImageLoadError as e: print(f"✗ Failed to load {image_path}: {e}") return results # Run analysis results = analyze_microscopy_images("data/datasets/cells") print(f"\nProcessed {len(results)} images")