Cleaning up downsampling for integer factors

This commit is contained in:
Ankit Agrawal
2013-07-04 17:34:55 +08:00
parent c57c865196
commit 6f9d7c5d1a
6 changed files with 97 additions and 36 deletions
+3 -1
View File
@@ -3,6 +3,7 @@ from ._regionprops import regionprops, perimeter
from ._structural_similarity import structural_similarity
from ._polygon import approximate_polygon, subdivide_polygon
from .fit import LineModel, CircleModel, EllipseModel, ransac
from ._sum_blocks import sum_blocks
__all__ = ['find_contours',
@@ -14,4 +15,5 @@ __all__ = ['find_contours',
'LineModel',
'CircleModel',
'EllipseModel',
'ransac']
'ransac',
'sum_blocks']
+34
View File
@@ -0,0 +1,34 @@
from ..transform._warps import _downsample
def sum_blocks(array, factors):
"""Sums the elements in blocks of integer factors and pads the original
array with zeroes if the dimensions are not perfectly divisible by factors.
Parameters
----------
array : ndarray
Input n-dimensional array.
factors: tuple
Tuple containing integer values representing block length along each
axis.
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]])
>>> sum_blocks(a, (2,3))
array([[21, 24],
[33, 27]])
"""
return _downsample(array, factors)
+16
View File
@@ -0,0 +1,16 @@
import numpy as np
from numpy.testing import assert_array_equal
from skimage.measure._sum_blocks import sum_blocks
def test_downsample_sum_blocks():
"""Verifying downsampling of an array with expected result in sum mode"""
image1 = np.arange(4*6).reshape(4, 6)
out1 = sum_blocks(image1, (2, 3))
expected1 = np.array([[ 24, 42],
[ 96, 114]])
assert_array_equal(expected1, out1)
image2 = np.arange(5*8).reshape(5, 8)
out2 = sum_blocks(image2, (3, 3))
expected2 = np.array([[ 81, 108, 87],
[174, 192, 138]])
assert_array_equal(expected2, out2)
-1
View File
@@ -9,7 +9,6 @@ from ._geometric import (warp, warp_coords, estimate_transform,
SimilarityTransform, AffineTransform,
ProjectiveTransform, PolynomialTransform,
PiecewiseAffineTransform)
from ._warps import swirl, resize, rotate, rescale, downscale_local_means
from .pyramids import (pyramid_reduce, pyramid_expand,
pyramid_gaussian, pyramid_laplacian)
+39 -17
View File
@@ -287,7 +287,7 @@ def swirl(image, center=None, strength=1, radius=100, rotation=0,
order=order, mode=mode, cval=cval)
def _downsample(array, factors, mode='sum'):
def _downsample(array, factors, sum=True):
"""Performs downsampling with integer factors.
Parameters
@@ -296,10 +296,9 @@ def _downsample(array, factors, mode='sum'):
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'.
sum : bool
If True, downsampled element is the sum of its corresponding
constituent elements in the input array. Default is True.
Returns
-------
@@ -307,17 +306,6 @@ def _downsample(array, factors, mode='sum'):
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 = []
@@ -337,10 +325,44 @@ def _downsample(array, factors, mode='sum'):
out = view_as_blocks(array, factors)
block_shape = out.shape
if mode == 'sum':
if 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 downscale_local_means(array, factors):
"""Downsamples the array in blocks of input integer factors after padding
the original array with zeroes if the dimensions are not perfectly
divisible by factors and replaces it with mean i.e. average value.
Parameters
----------
array : ndarray
Input n-dimensional array.
factors: tuple
Tuple containing integer values representing block length along each
axis.
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]])
>>> downscale_local_means(a, (2,3))
array([[3.5, 4.],
[5.5, 4.5]])
"""
return _downsample(array, factors, False)
+5 -17
View File
@@ -5,7 +5,8 @@ from scipy.ndimage import map_coordinates
from skimage.transform import (warp, warp_coords, rotate, resize, rescale,
AffineTransform,
ProjectiveTransform,
SimilarityTransform)
SimilarityTransform,
downscale_local_means)
from skimage import transform as tf, data, img_as_float
from skimage.color import rgb2gray
@@ -193,29 +194,16 @@ 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():
def test_downscale_local_means():
"""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')
out1 = downscale_local_means(image1, (2, 3))
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')
out2 = downscale_local_means(image2, (4, 5))
expected2 = np.array([[ 14. , 10.8],
[ 8.5, 5.7]])
assert_array_equal(expected2, out2)