mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-14 11:18:06 +08:00
STY: Cleanups after Tony's review.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user