Source code for tike.operators.cupy.rotate

__author__ = "Daniel Ching"
__copyright__ = "Copyright (c) 2020, UChicago Argonne, LLC."
__docformat__ = 'restructuredtext en'

import numpy as np
import tike.precision

from .flow import _remap_lanczos
from .operator import Operator


[docs]class Rotate(Operator): """Rotate a stack of 2D images along last two dimensions. Parameters ---------- angle : float The desired rotation in radians. Operation skipped if angle is None. cval : complex64 The value to use for filling regions that rotated from outside the original image. """ def _make_grid(self, unrotated, angle): """Return the points on the rotated grid.""" cos, sin = np.cos(angle), np.sin(angle) shifti = (unrotated.shape[-2] - 1) / 2.0 shiftj = (unrotated.shape[-1] - 1) / 2.0 i, j = self.xp.mgrid[0:unrotated.shape[-2], 0:unrotated.shape[-1]].astype( tike.precision.floating) i -= shifti j -= shiftj i1 = (+cos * i + sin * j) + shifti j1 = (-sin * i + cos * j) + shiftj return self.xp.stack([i1.ravel(), j1.ravel()], axis=-1) def fwd(self, unrotated, angle, cval=0.0): if angle is None: return unrotated f = unrotated g = self.xp.zeros_like(f) # Compute rotated coordinates coords = self._make_grid(f, angle) # Reshape into stack of 2D images shape = f.shape h, w = shape[-2:] f = f.reshape(-1, h, w) g = g.reshape(-1, h * w) for i in range(len(f)): _remap_lanczos(f[i], coords, 2, g[i], fwd=True, cval=cval) return g.reshape(shape) def adj(self, rotated, angle, cval=0.0): if angle is None: return rotated g = rotated f = self.xp.zeros_like(g) # Compute rotated coordinates coords = self._make_grid(f, angle) # Reshape into stack of 2D images shape = f.shape h, w = shape[-2:] f = f.reshape(-1, h, w) g = g.reshape(-1, h * w) for i in range(len(f)): _remap_lanczos(f[i], coords, 2, g[i], fwd=False, cval=cval) return f.reshape(shape) def inv(self, rotated, angle, cval=0.0): return self.fwd( rotated, angle if angle is None else -angle, cval, )