mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-09 13:25:31 +08:00
Added docs, tests for downsample() in skimage.transform._warps
This commit is contained in:
@@ -9,7 +9,7 @@ from ._geometric import (warp, warp_coords, estimate_transform,
|
||||
SimilarityTransform, AffineTransform,
|
||||
ProjectiveTransform, PolynomialTransform,
|
||||
PiecewiseAffineTransform)
|
||||
from ._warps import swirl, resize, rotate, rescale
|
||||
from ._warps import swirl, resize, rotate, rescale, downscale_local_means
|
||||
from .pyramids import (pyramid_reduce, pyramid_expand,
|
||||
pyramid_gaussian, pyramid_laplacian)
|
||||
|
||||
@@ -39,6 +39,7 @@ __all__ = ['hough_circle',
|
||||
'resize',
|
||||
'rotate',
|
||||
'rescale',
|
||||
'downscale_local_means',
|
||||
'pyramid_reduce',
|
||||
'pyramid_expand',
|
||||
'pyramid_gaussian',
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import numpy as np
|
||||
from scipy import ndimage
|
||||
|
||||
from ._geometric import warp, SimilarityTransform, AffineTransform
|
||||
from skimage.util.shape import view_as_blocks, _pad_asymmetric_zeros
|
||||
|
||||
|
||||
def resize(image, output_shape, order=1, mode='constant', cval=0.):
|
||||
@@ -283,3 +285,62 @@ def swirl(image, center=None, strength=1, radius=100, rotation=0,
|
||||
return warp(image, _swirl_mapping, map_args=warp_args,
|
||||
output_shape=output_shape,
|
||||
order=order, mode=mode, cval=cval)
|
||||
|
||||
|
||||
def downsample(array, factors, mode='sum'):
|
||||
"""Performs downsampling with integer factors.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
array : ndarray
|
||||
Input n-dimensional array.
|
||||
factors: tuple
|
||||
Tuple containing downsampling factor along each axis.
|
||||
mode : string
|
||||
Decides whether the downsampled element is the sum or mean
|
||||
of its corresponding constituent elements in the input array. Default
|
||||
is 'sum'.
|
||||
|
||||
Returns
|
||||
-------
|
||||
array : ndarray
|
||||
Downsampled array with same number of dimensions as that of input
|
||||
array.
|
||||
|
||||
Example
|
||||
-------
|
||||
>>> a = np.arange(15).reshape(3, 5)
|
||||
>>> a
|
||||
array([[ 0, 1, 2, 3, 4],
|
||||
[ 5, 6, 7, 8, 9],
|
||||
[10, 11, 12, 13, 14]])
|
||||
>>> downsample(a, (2,3))
|
||||
array([[21, 24],
|
||||
[33, 27]])
|
||||
|
||||
"""
|
||||
|
||||
pad_size = []
|
||||
if len(factors) != array.ndim:
|
||||
raise ValueError("'factors' must have the same length "
|
||||
"as 'array.shape'")
|
||||
else:
|
||||
for i in range(len(factors)):
|
||||
if array.shape[i] % factors[i] != 0:
|
||||
pad_size.append(factors[i] - (array.shape[i] % factors[i]))
|
||||
else:
|
||||
pad_size.append(0)
|
||||
|
||||
for i in range(len(pad_size)):
|
||||
array = _pad_asymmetric_zeros(array, pad_size[i], i)
|
||||
|
||||
out = view_as_blocks(array, factors)
|
||||
block_shape = out.shape
|
||||
|
||||
if mode == 'sum':
|
||||
for i in range(len(block_shape)/2):
|
||||
out = out.sum(-1)
|
||||
else:
|
||||
for i in range(len(block_shape)/2):
|
||||
out = out.mean(-1)
|
||||
return out
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
# TODO : Doc, Tests, PEP8 check
|
||||
|
||||
import numpy as np
|
||||
from skimage.util.shape import view_as_blocks
|
||||
|
||||
|
||||
def _pad_asymmetric_zeros(arr, pad_amt, axis=-1):
|
||||
"""Pads `arr` by `pad_amt` along specified `axis`"""
|
||||
if axis == -1:
|
||||
axis = arr.ndim - 1
|
||||
|
||||
zeroshape = tuple([x if i != axis else pad_amt
|
||||
for (i, x) in enumerate(arr.shape)])
|
||||
|
||||
return np.concatenate((arr, np.zeros(zeroshape, dtype=arr.dtype)),
|
||||
axis=axis)
|
||||
|
||||
|
||||
def downsample(image, factors, method='sum'):
|
||||
|
||||
pad_size = []
|
||||
if len(factors) != image.ndim:
|
||||
raise ValueError("'factors' must have the same length "
|
||||
"as 'image.shape'")
|
||||
else:
|
||||
for i in range(len(factors)):
|
||||
if image.shape[i] % factors[i] != 0:
|
||||
pad_size.append(factors[i] - (image.shape[i] % factors[i]))
|
||||
else:
|
||||
pad_size.append(0)
|
||||
|
||||
for i in range(len(pad_size)):
|
||||
image = _pad_asymmetric_zeros(image, pad_size[i], i)
|
||||
|
||||
out = view_as_blocks(image, factors)
|
||||
block_shape = out.shape
|
||||
|
||||
if method == 'sum':
|
||||
for i in range(len(block_shape)/2):
|
||||
out = out.sum(-1)
|
||||
else:
|
||||
for i in range(len(block_shape)/2):
|
||||
out = out.mean(-1)
|
||||
return out
|
||||
|
||||
def upsample(image, factors, method='divide'):
|
||||
|
||||
f = factors
|
||||
|
||||
if (f[0] - int(f[0]) != 0) or (f[1] - int(f[1]) != 0):
|
||||
raise ValueError('Use resample() for non-integer upsampling')
|
||||
out = np.zeros((f[0] * image.shape[0], f[1] * image.shape[1]))
|
||||
|
||||
for i in range(out.shape[0]):
|
||||
for j in range(out.shape[1]):
|
||||
out[i][j] = (image[i / f[0]][j / f[1]])
|
||||
if method == 'divide':
|
||||
return out / float(f[0] * f[1])
|
||||
else:
|
||||
return out
|
||||
@@ -1,4 +1,4 @@
|
||||
from numpy.testing import assert_array_almost_equal, run_module_suite
|
||||
from numpy.testing import assert_array_almost_equal, run_module_suite, assert_array_equal
|
||||
import numpy as np
|
||||
from scipy.ndimage import map_coordinates
|
||||
|
||||
@@ -193,6 +193,33 @@ def test_warp_coords_example():
|
||||
coords = warp_coords(tform, (30, 30, 3))
|
||||
map_coordinates(image[:, :, 0], coords[:2])
|
||||
|
||||
def test_downsample_sum():
|
||||
"""Verifying downsampling of an array with expected result in sum mode"""
|
||||
image1 = np.arange(4*6).reshape(4, 6)
|
||||
out1 = tf.downsample(image1, (2, 3))
|
||||
expected1 = np.array([[ 24, 42],
|
||||
[ 96, 114]])
|
||||
assert_array_equal(expected1, out1)
|
||||
image2 = np.arange(5*8).reshape(5, 8)
|
||||
out2 = tf.downsample(image2, (3, 3))
|
||||
expected2 = np.array([[ 81, 108, 87],
|
||||
[174, 192, 138]])
|
||||
assert_array_equal(expected2, out2)
|
||||
|
||||
|
||||
def test_downsample_mean():
|
||||
"""Verifying downsampling of an array with expected result in mean mode"""
|
||||
image1 = np.arange(4*6).reshape(4, 6)
|
||||
out1 = tf.downsample(image1, (2, 3), 'mean')
|
||||
expected1 = np.array([[ 4., 7.],
|
||||
[ 16., 19.]])
|
||||
assert_array_equal(expected1, out1)
|
||||
image2 = np.arange(5*8).reshape(5, 8)
|
||||
out2 = tf.downsample(image2, (4, 5), 'mean')
|
||||
expected2 = np.array([[ 14. , 10.8],
|
||||
[ 8.5, 5.7]])
|
||||
assert_array_equal(expected2, out2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_module_suite()
|
||||
|
||||
@@ -230,3 +230,15 @@ def view_as_windows(arr_in, window_shape):
|
||||
arr_out = as_strided(arr_in, shape=new_shape, strides=new_strides)
|
||||
|
||||
return arr_out
|
||||
|
||||
|
||||
def _pad_asymmetric_zeros(arr, pad_amt, axis=-1):
|
||||
"""Pads `arr` with zeros by `pad_amt` along specified `axis`"""
|
||||
if axis == -1:
|
||||
axis = arr.ndim - 1
|
||||
|
||||
zeroshape = tuple([x if i != axis else pad_amt
|
||||
for (i, x) in enumerate(arr.shape)])
|
||||
|
||||
return np.concatenate((arr, np.zeros(zeroshape, dtype=arr.dtype)),
|
||||
axis=axis)
|
||||
|
||||
Reference in New Issue
Block a user