Source code for dask_image.ndinterp._rotate

# -*- coding: utf-8 -*-

import dask.array as da
import numpy as np
from scipy.special import sindg, cosdg

from ._affine_transform import affine_transform


[docs]def rotate( input_arr, angle, axes=(1, 0), reshape=True, output_chunks=None, **kwargs, ): """Rotate an array using Dask. The array is rotated in the plane defined by the two axes given by the `axes` parameter using spline interpolation of the requested order. Chunkwise processing is performed using `dask_image.ndinterp.affine_transform`, for which further parameters supported by the ndimage functions can be passed as keyword arguments. Notes ----- Differences to `ndimage.rotate`: - currently, prefiltering is not supported (affecting the output in case of interpolation `order > 1`) - default order is 1 - modes 'reflect', 'mirror' and 'wrap' are not supported Arguments are equal to `ndimage.rotate` except for - `output` (not present here) - `output_chunks` (relevant in the dask array context) Parameters ---------- input_arr : array_like (Numpy Array, Cupy Array, Dask Array...) The image array. angle : float The rotation angle in degrees. axes : tuple of 2 ints, optional The two axes that define the plane of rotation. Default is the first two axes. reshape : bool, optional If `reshape` is true, the output shape is adapted so that the input array is contained completely in the output. Default is True. output_chunks : tuple of ints, optional The shape of the chunks of the output Dask Array. **kwargs : dict, optional Additional keyword arguments are passed to `dask_image.ndinterp.affine_transform`. Returns ------- rotate : Dask Array A dask array representing the rotated input. Examples -------- >>> from scipy import ndimage, misc >>> import matplotlib.pyplot as plt >>> import dask.array as da >>> fig = plt.figure(figsize=(10, 3)) >>> ax1, ax2, ax3 = fig.subplots(1, 3) >>> img = da.from_array(misc.ascent(),chunks=(64,64)) >>> img_45 = dask_image.ndinterp.rotate(img, 45, reshape=False) >>> full_img_45 = dask_image.ndinterp.rotate(img, 45, reshape=True) >>> ax1.imshow(img, cmap='gray') >>> ax1.set_axis_off() >>> ax2.imshow(img_45, cmap='gray') >>> ax2.set_axis_off() >>> ax3.imshow(full_img_45, cmap='gray') >>> ax3.set_axis_off() >>> fig.set_tight_layout(True) >>> plt.show() >>> print(img.shape) (512, 512) >>> print(img_45.shape) (512, 512) >>> print(full_img_45.shape) (724, 724) """ if not isinstance(input_arr, da.core.Array): input_arr = da.from_array(input_arr) if output_chunks is None: output_chunks = input_arr.chunksize ndim = input_arr.ndim if ndim < 2: raise ValueError('input array should be at least 2D') axes = list(axes) if len(axes) != 2: raise ValueError('axes should contain exactly two values') if not all([float(ax).is_integer() for ax in axes]): raise ValueError('axes should contain only integer values') if axes[0] < 0: axes[0] += ndim if axes[1] < 0: axes[1] += ndim if axes[0] < 0 or axes[1] < 0 or axes[0] >= ndim or axes[1] >= ndim: raise ValueError('invalid rotation plane specified') axes.sort() c, s = cosdg(angle), sindg(angle) rot_matrix = np.array([[c, s], [-s, c]]) img_shape = np.asarray(input_arr.shape) in_plane_shape = img_shape[axes] if reshape: # Compute transformed input bounds iy, ix = in_plane_shape in_bounds = np.array([[0, 0, iy, iy], [0, ix, 0, ix]]) out_bounds = rot_matrix @ in_bounds # Compute the shape of the transformed input plane out_plane_shape = (np.ptp(out_bounds, axis=1) + 0.5).astype(int) else: out_plane_shape = img_shape[axes] output_shape = np.array(img_shape) output_shape[axes] = out_plane_shape output_shape = tuple(output_shape) out_center = rot_matrix @ ((out_plane_shape - 1) / 2) in_center = (in_plane_shape - 1) / 2 offset = in_center - out_center matrix_nd = np.eye(ndim) offset_nd = np.zeros(ndim) for o_x, idx in enumerate(axes): matrix_nd[idx, axes[0]] = rot_matrix[o_x, 0] matrix_nd[idx, axes[1]] = rot_matrix[o_x, 1] offset_nd[idx] = offset[o_x] output = affine_transform( input_arr, matrix=matrix_nd, offset=offset_nd, output_shape=output_shape, output_chunks=output_chunks, **kwargs, ) return output