from __future__ import division import numpy as np from ._warp import warp def _swirl_mapping(xy, center, rotation, strength, radius): x, y = xy.T x0, y0 = center rho = np.sqrt((x - x0)**2 + (y - y0)**2) # Ensure that the transformation decays to approximately 1/1000-th # within the specified radius. radius = radius / 5 * np.log(2) theta = rotation + strength * \ np.exp(-rho / radius) + \ np.arctan2(y - y0, x - x0) xy[..., 0] = x0 + rho * np.cos(theta) xy[..., 1] = y0 + rho * np.sin(theta) return xy def swirl(image, center=None, strength=1, radius=100, rotation=0, output_shape=None, order=1, mode='constant', cval=0): """Perform a swirl transformation. Parameters ---------- image : ndarray Input image. center : (x,y) tuple or (2,) ndarray Center coordinate of transformation. strength : float The amount of swirling applied. radius : float The extent of the swirl in pixels. The effect dies out rapidly beyond `radius`. rotation : float Additional rotation applied to the image. Returns ------- swirled : ndarray Swirled version of the input. Other parameters ---------------- output_shape : tuple or ndarray Size of the generated output image. order : int Order of splines used in interpolation. See `scipy.ndimage.map_coordinates` for detail. mode : string How to handle values outside the image borders. See `scipy.ndimage.map_coordinates` for detail. cval : string Used in conjunction with mode 'constant', the value outside the image boundaries. """ if center is None: center = np.array(image.shape)[:2] / 2 warp_args = {'center': center, 'rotation': rotation, 'strength': strength, 'radius': radius} return warp(image, _swirl_mapping, map_args=warp_args, output_shape=output_shape, order=order, mode=mode, cval=cval)