SmokeSignal-AI / utils /preprocess.py
dhyann2815's picture
refactor: dependencies
d43b896
Raw History Blame Contribute Delete
4.13 kB
#preprocess.py
#This file is used to preprocess the image before it is fed into the model.
import numpy as np
from PIL import Image
def normalize_image(image_input, target_size=None):
"""
Normalizes an image by scaling pixel values to the range [0, 1].
Works with both file paths and PIL images.
Args:
image_input (str or PIL.Image): The image file path or PIL Image object.
target_size (tuple, optional): Target size as (width, height) for resizing.
Returns:
numpy.ndarray: The normalized image as a NumPy array, or None if the image cannot be processed.
"""
try:
# Handle different input types
if isinstance(image_input, str):
# Load from file path using PIL
img_pil = Image.open(image_input)
img = np.array(img_pil)
elif isinstance(image_input, Image.Image):
# Convert PIL image to numpy array
img = np.array(image_input)
else:
print(f"Error: Unsupported image input type: {type(image_input)}")
return None
# Resize if target size is specified
if target_size is not None:
# Use PIL resize for all cases
img_pil = Image.fromarray(img)
img_pil = img_pil.resize(target_size)
img = np.array(img_pil)
# Convert the image to float32 for accurate calculations
img = img.astype(np.float32)
# Normalize the image to the range [0, 1]
normalized_img = img / 255.0
return normalized_img
except Exception as e:
print(f"Error processing image: {e}")
return None
def preprocess_for_model(image_input, model_input_shape):
"""
Preprocess image specifically for model input.
Args:
image_input (str or PIL.Image): The image to preprocess
model_input_shape (tuple): Expected model input shape (height, width, channels)
Returns:
numpy.ndarray: Preprocessed image ready for model input
"""
try:
# Extract target size from model input shape
if len(model_input_shape) == 3:
target_size = (model_input_shape[1], model_input_shape[0]) # (width, height)
else:
target_size = None
# Normalize image
normalized_img = normalize_image(image_input, target_size)
if normalized_img is None:
return None
# Add batch dimension if needed
if len(model_input_shape) == 3:
# For image models: (batch, height, width, channels)
preprocessed = np.expand_dims(normalized_img, axis=0)
elif len(model_input_shape) == 2:
# For flattened models: (batch, features)
preprocessed = normalized_img.reshape(1, -1)
else:
raise ValueError(f"Unsupported model input shape: {model_input_shape}")
return preprocessed
except Exception as e:
print(f"Error preprocessing image for model: {e}")
return None
def get_image_info(image_input):
"""
Get basic information about an image.
Args:
image_input (str or PIL.Image): The image to analyze
Returns:
dict: Dictionary containing image information
"""
try:
if isinstance(image_input, str):
# Use PIL for file paths
img_pil = Image.open(image_input)
width, height = img_pil.size
channels = len(img_pil.getbands())
format_type = "File (PIL)"
elif isinstance(image_input, Image.Image):
width, height = image_input.size
channels = len(image_input.getbands())
format_type = "PIL Image"
else:
return None
return {
"format": format_type,
"width": width,
"height": height,
"channels": channels,
"aspect_ratio": width / height if height > 0 else 0
}
except Exception as e:
print(f"Error getting image info: {e}")
return None