Affine transforms using Scipy#

In this section we demonstrate how to apply an affine transform using scipy.

import numpy as np
from skimage.io import imread, imshow
from scipy import ndimage as ndi
image = imread('../../data/Haase_MRT_tfl3d1.tif')
imshow(image[100])
image.shape
(192, 256, 256)
../_images/b9ec53895c9942461dd35e1b88b95a9557441ceb09c074bd865d8bb6ddfdb74b.png

Affine transforms are typically defines using transform matrices.

For example, we can enter a scaling factor into such a matrix like in the following. Typically, the inverse transform is managed in these matrices. In the case of scaling, we need to enter a scaling factor of 0.5 in case we want to increase the image size by factor 2. The reason is that the affine transform matrix defines the transform that needs to be applied from every pixel in the target image to every pixel in the source image. If the target image is twice as large as the source, we need to multiply target pixel coordinates with 0.5 to determine the corresponding source pixel coordinates.

# scaling by factor 1 / s
s = 0.5
matrix = np.asarray([
    [s, 0, 0, 0],
    [0, s, 0, 0],
    [0, 0, s, 0],
    [0, 0, 0, 1],
])

Before applying the transform, we also need to calculate the output image size (shape) and create that output image:

output_shape = tuple((np.asarray(image.shape) / s).astype(int))
scaled = np.ndarray(output_shape)
scaled.shape
(384, 512, 512)
result = ndi.affine_transform(image, matrix, output=scaled, output_shape=output_shape)
imshow(scaled[200], cmap="Greys_r", vmin=0)
<matplotlib.image.AxesImage at 0x14efd955df0>
../_images/278376013e6ab625f623e6a2b01e4906416b1740025c14410368b67414979692.png