Source code for IQM_Vis.transforms.affine

'''
affine (geometric) transformations
'''
# Author: Matt Clifford <matt.clifford@bristol.ac.uk>
# License: BSD 3-Clause License
import numpy as np
from skimage.transform import resize, rotate


[docs]def rotation(image, angle=0): '''Rotate an image around its centre. Uses skimage.transform.rotate. Areas that are rotated beyond the image are filled in with black pixel values Args: image (np.array): image to be rotated angle (float): amount of rotation in degrees (Defaults to 0) Returns: image (np.array): rotated image ''' if angle == 0: return image return np.clip(rotate(image, angle, order=3), 0, 1)
[docs]def x_shift(image, x_shift=0): '''Translate image horizontally Args: image (np.array): image to be shifted x_shift (float): shift proportion of the image in the range (-1, 1). (Defaults to 0) Returns: image (np.array): shifted image ''' if x_shift == 0: return image return _translate_image(image, x_shift, 0)
[docs]def y_shift(image, y_shift=0): '''Translate image vertically Args: image (np.array): image to be shifted y_shift (float): shift proportion of the image in the range (-1, 1). (Defaults to 0) Returns: image (np.array): shifted image ''' if y_shift == 0: return image return _translate_image(image, 0, y_shift)
def _translate_image(image, x_shift=0, y_shift=0): '''Translate image vertically Args: image (np.array): image to be shifted x_shift (float): shift proportion of the image in the range (-1, 1). (Defaults to 0) y_shift (float): shift proportion of the image in the range (-1, 1). (Defaults to 0) Returns: image (np.array): shifted image ''' if x_shift == 0 and y_shift == 0: return image original_size = image.shape canvas = np.zeros(original_size, dtype=image.dtype) prop_x = int(original_size[1]*abs(x_shift)) prop_y = int(original_size[0]*abs(y_shift)) # make sure we dont go off the canvas if original_size[1] - prop_x < 1 or original_size[0] - prop_y < 1: return canvas if y_shift >= 0 and x_shift >= 0: canvas[prop_y:, prop_x:, :] = image[:original_size[0] - prop_y, :original_size[1]-prop_x, :] elif y_shift < 0 and x_shift >= 0: canvas[:original_size[0]-prop_y, prop_x:, :] = image[prop_y - original_size[0]:, :original_size[1]-prop_x, :] elif y_shift >= 0 and x_shift < 0: canvas[prop_y:, :original_size[1]-prop_x, :] = image[:original_size[0]-prop_y, prop_x-original_size[1]:, :] elif y_shift < 0 and x_shift < 0: canvas[:original_size[0]-prop_y:, :original_size[1]-prop_x, :] = image[prop_y-original_size[0]:, prop_x-original_size[1]:, :] return np.clip(canvas, 0, 1)
[docs]def zoom_image(image, scale_factor=1): '''digital zoom of image Args: image (np.array): image to be zoomed scale_factor (float): the percentage to zoom in by (for square zoom only). 0.5 = 2x zoom out 1 = normal size 2 = 2x zoom in (Defaults to 1) Returns: image (np.array): zoomed image ''' if scale_factor == 1: return image original_size = image.shape new_size_x = int(original_size[0]/scale_factor) new_size_y = int(original_size[1]/scale_factor) if scale_factor > 1: start_point_x = int((original_size[0] - new_size_x)/2) start_point_y = int((original_size[1] - new_size_y)/2) image = image[start_point_x:start_point_x+new_size_x, start_point_y:start_point_y+new_size_y, :] elif scale_factor < 1: new_size = (new_size_x, new_size_y, original_size[2]) if len( original_size) == 3 else (new_size_x, new_size_y) start_point_x = int((new_size_x - original_size[0])/2) start_point_y = int((new_size_y - original_size[1])/2) zoomed_out = np.zeros(new_size, dtype=image.dtype) zoomed_out[start_point_x:start_point_x+original_size[0], start_point_y:start_point_y+original_size[1], :] = image image = zoomed_out return np.clip(resize(image, original_size), 0, 1)