Add support for negative indexes/slices.

This commit is contained in:
Tony S Yu
2013-09-29 20:16:29 -05:00
parent 8f506be2ea
commit 6ce788a5d3
2 changed files with 34 additions and 24 deletions
+11 -10
View File
@@ -38,26 +38,25 @@ def _verify_picture_index(index):
if isinstance(dim_slice, int):
index[i] = dim_slice = slice(dim_slice, dim_slice + 1)
if dim_slice.start is not None and dim_slice.start < 0:
raise IndexError("Negative slicing not supported")
if dim_slice.stop is not None and dim_slice.stop < 0:
raise IndexError("Negative slicing not supported")
if dim_slice.step is not None and dim_slice.step != 1:
raise IndexError("Only a step size of 1 is supported")
return tuple(index)
def rgb_transpose(array):
"""Return RGB array with first 2 axes transposed."""
return np.transpose(array, (1, 0, 2))
def array_to_xy_origin(image):
"""Return view of image transformed from array to Cartesian origin."""
return np.transpose(image[::-1], (1, 0, 2))
return rgb_transpose(image[::-1])
def xy_to_array_origin(image):
"""Return view of image transformed from Cartesian to array origin."""
return np.transpose(image[:, ::-1], (1, 0, 2))
return rgb_transpose(image[:, ::-1])
class Pixel(object):
@@ -151,6 +150,10 @@ class Pixel(object):
self._picture.xy_array[self._x, self._y] = self.rgb
self._picture._array_modified()
def __eq__(self, other):
if isinstance(other, Pixel):
return self.rgb == other.rgb
def __repr__(self):
args = self.red, self.green, self.blue
return "Pixel(red={0}, green={1}, blue={2})".format(*args)
@@ -396,8 +399,6 @@ class Picture(object):
"""Return `Picture`s for slices and `Pixel`s for indexes."""
xy_index = _verify_picture_index(xy_index)
if all(isinstance(index, int) for index in xy_index):
if any(index < 0 for index in xy_index):
raise IndexError("Negative indices not supported")
return self._makepixel(*xy_index)
else:
return Picture(xy_array=self.xy_array[xy_index])
+23 -14
View File
@@ -4,7 +4,8 @@ import tempfile
import numpy as np
from numpy.testing import assert_equal, raises, assert_allclose
from skimage import novice
from skimage.novice._novice import array_to_xy_origin, xy_to_array_origin
from skimage.novice._novice import (array_to_xy_origin, xy_to_array_origin,
rgb_transpose)
from skimage import data_dir
@@ -164,7 +165,7 @@ def test_picture_slice():
assert_allclose(subpic.array, array[x_slice, :])
def test_slicing():
def test_move_slice():
h, w = 3, 12
array = _array_2d_to_RGB(np.linspace(0, 255, h * w).reshape(h, w))
array = array.astype(np.uint8)
@@ -184,6 +185,26 @@ def test_slicing():
assert pic[:rest, :] == pic_orig[cut:, :]
def test_negative_index():
n = 10
array = _array_2d_to_RGB(np.arange(0, n)[np.newaxis, :])
# Test both x and y indices.
pic = novice.Picture(array=array)
assert pic[-1, 0] == pic[n - 1, 0]
pic = novice.Picture(array=rgb_transpose(array))
assert pic[0, -1] == pic[0, n - 1]
def test_negative_slice():
n = 10
array = _array_2d_to_RGB(np.arange(0, n)[np.newaxis, :])
# Test both x and y slices.
pic = novice.Picture(array=array)
assert pic[-3:, 0] == pic[n - 3:, 0]
pic = novice.Picture(array=rgb_transpose(array))
assert pic[0, -3:] == pic[0, n - 3:]
@raises(IndexError)
def test_1d_getitem_raises():
pic = novice.Picture.from_size((1, 1))
@@ -214,18 +235,6 @@ def test_getitem_with_step_raises():
pic[::2, ::2]
@raises(IndexError)
def test_negative_index_raises():
pic = novice.Picture.from_size((1, 1))
pic[-1, -1]
@raises(IndexError)
def test_negative_slice_raises():
pic = novice.Picture.from_size((1, 1))
pic[-1:, -1:]
@raises(IndexError)
def test_out_of_bounds_indexing():
pic = novice.open(SMALL_IMAGE_PATH)