Source code for stouputils.data_science.data_processing.image.translation


# Imports
from .common import Any, NDArray, check_image, cv2, np


# Functions
[docs] def translate_image(image: NDArray[Any], x: float, y: float, padding: int = 0, ignore_dtype: bool = False) -> NDArray[Any]: """ Translate an image Args: image (NDArray[Any]): Image to translate x (float): Translation along the x axis (between -1 and 1) y (float): Translation along the y axis (between -1 and 1) padding (int): Padding that has been added to the image before calling this function ignore_dtype (bool): Ignore the dtype check Returns: NDArray[Any]: Translated image >>> ## Basic tests >>> image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]).astype(np.uint8) >>> translate_image(image, 0.5, 0.5).tolist() [[0, 0, 0], [0, 1, 2], [0, 4, 5]] >>> translate_image(image, 0, -2/3).tolist() [[7, 8, 9], [0, 0, 0], [0, 0, 0]] >>> ## Test invalid inputs >>> translate_image(image, 2, 0) Traceback (most recent call last): ... AssertionError: x must be between -1 and 1, got 2 >>> translate_image(image, 0, 2) Traceback (most recent call last): ... AssertionError: y must be between -1 and 1, got 2 >>> translate_image("not an image", 0, 0) Traceback (most recent call last): ... AssertionError: Image must be a numpy array >>> translate_image(image, 0, 0, padding=-1) Traceback (most recent call last): ... AssertionError: padding must be positive, got -1 """ # Check input data check_image(image, ignore_dtype=ignore_dtype) assert isinstance(x, float | int), f"x must be a number, got {type(x)}" assert isinstance(y, float | int), f"y must be a number, got {type(y)}" assert -1 <= x <= 1, f"x must be between -1 and 1, got {x}" assert -1 <= y <= 1, f"y must be between -1 and 1, got {y}" assert isinstance(padding, int), f"padding must be an integer, got {type(padding)}" assert padding >= 0, f"padding must be positive, got {padding}" # Get image dimensions height, width = image.shape[:2] original_width: int = width - 2 * padding original_height: int = height - 2 * padding # Convert relative translations to absolute pixels x_pixels: int = int(x * original_width) y_pixels: int = int(y * original_height) # Create translation matrix translation_matrix: NDArray[Any] = np.array([[1, 0, x_pixels], [0, 1, y_pixels]], dtype=np.float32) # Apply affine transformation return cv2.warpAffine(image, translation_matrix, (width, height))