diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 490fb89..4fe2cea 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v3 - name: Install Python dependencies - run: pip install ipython numpydoc pytest scikit-image sphinx sphinx-copybutton sphinx-rtd-theme + run: pip install ipython numpydoc pytest imageio sphinx sphinx-copybutton sphinx-rtd-theme - name: Install pims run: python -m pip install -v . diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index bed2928..670a81b 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -32,7 +32,7 @@ jobs: set -vxeuo pipefail python -m pip install -v . if [[ ${{ matrix.optional-deps }} = extras ]]; then - python -mpip install av jinja2 jpype1 matplotlib moviepy scikit-image tifffile + python -mpip install av jinja2 jpype1 matplotlib moviepy imageio tifffile fi python -m pip install coverage pytest python -m pip list diff --git a/doc/source/install.rst b/doc/source/install.rst index d2234f1..71d6a0f 100644 --- a/doc/source/install.rst +++ b/doc/source/install.rst @@ -10,6 +10,7 @@ PIMS is easy to install on Windows, OSX, or Linux. Its dependencies are: For basic image reading one of the following is required: +* `imageio `_ * `scikit-image `_ * `matplotlib `_ diff --git a/environment.yml b/environment.yml index ccec4f5..9f56667 100644 --- a/environment.yml +++ b/environment.yml @@ -7,7 +7,6 @@ dependencies: - slicerator - pillow - matplotlib -- scikit-image - jinja2 - av - tifffile diff --git a/pims/image_reader.py b/pims/image_reader.py index 2ccef20..071a7b0 100644 --- a/pims/image_reader.py +++ b/pims/image_reader.py @@ -4,8 +4,6 @@ from pims.frame import Frame try: - from skimage.io import imread -except ImportError: try: from imageio import v2 as iio except ImportError: @@ -13,7 +11,8 @@ def imread(*args, **kwargs): # Strip metadata for consistency. return np.asarray(iio.imread(*args, **kwargs)) - +except ImportError: + from skimage.io import imread class ImageReader(FramesSequence): """Reads a single image into a length-1 reader. diff --git a/pims/image_sequence.py b/pims/image_sequence.py index 2571f85..e371548 100644 --- a/pims/image_sequence.py +++ b/pims/image_sequence.py @@ -27,7 +27,7 @@ class ImageSequence(FramesSequence): which will ignore extraneous files or a list of files to open in the order they should be loaded. When a path to a zipfile is specified, all files in the zipfile will be loaded. - plugin : string + plugin : string, optional, deprecated Passed on to skimage.io.imread if scikit-image is available. If scikit-image is not available, this will be ignored and a warning will be issued. Not available in combination with zipfiles. @@ -51,15 +51,15 @@ class ImageSequence(FramesSequence): >>> frame_count = len(video) # Number of frames in video >>> frame_shape = video.frame_shape # Pixel dimensions of video """ - def __init__(self, path_spec, plugin=None): - if not imread.__module__.startswith("skimage"): - if plugin is not None: - warn("A plugin was specified but ignored. Plugins can only " - "be specified if scikit-image is available. Instead, " - "ImageSequence will use imageio") - self.kwargs = dict() - else: - self.kwargs = dict(plugin=plugin) + def __init__(self, path_spec, **kwargs): + self.kwargs = kwargs + if 'plugin' in self.kwargs: + warn_msg = "The 'plugin' parameter is deprecated and will be removed in a future release." + if imread.__module__.startswith("skimage"): + warn(warn_msg, DeprecationWarning) + else: + warn(warn_msg + " 'plugin' will be ignored because imageio is used for image reading.", DeprecationWarning) + self.kwargs.pop('plugin') self._is_zipfile = False self._zipfile = None @@ -333,7 +333,7 @@ class ImageSequenceND(FramesSequenceND, ImageSequence): specified, all files in the zipfile will be loaded. The filenames should contain the indices of T, Z and C, preceded by a axis identifier such as: 'file_t001c05z32'. - plugin : string, optional + plugin : string, optional, deprecated Passed on to skimage.io.imread if scikit-image is available. If scikit-image is not available, this will be ignored and a warning will be issued. Not available in combination with zipfiles. diff --git a/pims/tests/test_imseq.py b/pims/tests/test_imseq.py index 150905c..941b782 100644 --- a/pims/tests/test_imseq.py +++ b/pims/tests/test_imseq.py @@ -28,9 +28,8 @@ def setUp(self): self.filename = os.path.join(self.filepath, '*.png') self.frame0 = frames[0] self.frame1 = frames[1] - self.kwargs = dict(plugin='pil') self.klass = pims.ImageSequence - self.v = self.klass(self.filename, **self.kwargs) + self.v = self.klass(self.filename) self.expected_shape = shape self.expected_len = 5 self.tempdir = tempfile.mkdtemp() @@ -52,6 +51,10 @@ def tearDown(self): os.remove(self.tempfile) os.rmdir(self.tempdir) + def test_plugin_deprecation(self): + with self.assertWarns(DeprecationWarning): + pims.ImageSequence(self.filename, plugin='PIL') + class TestImageSequenceWithMPL(_image_series, unittest.TestCase): def setUp(self): @@ -65,9 +68,8 @@ def setUp(self): self.filename = os.path.join(self.filepath, '*.png') self.frame0 = frames[0] self.frame1 = frames[1] - self.kwargs = dict(plugin='matplotlib') self.klass = pims.ImageSequence - self.v = self.klass(self.filename, **self.kwargs) + self.v = self.klass(self.filename) self.expected_shape = shape self.expected_len = 5 @@ -89,9 +91,8 @@ def setUp(self): for fn in self.filenames] self.frame0 = frames[0] self.frame1 = frames[1] - self.kwargs = dict(plugin='matplotlib') self.klass = pims.ImageSequence - self.v = self.klass(self.filename, **self.kwargs) + self.v = self.klass(self.filename) self.expected_shape = shape self.expected_len = len(self.filenames) @@ -112,9 +113,8 @@ def setUp(self): self.filename = os.path.join(self.filepath, 'T76*.png') self.frame0 = frames[0] self.frame1 = frames[2] - self.kwargs = dict(plugin='matplotlib') self.klass = pims.ImageSequence - self.v = self.klass(self.filename, **self.kwargs) + self.v = self.klass(self.filename) self.expected_shape = shape self.expected_len = len(self.filenames)