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 23:39:55 -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