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 radius = radius / 5 * np.log(2) rho = np.sqrt((x - x0)**2 + (y - y0)**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 swirling 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, passed as-is to ndimage. mode : string How to handle values outside the image borders, passed as-is to ndimage. 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, tf_args=warp_args, output_shape=output_shape, order=order, mode=mode, cval=cval)