From 11c7fd2f59de5443f7fbb8a6ea7e860a9ad3fb88 Mon Sep 17 00:00:00 2001 From: Juan Nunez-Iglesias Date: Fri, 20 Jul 2012 15:16:48 -0500 Subject: [PATCH 1/3] Add function 'concatenate' to ImageCollection Many algorithms work on 3D stacks rather than images. It is convenient to provide automatic conversion from an ImageCollection to an nD-stack. --- skimage/io/collection.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/skimage/io/collection.py b/skimage/io/collection.py index e698b52b..7a07aa7f 100644 --- a/skimage/io/collection.py +++ b/skimage/io/collection.py @@ -307,3 +307,23 @@ class ImageCollection(object): """ self.data = np.empty_like(self.data) + + def concatenate(self): + """Concatenate all images in the collection on a new axis. + + Returns + ------- + ar : np.ndarray + An array having one more dimension than the images in `self`. + + Raises + ------ + ValueError + If images in the collection don't have identical shapes. + """ + all_images = [img[np.newaxis, ...] for img in self] + try: + ar = np.concatenate(all_images) + except ValueError: + raise ValueError('Image dimensions must agree.') + return ar From 62ce6f3ab52c9a73e5eca7b52d95df62548ae776 Mon Sep 17 00:00:00 2001 From: Juan Nunez-Iglesias Date: Fri, 20 Jul 2012 15:35:03 -0500 Subject: [PATCH 2/3] Add test for ImageCollection.concatenate --- skimage/io/tests/test_collection.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/skimage/io/tests/test_collection.py b/skimage/io/tests/test_collection.py index 0d420ae7..6ddae6fe 100644 --- a/skimage/io/tests/test_collection.py +++ b/skimage/io/tests/test_collection.py @@ -23,9 +23,12 @@ if sys.version_info[0] > 2: class TestImageCollection(): pattern = [os.path.join(data_dir, pic) for pic in ['camera.png', 'color.png']] + pattern_matched = [os.path.join(data_dir, pic) for pic in + ['camera.png', 'moon.png']] def setUp(self): self.collection = ImageCollection(self.pattern) + self.collection_matched = ImageCollection(self.pattern_matched) def test_len(self): assert len(self.collection) == 2 @@ -59,6 +62,12 @@ class TestImageCollection(): ic = ImageCollection(load_pattern, load_func=load_fn) assert_equal(ic[1], (2, 'two')) + def test_concatenate(self): + ar = self.collection_matched.concatenate() + assert_equal(ar.shape, (len(self.collection_matched),) + + self.collection[0].shape) + assert_raises(ValueError, self.collection.concatenate) + class TestMultiImage(): From a61ac37ff2e848ffafc34a95e751f6363f5a5956 Mon Sep 17 00:00:00 2001 From: Juan Nunez-Iglesias Date: Fri, 20 Jul 2012 16:46:33 -0500 Subject: [PATCH 3/3] Add concatenate() support for MultiImage Previously we added the ImageCollection.concatenate function. This updates MultiImage to have the same functionality, and moves the grunt work to an outside function to avoid repetition. --- skimage/io/collection.py | 65 +++++++++++++++++++++++++---- skimage/io/tests/test_collection.py | 6 +++ 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/skimage/io/collection.py b/skimage/io/collection.py index 7a07aa7f..1e31bd1d 100644 --- a/skimage/io/collection.py +++ b/skimage/io/collection.py @@ -2,13 +2,42 @@ from __future__ import with_statement -__all__ = ['MultiImage', 'ImageCollection', 'imread'] +__all__ = ['MultiImage', 'ImageCollection', 'imread', 'concatenate_images'] from glob import glob import numpy as np from ._io import imread +def concatenate_images(ic): + """Concatenate all images in the image collection into an array. + + Parameters + ---------- + ic: an iterable of images (including ImageCollection and MultiImage) + The images to be concatenated. + + Returns + ------- + ar : np.ndarray + An array having one more dimension than the images in `ic`. + + See Also + -------- + `ImageCollection.concatenate`, `MultiImage.concatenate` + + Raises + ------ + ValueError + If images in `ic` don't have identical shapes. + """ + all_images = [img[np.newaxis, ...] for img in ic] + try: + ar = np.concatenate(all_images) + except ValueError: + raise ValueError('Image dimensions must agree.') + return ar + class MultiImage(object): """A class containing a single multi-frame image. @@ -142,6 +171,24 @@ class MultiImage(object): def __str__(self): return str(self.filename) + ' [%s frames]' % self._numframes + def concatenate(self): + """Concatenate all images in the multi-image into an array. + + Returns + ------- + ar : np.ndarray + An array having one more dimension than the images in `self`. + + See Also + -------- + `concatenate_images` + + Raises + ------ + ValueError + If images in the `MultiImage` don't have identical shapes. + """ + return concatenate_images(self) class ImageCollection(object): """Load and manage a collection of image files. @@ -309,21 +356,21 @@ class ImageCollection(object): self.data = np.empty_like(self.data) def concatenate(self): - """Concatenate all images in the collection on a new axis. + """Concatenate all images in the collection into an array. Returns ------- ar : np.ndarray An array having one more dimension than the images in `self`. + See Also + -------- + `concatenate_images` + Raises ------ ValueError - If images in the collection don't have identical shapes. + If images in the `ImageCollection` don't have identical shapes. """ - all_images = [img[np.newaxis, ...] for img in self] - try: - ar = np.concatenate(all_images) - except ValueError: - raise ValueError('Image dimensions must agree.') - return ar + return concatenate_images(self) + diff --git a/skimage/io/tests/test_collection.py b/skimage/io/tests/test_collection.py index 6ddae6fe..9dd266bf 100644 --- a/skimage/io/tests/test_collection.py +++ b/skimage/io/tests/test_collection.py @@ -111,6 +111,12 @@ class TestMultiImage(): self.img.conserve_memory = val assert_raises(AttributeError, set_mem, True) + @skipif(not PIL_available) + def test_concatenate(self): + ar = self.img.concatenate() + assert_equal(ar.shape, (len(self.img),) + + self.img[0].shape) + if __name__ == "__main__": run_module_suite()