MAINT: All modes in _shared.interpolation.pxd were changed to be consistent with numpy.pad naming conventions. Specifically 'nearest' was changed to 'edge' and 'mirror' was changed to 'reflect'. All functions with a mode argument that rely on these functions had their inputs changed accordingly. For now there is a deprecation warning if the user supplies mode 'nearest'. Mode 'mirror' never appeared in an official release of skimage and so has no corresponding deprecation warning.

This commit is contained in:
Gregory R. Lee
2015-08-13 22:11:04 -04:00
parent 8e3b6bc9da
commit 81ea7a6e34
10 changed files with 109 additions and 62 deletions
+32 -19
View File
@@ -2,6 +2,20 @@
#cython: boundscheck=False
#cython: nonecheck=False
#cython: wraparound=False
"""
Note: All edge modes implemented here follow the corresponding numpy.pad
conventions.
The table below illustrates the behavior for the array [1, 2, 3, 4], if padded
by 4 values on each side:
pad original pad
constant (with c=0) : 0 0 0 0 | 1 2 3 4 | 0 0 0 0
wrap : 1 2 3 4 | 1 2 3 4 | 1 2 3 4
symmetric : 4 3 2 1 | 1 2 3 4 | 4 3 2 1
edge : 1 1 1 1 | 1 2 3 4 | 4 4 4 4
reflect : 3 4 3 2 | 1 2 3 4 | 3 2 1 2
"""
from libc.math cimport ceil, floor
@@ -24,8 +38,8 @@ cdef inline double nearest_neighbour_interpolation(double* image,
Shape of image.
r, c : double
Position at which to interpolate.
mode : {'C', 'W', 'R', 'N', 'M'}
Wrapping mode. Constant, Wrap, Reflect, Nearest or Mirror.
mode : {'C', 'W', 'S', 'E', 'R'}
Wrapping mode. Constant, Wrap, Symmetric, Edge or Reflect.
cval : double
Constant value to use for constant mode.
@@ -52,8 +66,8 @@ cdef inline double bilinear_interpolation(double* image, Py_ssize_t rows,
Shape of image.
r, c : double
Position at which to interpolate.
mode : {'C', 'W', 'R', 'N', 'M'}
Wrapping mode. Constant, Wrap, Reflect, Nearest or Mirror.
mode : {'C', 'W', 'S', 'E', 'R'}
Wrapping mode. Constant, Wrap, Symmetric, Edge or Reflect.
cval : double
Constant value to use for constant mode.
@@ -119,8 +133,8 @@ cdef inline double biquadratic_interpolation(double* image, Py_ssize_t rows,
Shape of image.
r, c : double
Position at which to interpolate.
mode : {'C', 'W', 'R', 'N', 'M'}
Wrapping mode. Constant, Wrap, Reflect, Nearest or Mirror.
mode : {'C', 'W', 'S', 'E', 'R'}
Wrapping mode. Constant, Wrap, Symmetric, Edge or Reflect.
cval : double
Constant value to use for constant mode.
@@ -192,8 +206,8 @@ cdef inline double bicubic_interpolation(double* image, Py_ssize_t rows,
Shape of image.
r, c : double
Position at which to interpolate.
mode : {'C', 'W', 'R', 'N', 'M'}
Wrapping mode. Constant, Wrap, Reflect, Nearest or Mirror.
mode : {'C', 'W', 'S', 'E', 'R'}
Wrapping mode. Constant, Wrap, Symmetric, Edge or Reflect.
cval : double
Constant value to use for constant mode.
@@ -248,8 +262,8 @@ cdef inline double get_pixel2d(double* image, Py_ssize_t rows, Py_ssize_t cols,
Shape of image.
r, c : int
Position at which to get the pixel.
mode : {'C', 'W', 'R', 'N', 'M'}
Wrapping mode. Constant, Wrap, Reflect, Nearest or Mirror.
mode : {'C', 'W', 'S', 'E', 'R'}
Wrapping mode. Constant, Wrap, Symmetric, Edge or Reflect.
cval : double
Constant value to use for constant mode.
@@ -281,8 +295,8 @@ cdef inline double get_pixel3d(double* image, Py_ssize_t rows, Py_ssize_t cols,
Shape of image.
r, c, d : int
Position at which to get the pixel.
mode : {'C', 'W', 'R', 'N', 'M'}
Wrapping mode. Constant, Wrap, Reflect, Nearest or Mirror.
mode : {'C', 'W', 'S', 'E', 'R'}
Wrapping mode. Constant, Wrap, Symmetric, Edge or Reflect.
cval : double
Constant value to use for constant mode.
@@ -312,14 +326,13 @@ cdef inline Py_ssize_t coord_map(Py_ssize_t dim, long coord, char mode) nogil:
Maximum coordinate.
coord : int
Coord provided by user. May be < 0 or > dim.
mode : {'W', 'R', 'N', 'M'}
Whether to wrap, reflect, mirror or use the nearest coordinate if it
falls outside [0, dim).
mode : {'W', 'S', 'R', 'E'}
Whether to wrap, symmetric reflect, reflect or use the nearest
coordinate if `coord` falls outside [0, dim).
"""
cdef Py_ssize_t cmax
cmax = dim - 1
if mode == 'R': # reflect
if mode == 'S': # symmetric
if coord < 0:
coord = -coord - 1
if coord > cmax:
@@ -332,12 +345,12 @@ cdef inline Py_ssize_t coord_map(Py_ssize_t dim, long coord, char mode) nogil:
return <Py_ssize_t>(cmax - ((-coord - 1) % dim))
elif coord > cmax:
return <Py_ssize_t>(coord % dim)
elif mode == 'N': # nearest
elif mode == 'E': # edge
if coord < 0:
return 0
elif coord > cmax:
return cmax
elif mode == 'M': # mirror
elif mode == 'R': # reflect (mirror)
if coord < 0:
# How many times times does the coordinate wrap?
if <Py_ssize_t>(-coord / cmax) % 2 != 0:
+3 -2
View File
@@ -1,6 +1,7 @@
from interpolation cimport coord_map, get_pixel2d
import numpy as np
cimport numpy as cnp
from .utils import _mode_deprecations
def coord_map_py(Py_ssize_t dim, long coord, mode):
@@ -18,7 +19,7 @@ def extend_image(image, pad=10, mode='constant', cval=0):
Input image.
pad : int, optional
The number of pixels to pad around the border
mode : {'constant', 'nearest', 'reflect', 'mirror', 'wrap'}, optional
mode : {'constant', 'edge', 'symmetric', 'reflect', 'wrap'}, optional
Points outside the boundaries of the input are filled according
to the given mode.
cval : float, optional
@@ -36,7 +37,7 @@ def extend_image(image, pad=10, mode='constant', cval=0):
function is intended only for testing get_pixel2d and demonstrating the
coordinate mapping modes implemented in ``coord_map``.
"""
mode = _mode_deprecations(mode)
cdef:
Py_ssize_t rows = image.shape[0]
Py_ssize_t cols = image.shape[1]
+13 -9
View File
@@ -3,21 +3,25 @@ from numpy.testing import assert_array_equal
def test_coord_map():
reflect = [coord_map_py(4, n, 'R') for n in range(-6, 6)]
expected_reflect = [2, 3, 3, 2, 1, 0, 0, 1, 2, 3, 3, 2]
assert_array_equal(reflect, expected_reflect)
symmetric = [coord_map_py(4, n, 'S') for n in range(-6, 6)]
expected_symmetric = [2, 3, 3, 2, 1, 0, 0, 1, 2, 3, 3, 2]
assert_array_equal(symmetric, expected_symmetric)
wrap = [coord_map_py(4, n, 'W') for n in range(-6, 6)]
expected_wrap = [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1]
assert_array_equal(wrap, expected_wrap)
nearest = [coord_map_py(4, n, 'N') for n in range(-6, 6)]
expected_neareset = [0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 3, 3]
assert_array_equal(nearest, expected_neareset)
edge = [coord_map_py(4, n, 'E') for n in range(-6, 6)]
expected_edge = [0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 3, 3]
assert_array_equal(edge, expected_edge)
mirror = [coord_map_py(4, n, 'M') for n in range(-6, 6)]
expected_mirror = [0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1]
assert_array_equal(mirror, expected_mirror)
reflect = [coord_map_py(4, n, 'R') for n in range(-6, 6)]
expected_reflect = [0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1]
assert_array_equal(reflect, expected_reflect)
constant = [coord_map_py(4, n, 'C') for n in range(-6, 6)]
expected_constant = [0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0]
assert_array_equal(constant, expected_constant)
other = [coord_map_py(4, n, 'undefined') for n in range(-6, 6)]
assert_array_equal(other, list(range(-6, 6)))
+11
View File
@@ -163,3 +163,14 @@ def assert_nD(array, ndim, arg_name='image'):
ndim = [ndim]
if not array.ndim in ndim:
raise ValueError(msg % (arg_name, '-or-'.join([str(n) for n in ndim])))
def _mode_deprecations(mode):
""" to be used by functions to update deprecated mode names in
`skimage._shared.interpolation.pyx`."""
if mode.lower() == 'nearest':
warnings.warn(skimage_deprecation(
"Mode 'nearest' has been renamed 'edge'. Mode 'nearest' will be "
"removed in a future release."))
mode = 'edge'
return mode
+4 -2
View File
@@ -2,6 +2,7 @@
import numpy as np
from .. import img_as_float
from ..restoration._denoise_cy import _denoise_bilateral, _denoise_tv_bregman
from .._shared.utils import _mode_deprecations
def denoise_bilateral(image, win_size=5, sigma_range=None, sigma_spatial=1,
@@ -37,9 +38,9 @@ def denoise_bilateral(image, win_size=5, sigma_range=None, sigma_spatial=1,
bins : int
Number of discrete values for gaussian weights of color filtering.
A larger value results in improved accuracy.
mode : string
mode : {'constant', 'edge', 'symmetric', 'reflect', 'wrap'}
How to handle values outside the image borders. See
`scipy.ndimage.map_coordinates` for detail.
`numpy.pad` for detail.
cval : string
Used in conjunction with mode 'constant', the value outside
the image boundaries.
@@ -54,6 +55,7 @@ def denoise_bilateral(image, win_size=5, sigma_range=None, sigma_spatial=1,
.. [1] http://users.soe.ucsc.edu/~manduchi/Papers/ICCV98.pdf
"""
mode = _mode_deprecations(mode)
return _denoise_bilateral(image, win_size, sigma_range, sigma_spatial,
bins, mode, cval)
+3 -3
View File
@@ -105,9 +105,9 @@ def _denoise_bilateral(image, Py_ssize_t win_size, sigma_range,
centres = <double*>malloc(dims * sizeof(double))
total_values = <double*>malloc(dims * sizeof(double))
if mode not in ('constant', 'wrap', 'reflect', 'nearest'):
raise ValueError("Invalid mode specified. Please use "
"`constant`, `nearest`, `wrap` or `reflect`.")
if mode not in ('constant', 'wrap', 'symmetric', 'reflect', 'edge'):
raise ValueError("Invalid mode specified. Please use `constant`, "
"`edge`, `wrap`, `symmetric` or `reflect`.")
cdef char cmode = ord(mode[0].upper())
for r in range(rows):
+9 -7
View File
@@ -5,8 +5,10 @@ import numpy as np
from scipy import spatial
from scipy import ndimage as ndi
from .._shared.utils import get_bound_method_class, safe_as_int
from .._shared.utils import (get_bound_method_class, safe_as_int,
_mode_deprecations)
from ..util import img_as_float
from ._warps_cy import _warp_fast
@@ -1128,9 +1130,9 @@ def _clip_warp_output(input_image, output_image, order, mode, cval, clip):
order : int, optional
The order of the spline interpolation, default is 1. The order has to
be in the range 0-5. See `skimage.transform.warp` for detail.
mode : {'constant', 'nearest', 'reflect', 'mirror', 'wrap'}, optional
mode : {'constant', 'edge', 'symmetric', 'reflect', 'wrap'}, optional
Points outside the boundaries of the input are filled according
to the given mode.
to the given mode. Modes match the behaviour of `numpy.pad`.
cval : float, optional
Used in conjunction with mode 'constant', the value outside
the image boundaries.
@@ -1140,7 +1142,7 @@ def _clip_warp_output(input_image, output_image, order, mode, cval, clip):
produce values outside the given input range.
"""
mode = _mode_deprecations(mode)
if clip and order != 0:
min_val = input_image.min()
max_val = input_image.max()
@@ -1211,9 +1213,9 @@ def warp(image, inverse_map=None, map_args={}, output_shape=None, order=1,
- 3: Bi-cubic
- 4: Bi-quartic
- 5: Bi-quintic
mode : {'constant', 'nearest', 'reflect', 'mirror', 'wrap'}, optional
mode : {'constant', 'edge', 'symmetric', 'reflect', 'wrap'}, optional
Points outside the boundaries of the input are filled according
to the given mode.
to the given mode. Modes match the behaviour of `numpy.pad`.
cval : float, optional
Used in conjunction with mode 'constant', the value outside
the image boundaries.
@@ -1294,7 +1296,7 @@ def warp(image, inverse_map=None, map_args={}, output_shape=None, order=1,
>>> warped = warp(cube, coords)
"""
mode = _mode_deprecations(mode)
image = _convert_warp_input(image, preserve_range)
input_shape = np.array(image.shape)
+23 -10
View File
@@ -4,6 +4,18 @@ from scipy import ndimage as ndi
from ..measure import block_reduce
from ._geometric import (warp, SimilarityTransform, AffineTransform,
_convert_warp_input, _clip_warp_output)
from .._shared.utils import _mode_deprecations
def _to_ndimage_mode(mode):
""" Convert from a numpy.pad mode name to the corresponding ndimage
mode. """
mode = _mode_deprecations(mode.lower())
mode_translation_dict = dict(edge='nearest', symmetric='reflect',
reflect='mirror')
if mode in mode_translation_dict:
mode = mode_translation_dict[mode]
return mode
def resize(image, output_shape, order=1, mode='constant', cval=0, clip=True,
@@ -35,9 +47,9 @@ def resize(image, output_shape, order=1, mode='constant', cval=0, clip=True,
order : int, optional
The order of the spline interpolation, default is 1. The order has to
be in the range 0-5. See `skimage.transform.warp` for detail.
mode : {'constant', 'nearest', 'reflect', 'mirror', 'wrap'}, optional
mode : {'constant', 'edge', 'symmetric', 'reflect', 'wrap'}, optional
Points outside the boundaries of the input are filled according
to the given mode.
to the given mode. Modes match the behaviour of `numpy.pad`.
cval : float, optional
Used in conjunction with mode 'constant', the value outside
the image boundaries.
@@ -51,10 +63,10 @@ def resize(image, output_shape, order=1, mode='constant', cval=0, clip=True,
Note
----
Modes 'mirror' and 'reflect' are similar, but differ in whether the edge
Modes 'reflect' and 'symmetric' are similar, but differ in whether the edge
voxels are duplicated during the reflection. As an example, if an array
has values [0, 1, 2] and was padded to the right by four values using
reflect, the result would be [0, 1, 2, 2, 1, 0, 0], while for mirror it
symmetric, the result would be [0, 1, 2, 2, 1, 0, 0], while for reflect it
would be [0, 1, 2, 1, 0, 1, 2].
Examples
@@ -76,6 +88,7 @@ def resize(image, output_shape, order=1, mode='constant', cval=0, clip=True,
# 3-dimensional interpolation
if len(output_shape) == 3 and (image.ndim == 2
or output_shape[2] != image.shape[2]):
mode = _to_ndimage_mode(mode)
dim = output_shape[2]
if image.ndim == 2:
image = image[:, :, np.newaxis]
@@ -146,9 +159,9 @@ def rescale(image, scale, order=1, mode='constant', cval=0, clip=True,
order : int, optional
The order of the spline interpolation, default is 1. The order has to
be in the range 0-5. See `skimage.transform.warp` for detail.
mode : {'constant', 'nearest', 'reflect', 'mirror', 'wrap'}, optional
mode : {'constant', 'edge', 'symmetric', 'reflect', 'wrap'}, optional
Points outside the boundaries of the input are filled according
to the given mode.
to the given mode. Modes match the behaviour of `numpy.pad`.
cval : float, optional
Used in conjunction with mode 'constant', the value outside
the image boundaries.
@@ -214,9 +227,9 @@ def rotate(image, angle, resize=False, center=None, order=1, mode='constant',
order : int, optional
The order of the spline interpolation, default is 1. The order has to
be in the range 0-5. See `skimage.transform.warp` for detail.
mode : {'constant', 'nearest', 'reflect', 'mirror', 'wrap'}, optional
mode : {'constant', 'edge', 'symmetric', 'reflect', 'wrap'}, optional
Points outside the boundaries of the input are filled according
to the given mode.
to the given mode. Modes match the behaviour of `numpy.pad`.
cval : float, optional
Used in conjunction with mode 'constant', the value outside
the image boundaries.
@@ -368,9 +381,9 @@ def swirl(image, center=None, strength=1, radius=100, rotation=0,
order : int, optional
The order of the spline interpolation, default is 1. The order has to
be in the range 0-5. See `skimage.transform.warp` for detail.
mode : {'constant', 'nearest', 'reflect', 'mirror', 'wrap'}, optional
mode : {'constant', 'edge', 'symmetric', 'reflect', 'wrap'}, optional
Points outside the boundaries of the input are filled according
to the given mode.
to the given mode. Modes match the behaviour of `numpy.pad`.
cval : float, optional
Used in conjunction with mode 'constant', the value outside
the image boundaries.
+7 -6
View File
@@ -70,18 +70,19 @@ def _warp_fast(cnp.ndarray image, cnp.ndarray H, output_shape=None,
* 1: Bi-linear (default)
* 2: Bi-quadratic
* 3: Bi-cubic
mode : {'constant', 'reflect', 'mirror', 'wrap', 'nearest'}, optional
How to handle values outside the image borders (default is constant).
mode : {'constant', 'edge', 'symmetric', 'reflect', 'wrap'}, optional
Points outside the boundaries of the input are filled according
to the given mode. Modes match the behaviour of `numpy.pad`.
cval : string, optional (default 0)
Used in conjunction with mode 'C' (constant), the value
outside the image boundaries.
Note
----
Modes 'mirror' and 'reflect' are similar, but differ in whether the edge
Modes 'reflect' and 'symmetric' are similar, but differ in whether the edge
voxels are duplicated during the reflection. As an example, if an array
has values [0, 1, 2] and was padded to the right by four values using
reflect, the result would be [0, 1, 2, 2, 1, 0, 0], while for mirror it
symmetric, the result would be [0, 1, 2, 2, 1, 0, 0], while for reflect it
would be [0, 1, 2, 1, 0, 1, 2].
"""
@@ -89,9 +90,9 @@ def _warp_fast(cnp.ndarray image, cnp.ndarray H, output_shape=None,
cdef double[:, ::1] img = np.ascontiguousarray(image, dtype=np.double)
cdef double[:, ::1] M = np.ascontiguousarray(H)
if mode not in ('constant', 'wrap', 'reflect', 'mirror', 'nearest'):
if mode not in ('constant', 'wrap', 'symmetric', 'reflect', 'edge'):
raise ValueError("Invalid mode specified. Please use `constant`, "
"`nearest`, `wrap`, `mirror` or `reflect`.")
"`edge`, `wrap`, `reflect` or `symmetric`.")
cdef char mode_c = ord(mode[0].upper())
cdef Py_ssize_t out_r, out_c
+4 -4
View File
@@ -45,7 +45,7 @@ def pyramid_reduce(image, downscale=2, sigma=None, order=1,
order : int, optional
Order of splines used in interpolation of downsampling. See
`skimage.transform.warp` for detail.
mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
mode : {'reflect', 'constant', 'edge', 'symmetric', 'wrap'}, optional
The mode parameter determines how the array borders are handled, where
cval is the value when mode is equal to 'constant'.
cval : float, optional
@@ -99,7 +99,7 @@ def pyramid_expand(image, upscale=2, sigma=None, order=1,
order : int, optional
Order of splines used in interpolation of upsampling. See
`skimage.transform.warp` for detail.
mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
mode : {'reflect', 'constant', 'edge', 'symmetric', 'wrap'}, optional
The mode parameter determines how the array borders are handled, where
cval is the value when mode is equal to 'constant'.
cval : float, optional
@@ -164,7 +164,7 @@ def pyramid_gaussian(image, max_layer=-1, downscale=2, sigma=None, order=1,
order : int, optional
Order of splines used in interpolation of downsampling. See
`skimage.transform.warp` for detail.
mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
mode : {'reflect', 'constant', 'edge', 'symmetric', 'wrap'}, optional
The mode parameter determines how the array borders are handled, where
cval is the value when mode is equal to 'constant'.
cval : float, optional
@@ -245,7 +245,7 @@ def pyramid_laplacian(image, max_layer=-1, downscale=2, sigma=None, order=1,
order : int, optional
Order of splines used in interpolation of downsampling. See
`skimage.transform.warp` for detail.
mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
mode : {'reflect', 'constant', 'edge', 'symmetric', 'wrap'}, optional
The mode parameter determines how the array borders are handled, where
cval is the value when mode is equal to 'constant'.
cval : float, optional