mirror of
https://github.com/wassname/scikit-image.git
synced 2026-08-01 12:50:48 +08:00
@@ -684,9 +684,9 @@ def gray2rgb(image):
|
||||
"""
|
||||
if np.squeeze(image).ndim == 3 and image.shape[2] in (3, 4):
|
||||
return image
|
||||
elif is_gray(image):
|
||||
elif image.ndim != 1 and np.squeeze(image).ndim in (1, 2, 3):
|
||||
image = image[..., np.newaxis]
|
||||
return np.concatenate((image,)*3, axis=-1)
|
||||
return np.concatenate(3 * (image,), axis=-1)
|
||||
else:
|
||||
raise ValueError("Input image expected to be RGB, RGBA or gray.")
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ def _denoise_tv_chambolle_3d(im, weight=100, eps=2.e-4, n_iter_max=200):
|
||||
>>> mask = (x - 22)**2 + (y - 20)**2 + (z - 17)**2 < 8**2
|
||||
>>> mask = mask.astype(np.float)
|
||||
>>> mask += 0.2 * np.random.randn(*mask.shape)
|
||||
>>> res = denoise_tv(mask, weight=100)
|
||||
>>> res = denoise_tv_chambolle(mask, weight=100)
|
||||
|
||||
"""
|
||||
|
||||
@@ -127,7 +127,7 @@ def _denoise_tv_chambolle_2d(im, weight=50, eps=2.e-4, n_iter_max=200):
|
||||
>>> from skimage import color, data
|
||||
>>> lena = color.rgb2gray(data.lena())
|
||||
>>> lena += 0.5 * lena.std() * np.random.randn(*lena.shape)
|
||||
>>> denoised_lena = denoise_tv(lena, weight=60)
|
||||
>>> denoised_lena = denoise_tv_chambolle(lena, weight=60)
|
||||
|
||||
"""
|
||||
|
||||
@@ -227,7 +227,7 @@ def denoise_tv_chambolle(im, weight=50, eps=2.e-4, n_iter_max=200,
|
||||
>>> from skimage import color, data
|
||||
>>> lena = color.rgb2gray(data.lena())
|
||||
>>> lena += 0.5 * lena.std() * np.random.randn(*lena.shape)
|
||||
>>> denoised_lena = denoise_tv(lena, weight=60)
|
||||
>>> denoised_lena = denoise_tv_chambolle(lena, weight=60)
|
||||
|
||||
3D example on synthetic data:
|
||||
|
||||
@@ -235,7 +235,7 @@ def denoise_tv_chambolle(im, weight=50, eps=2.e-4, n_iter_max=200,
|
||||
>>> mask = (x - 22)**2 + (y - 20)**2 + (z - 17)**2 < 8**2
|
||||
>>> mask = mask.astype(np.float)
|
||||
>>> mask += 0.2*np.random.randn(*mask.shape)
|
||||
>>> res = denoise_tv(mask, weight=100)
|
||||
>>> res = denoise_tv_chambolle(mask, weight=100)
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -951,11 +951,11 @@ def warp(image, inverse_map=None, map_args={}, output_shape=None, order=1,
|
||||
----------
|
||||
image : 2-D or 3-D array
|
||||
Input image.
|
||||
inverse_map : transformation object, callable ``xy = f(xy, **kwargs)``
|
||||
inverse_map : transformation object, callable ``xy = f(xy, **kwargs)``, (3, 3) array
|
||||
Inverse coordinate map. A function that transforms a (N, 2) array of
|
||||
``(x, y)`` coordinates in the *output image* into their corresponding
|
||||
coordinates in the *source image* (e.g. a transformation object or its
|
||||
inverse).
|
||||
inverse). See example section for usage.
|
||||
map_args : dict, optional
|
||||
Keyword arguments passed to `inverse_map`.
|
||||
output_shape : tuple (rows, cols), optional
|
||||
@@ -976,26 +976,46 @@ def warp(image, inverse_map=None, map_args={}, output_shape=None, order=1,
|
||||
Used in conjunction with mode 'constant', the value outside
|
||||
the image boundaries.
|
||||
|
||||
Notes
|
||||
-----
|
||||
In case of a `SimilarityTransform`, `AffineTransform` and
|
||||
`ProjectiveTransform` and `order` in [0, 3] this function uses the
|
||||
underlying transformation matrix to warp the image with a much faster
|
||||
routine.
|
||||
|
||||
Examples
|
||||
--------
|
||||
Shift an image to the right:
|
||||
|
||||
>>> from skimage.transform import warp
|
||||
>>> from skimage import data
|
||||
>>> image = data.camera()
|
||||
>>>
|
||||
>>> def shift_right(xy):
|
||||
... xy[:, 0] -= 10
|
||||
... return xy
|
||||
>>>
|
||||
>>> warp(image, shift_right)
|
||||
|
||||
Use a geometric transform to warp an image:
|
||||
The following image warps are all equal but differ substantially in
|
||||
execution time.
|
||||
|
||||
Use a geometric transform to warp an image (fast):
|
||||
|
||||
>>> from skimage.transform import SimilarityTransform
|
||||
>>> tform = SimilarityTransform(scale=0.1, rotation=0.1)
|
||||
>>> tform = SimilarityTransform(translation=(0, -10))
|
||||
>>> warp(image, tform)
|
||||
|
||||
Shift an image to the right with a callable (slow):
|
||||
|
||||
>>> def shift(xy):
|
||||
... xy[:, 1] -= 10
|
||||
... return xy
|
||||
>>> warp(image, shift_right)
|
||||
|
||||
Use a transformation matrix to warp an image (fast):
|
||||
|
||||
>>> matrix = np.array([[1, 0, 0], [0, 1, -10], [0, 0, 1]])
|
||||
>>> warp(image, matrix)
|
||||
>>> from skimage.transform import ProjectiveTransform
|
||||
>>> warp(image, ProjectiveTransform(matrix=matrix))
|
||||
|
||||
You can also use the inverse of a geometric transformation (fast):
|
||||
|
||||
>>> warp(image, tform.inverse)
|
||||
|
||||
"""
|
||||
# Backward API compatibility
|
||||
if reverse_map is not None:
|
||||
@@ -1015,16 +1035,21 @@ def warp(image, inverse_map=None, map_args={}, output_shape=None, order=1,
|
||||
if order in range(4) and not map_args:
|
||||
matrix = None
|
||||
|
||||
if inverse_map in HOMOGRAPHY_TRANSFORMS:
|
||||
if isinstance(inverse_map, np.ndarray) and inverse_map.shape == (3, 3):
|
||||
matrix = inverse_map
|
||||
|
||||
elif inverse_map in HOMOGRAPHY_TRANSFORMS:
|
||||
matrix = inverse_map._matrix
|
||||
|
||||
elif hasattr(inverse_map, '__name__') \
|
||||
and inverse_map.__name__ == 'inverse' \
|
||||
and get_bound_method_class(inverse_map) in HOMOGRAPHY_TRANSFORMS:
|
||||
elif (hasattr(inverse_map, '__name__')
|
||||
and inverse_map.__name__ == 'inverse'
|
||||
and get_bound_method_class(inverse_map)
|
||||
in HOMOGRAPHY_TRANSFORMS):
|
||||
|
||||
matrix = np.linalg.inv(six.get_method_self(inverse_map)._matrix)
|
||||
|
||||
if matrix is not None:
|
||||
matrix = matrix.astype(np.double)
|
||||
# transform all bands
|
||||
dims = []
|
||||
for dim in range(image.shape[2]):
|
||||
@@ -1042,25 +1067,30 @@ def warp(image, inverse_map=None, map_args={}, output_shape=None, order=1,
|
||||
|
||||
rows, cols = output_shape[:2]
|
||||
|
||||
if isinstance(inverse_map, np.ndarray) and inverse_map.shape == (3, 3):
|
||||
inverse_map = ProjectiveTransform(matrix=inverse_map)
|
||||
|
||||
def coord_map(*args):
|
||||
return inverse_map(*args, **map_args)
|
||||
|
||||
coords = warp_coords(coord_map, (rows, cols, bands))
|
||||
|
||||
# Prefilter not necessary for order 1 interpolation
|
||||
# Prefilter not necessary for order 0, 1 interpolation
|
||||
prefilter = order > 1
|
||||
out = ndimage.map_coordinates(image, coords, prefilter=prefilter,
|
||||
mode=mode, order=order, cval=cval)
|
||||
|
||||
# The spline filters sometimes return results outside [0, 1],
|
||||
# so clip to ensure valid data
|
||||
clipped = np.clip(out, 0, 1)
|
||||
# The spline filters sometimes return results outside [0, 1],
|
||||
# so clip to ensure valid data
|
||||
clipped = np.clip(out, 0, 1)
|
||||
|
||||
if mode == 'constant' and not (0 <= cval <= 1):
|
||||
clipped[out == cval] = cval
|
||||
if mode == 'constant' and not (0 <= cval <= 1):
|
||||
clipped[out == cval] = cval
|
||||
|
||||
if clipped.ndim == 3 and orig_ndim == 2:
|
||||
# remove singleton dim introduced by atleast_3d
|
||||
return clipped[..., 0]
|
||||
out = clipped
|
||||
|
||||
if out.ndim == 3 and orig_ndim == 2:
|
||||
# remove singleton dimension introduced by atleast_3d
|
||||
return out[..., 0]
|
||||
else:
|
||||
return clipped
|
||||
return out
|
||||
|
||||
@@ -11,10 +11,9 @@ from skimage import transform as tf, data, img_as_float
|
||||
from skimage.color import rgb2gray
|
||||
|
||||
|
||||
def test_warp():
|
||||
x = np.zeros((5, 5), dtype=np.uint8)
|
||||
x[2, 2] = 255
|
||||
x = img_as_float(x)
|
||||
def test_warp_tform():
|
||||
x = np.zeros((5, 5), dtype=np.double)
|
||||
x[2, 2] = 1
|
||||
theta = - np.pi / 2
|
||||
tform = SimilarityTransform(scale=1, rotation=theta, translation=(0, 4))
|
||||
|
||||
@@ -25,10 +24,36 @@ def test_warp():
|
||||
assert_array_almost_equal(x90, np.rot90(x))
|
||||
|
||||
|
||||
def test_warp_callable():
|
||||
x = np.zeros((5, 5), dtype=np.double)
|
||||
x[2, 2] = 1
|
||||
refx = np.zeros((5, 5), dtype=np.double)
|
||||
refx[1, 1] = 1
|
||||
|
||||
shift = lambda xy: xy + 1
|
||||
|
||||
outx = warp(x, shift, order=1)
|
||||
assert_array_almost_equal(outx, refx)
|
||||
|
||||
|
||||
def test_warp_matrix():
|
||||
x = np.zeros((5, 5), dtype=np.double)
|
||||
x[2, 2] = 1
|
||||
refx = np.zeros((5, 5), dtype=np.double)
|
||||
refx[1, 1] = 1
|
||||
|
||||
matrix = np.array([[1, 0, 1], [0, 1, 1], [0, 0, 1]])
|
||||
|
||||
# _warp_fast
|
||||
outx = warp(x, matrix, order=1)
|
||||
assert_array_almost_equal(outx, refx)
|
||||
# check for ndimage.map_coordinates
|
||||
outx = warp(x, matrix, order=5)
|
||||
|
||||
|
||||
def test_homography():
|
||||
x = np.zeros((5, 5), dtype=np.uint8)
|
||||
x[1, 1] = 255
|
||||
x = img_as_float(x)
|
||||
x = np.zeros((5, 5), dtype=np.double)
|
||||
x[1, 1] = 1
|
||||
theta = -np.pi / 2
|
||||
M = np.array([[np.cos(theta), - np.sin(theta), 0],
|
||||
[np.sin(theta), np.cos(theta), 4],
|
||||
|
||||
@@ -3,7 +3,7 @@ import numpy as np
|
||||
|
||||
def regular_grid(ar_shape, n_points):
|
||||
"""Find `n_points` regularly spaced along `ar_shape`.
|
||||
|
||||
|
||||
The returned points (as slices) should be as close to cubically-spaced as
|
||||
possible. Essentially, the points are spaced by the Nth root of the input
|
||||
array size, where N is the number of dimensions. However, if an array
|
||||
@@ -13,7 +13,7 @@ def regular_grid(ar_shape, n_points):
|
||||
Parameters
|
||||
----------
|
||||
ar_shape : array-like of ints
|
||||
The shape of the space embedding the grid. `len(ar_shape)` is the
|
||||
The shape of the space embedding the grid. ``len(ar_shape)`` is the
|
||||
number of dimensions.
|
||||
n_points : int
|
||||
The (approximate) number of points to embed in the space.
|
||||
@@ -66,7 +66,7 @@ def regular_grid(ar_shape, n_points):
|
||||
break
|
||||
starts = stepsizes // 2
|
||||
stepsizes = np.round(stepsizes)
|
||||
slices = [slice(start, None, step) for
|
||||
slices = [slice(start, None, step) for
|
||||
start, step in zip(starts, stepsizes)]
|
||||
slices = [slices[i] for i in unsort_dim_idxs]
|
||||
return slices
|
||||
|
||||
@@ -10,7 +10,7 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, grid_shape=None):
|
||||
"""Create a 2-dimensional 'montage' from a 3-dimensional input array
|
||||
representing an ensemble of equally shaped 2-dimensional images.
|
||||
|
||||
For example, montage2d(arr_in, fill) with the following `arr_in`
|
||||
For example, ``montage2d(arr_in, fill)`` with the following `arr_in`
|
||||
|
||||
+---+---+---+
|
||||
| 1 | 2 | 3 |
|
||||
@@ -37,7 +37,8 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, grid_shape=None):
|
||||
rescale_intensity: bool, optional
|
||||
Whether to rescale the intensity of each image to [0, 1].
|
||||
grid_shape: tuple, optional
|
||||
The desired grid shape for the montage (tiles_y, tiles_x). Tthe default aspect ratio is square.
|
||||
The desired grid shape for the montage (tiles_y, tiles_x).
|
||||
The default aspect ratio is square.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
@@ -208,11 +208,11 @@ def view_as_windows(arr_in, window_shape, step=1):
|
||||
|
||||
# -- basic checks on arguments
|
||||
if not isinstance(arr_in, np.ndarray):
|
||||
raise TypeError("'arr_in' must be a numpy ndarray")
|
||||
raise TypeError("`arr_in` must be a numpy ndarray")
|
||||
if not isinstance(window_shape, tuple):
|
||||
raise TypeError("'window_shape' must be a tuple")
|
||||
raise TypeError("`window_shape` must be a tuple")
|
||||
if not (len(window_shape) == arr_in.ndim):
|
||||
raise ValueError("'window_shape' is incompatible with 'arr_in.shape'")
|
||||
raise ValueError("`window_shape` is incompatible with `arr_in.shape`")
|
||||
|
||||
if step < 1:
|
||||
raise ValueError("`step` must be >= 1")
|
||||
@@ -221,10 +221,10 @@ def view_as_windows(arr_in, window_shape, step=1):
|
||||
window_shape = np.array(window_shape, dtype=arr_shape.dtype)
|
||||
|
||||
if ((arr_shape - window_shape) < 0).any():
|
||||
raise ValueError("'window_shape' is too large")
|
||||
raise ValueError("`window_shape` is too large")
|
||||
|
||||
if ((window_shape - 1) < 0).any():
|
||||
raise ValueError("'window_shape' is too small")
|
||||
raise ValueError("`window_shape` is too small")
|
||||
|
||||
# -- build rolling window view
|
||||
arr_in = np.ascontiguousarray(arr_in)
|
||||
|
||||
@@ -9,12 +9,12 @@ def unique_rows(ar):
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ar : 2D np.ndarray
|
||||
ar : 2-D ndarray
|
||||
The input array.
|
||||
|
||||
Returns
|
||||
-------
|
||||
ar_out : 2D np.ndarray
|
||||
ar_out : 2-D ndarray
|
||||
A copy of the input array with repeated rows removed.
|
||||
|
||||
Raises
|
||||
|
||||
Reference in New Issue
Block a user