diff --git a/skimage/io/collection.py b/skimage/io/collection.py index e698b52b..c754c8ad 100644 --- a/skimage/io/collection.py +++ b/skimage/io/collection.py @@ -5,11 +5,42 @@ from __future__ import with_statement __all__ = ['MultiImage', 'ImageCollection', 'imread'] from glob import glob +import re import numpy as np from ._io import imread +def _tryint(s): + try: + return int(s) + except ValueError: + return s + +def alphanumeric_key(s): + """Convert string to list of strings and ints that gives intuitive sorting. + + Parameters + ---------- + s: string + + Returns + ------- + k: a list of strings and ints + + Examples + -------- + >>> alphanumeric_key('z23a') + ['z', 23, 'a'] + >>> filenames = ['f9.10.png', 'f9.9.png', 'f10.10.png', 'f10.9.png'] + >>> sorted(filenames) + ['f10.10.png', 'f10.9.png', 'f9.10.png', 'f9.9.png'] + >>> sorted(filenames, key=alphanumeric_key) + ['f9.9.png', 'f9.10.png', 'f10.9.png', 'f10.10.png'] + """ + k = [_tryint(c) for c in re.split('([0-9]+)', s)] + return k + class MultiImage(object): """A class containing a single multi-frame image. @@ -213,7 +244,7 @@ class ImageCollection(object): (128, 128, 3) >>> ic = io.ImageCollection('/tmp/work/*.png:/tmp/other/*.jpg') - + """ def __init__(self, load_pattern, conserve_memory=True, load_func=None): """Load and manage a collection of images.""" @@ -222,7 +253,7 @@ class ImageCollection(object): self._files = [] for pattern in load_pattern: self._files.extend(glob(pattern)) - self._files.sort() + self._files = sorted(self._files, key=alphanumeric_key) else: self._files = load_pattern diff --git a/skimage/io/tests/test_collection.py b/skimage/io/tests/test_collection.py index 0d420ae7..969d3e56 100644 --- a/skimage/io/tests/test_collection.py +++ b/skimage/io/tests/test_collection.py @@ -7,6 +7,7 @@ from numpy.testing.decorators import skipif from skimage import data_dir from skimage.io import ImageCollection, MultiImage +from skimage.io.collection import alphanumeric_key try: @@ -19,6 +20,21 @@ else: if sys.version_info[0] > 2: basestring = str +class TestAlphanumericKey(): + def setUp(self): + self.test_string = 'z23a' + self.test_str_result = ['z', 23, 'a'] + self.filenames = ['f9.10.png', 'f9.9.png', 'f10.10.png', 'f10.9.png'] + self.sorted_filenames = \ + ['f9.9.png', 'f9.10.png', 'f10.9.png', 'f10.10.png'] + + def test_string_split(self): + assert_equal(alphanumeric_key(self.test_string), self.test_str_result) + + def test_string_sort(self): + sorted_filenames = sorted(self.filenames, key=alphanumeric_key) + assert_equal(sorted_filenames, self.sorted_filenames) + class TestImageCollection(): pattern = [os.path.join(data_dir, pic) for pic in ['camera.png',