STY: Cleanups after Tony's review.

This commit is contained in:
Stefan van der Walt
2012-05-04 11:50:13 -07:00
parent e13cc2541f
commit a5d8593408
4 changed files with 49 additions and 31 deletions
+4 -4
View File
@@ -36,7 +36,6 @@ The corresponding call to warp is::
The swirl transformation
````````````````````````
Consider the coordinate :math:`(x, y)` in the output image. The reverse
mapping for the swirl transformation first computes, relative to a center
:math:`(x_0, y_0)`, its polar coordinates,
@@ -60,9 +59,10 @@ and then transforms them according to
\theta' = \phi + s \, e^{-\rho / r + \theta}
where ``strength`` is a parameter for the amount of swirl, ``radius`` indicates
the extent of the transform in pixels, and ``rotation`` adds a rotation angle.
The transformation of ``radius`` into :math:`r` is to ensure that the
transformation decays to :math:`\approx 1/1000^{\mathsf{th}}` within the specified radius.
the swirl extent in pixels, and ``rotation`` adds a rotation angle. The
transformation of ``radius`` into :math:`r` is to ensure that the
transformation decays to :math:`\approx 1/1000^{\mathsf{th}}` within the
specified radius.
"""
from skimage import data
+11 -7
View File
@@ -7,9 +7,12 @@ 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)
rho = np.sqrt((x - x0)**2 + (y - y0)**2)
theta = rotation + strength * \
np.exp(-rho / radius) + \
np.arctan2(y - y0, x - x0)
@@ -32,8 +35,8 @@ def swirl(image, center=None, strength=1, radius=100, rotation=0,
strength : float
The amount of swirling applied.
radius : float
The extent of the swirling in pixels. The effect dies out
rapidly beyond radius.
The extent of the swirl in pixels. The effect dies out
rapidly beyond `radius`.
rotation : float
Additional rotation applied to the image.
@@ -47,10 +50,11 @@ def swirl(image, center=None, strength=1, radius=100, rotation=0,
output_shape : tuple or ndarray
Size of the generated output image.
order : int
Order of splines used in interpolation, passed as-is to ndimage.
Order of splines used in interpolation. See
`scipy.ndimage.map_coordinates` for detail.
mode : string
How to handle values outside the image borders, passed as-is
to ndimage.
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.
@@ -65,6 +69,6 @@ def swirl(image, center=None, strength=1, radius=100, rotation=0,
'strength': strength,
'radius': radius}
return warp(image, _swirl_mapping, tf_args=warp_args,
return warp(image, _swirl_mapping, map_args=warp_args,
output_shape=output_shape,
order=order, mode=mode, cval=cval)
+31 -16
View File
@@ -7,13 +7,21 @@ from skimage.util import img_as_float
eps = np.finfo(float).eps
def _stackcopy(a, b):
"""a[:,:,0] = a[:,:,1] = ... = b"""
"""Copy b into each color layer of a, such that::
a[:,:,0] = a[:,:,1] = ... = b
Notes
-----
Color images are stored as an ``MxNx3`` or ``MxNx4`` arrays.
"""
if a.ndim == 3:
a.transpose().swapaxes(1, 2)[:] = b
else:
a[:] = b
def warp(image, coord_tf, tf_args={},
def warp(image, reverse_map, map_args={},
output_shape=None, order=1, mode='constant', cval=0.):
"""Warp an image according to a given coordinate transformation.
@@ -21,20 +29,20 @@ def warp(image, coord_tf, tf_args={},
----------
image : 2-D array
Input image.
coord_tf : callable xy = f(xy, **kwargs)
Function that transforms an Nx2 array of ``(x, y)`` coordinates
in the *output image* into their corresponding coordinates in the
*source image*. Note that this is a reverse mapping (also
see examples below).
tf_args : dict, optional
Keyword arguments passed to `coord_tf`.
reverse_map : callable xy = f(xy, **kwargs)
Reverse coordinate map. A function that transforms an Nx2 array of
``(x, y)`` coordinates in the *output image* into their corresponding
coordinates in the *source image*. Also see examples below.
map_args : dict, optional
Keyword arguments passed to `reverse_map`.
output_shape : tuple (rows, cols)
Shape of the output image generated.
order : int
Order of splines used in interpolation.
Order of splines used in interpolation. See
`scipy.ndimage.map_coordinates` for detail.
mode : string
How to handle values outside the image borders. Passed as-is
to ndimage.
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.
@@ -65,17 +73,24 @@ def warp(image, coord_tf, tf_args={},
coords = np.empty(np.r_[3, output_shape], dtype=float)
# Construct transformed coordinates
## Construct transformed coordinates
rows, cols = output_shape[:2]
# Reshape grid coordinates into a (P, 2) array of (x, y) pairs
tf_coords = np.indices((cols, rows), dtype=float).reshape(2, -1).T
tf_coords = coord_tf(tf_coords, **tf_args)
# Map each (x, y) pair to the source image according to
# the user-provided mapping
tf_coords = reverse_map(tf_coords, **map_args)
# Reshape back to a (2, M, N) coordinate grid
tf_coords = tf_coords.T.reshape((-1, cols, rows)).swapaxes(1, 2)
# y-coordinate mapping
# Place the y-coordinate mapping
_stackcopy(coords[1, ...], tf_coords[0, ...])
# x-coordinate mapping
# Place the x-coordinate mapping
_stackcopy(coords[0, ...], tf_coords[1, ...])
# colour-coordinate mapping
+3 -4
View File
@@ -6,11 +6,10 @@ from skimage import transform as tf, data, img_as_float
def test_roundtrip():
image = img_as_float(data.checkerboard())
swirl_params = {'radius': 80, 'rotation': 0, 'order': 2, 'mode': 'reflect'}
unswirled = tf.swirl(
tf.swirl(image, strength=10, **swirl_params),
strength=-10, **swirl_params
)
swirled = tf.swirl(image, strength=10, **swirl_params)
unswirled = tf.swirl(swirled, strength=-10, **swirl_params)
assert np.mean(np.abs(image - unswirled)) < 0.01