Added docs, tests for downsample() in skimage.transform._warps

This commit is contained in:
Ankit Agrawal
2013-05-06 23:45:01 +05:30
parent 329cf37ca2
commit 7282f561d4
5 changed files with 103 additions and 62 deletions
+2 -1
View File
@@ -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',
+61
View File
@@ -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
-60
View File
@@ -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
+28 -1
View File
@@ -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()
+12
View File
@@ -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)