/
_io.py
221 lines (177 loc) · 6.43 KB
/
_io.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
import pathlib
import numpy as np
from .._shared.utils import warn
from .._shared.version_requirements import require
from ..exposure import is_low_contrast
from ..color.colorconv import rgb2gray, rgba2rgb
from ..io.manage_plugins import call_plugin
from .util import file_or_url_context
__all__ = [
'imread',
'imsave',
'imshow',
'show',
'imread_collection',
'imshow_collection',
]
def imread(fname, as_gray=False, plugin=None, **plugin_args):
"""Load an image from file.
Parameters
----------
fname : str or pathlib.Path
Image file name, e.g. ``test.jpg`` or URL.
as_gray : bool, optional
If True, convert color images to gray-scale (64-bit floats).
Images that are already in gray-scale format are not converted.
plugin : str, optional
Name of plugin to use. By default, the different plugins are
tried (starting with imageio) until a suitable
candidate is found. If not given and fname is a tiff file, the
tifffile plugin will be used.
Other Parameters
----------------
plugin_args : keywords
Passed to the given plugin.
Returns
-------
img_array : ndarray
The different color bands/channels are stored in the
third dimension, such that a gray-image is MxN, an
RGB-image MxNx3 and an RGBA-image MxNx4.
"""
if isinstance(fname, pathlib.Path):
fname = str(fname.resolve())
if plugin is None and hasattr(fname, 'lower'):
if fname.lower().endswith(('.tiff', '.tif')):
plugin = 'tifffile'
with file_or_url_context(fname) as fname:
img = call_plugin('imread', fname, plugin=plugin, **plugin_args)
if not hasattr(img, 'ndim'):
return img
if img.ndim > 2:
if img.shape[-1] not in (3, 4) and img.shape[-3] in (3, 4):
img = np.swapaxes(img, -1, -3)
img = np.swapaxes(img, -2, -3)
if as_gray:
if img.shape[2] == 4:
img = rgba2rgb(img)
img = rgb2gray(img)
return img
def imread_collection(load_pattern, conserve_memory=True, plugin=None, **plugin_args):
"""
Load a collection of images.
Parameters
----------
load_pattern : str or list
List of objects to load. These are usually filenames, but may
vary depending on the currently active plugin. See :class:`ImageCollection`
for the default behaviour of this parameter.
conserve_memory : bool, optional
If True, never keep more than one in memory at a specific
time. Otherwise, images will be cached once they are loaded.
Returns
-------
ic : :class:`ImageCollection`
Collection of images.
Other Parameters
----------------
plugin_args : keywords
Passed to the given plugin.
"""
return call_plugin(
'imread_collection', load_pattern, conserve_memory, plugin=plugin, **plugin_args
)
def imsave(fname, arr, plugin=None, check_contrast=True, **plugin_args):
"""Save an image to file.
Parameters
----------
fname : str or pathlib.Path
Target filename.
arr : ndarray of shape (M,N) or (M,N,3) or (M,N,4)
Image data.
plugin : str, optional
Name of plugin to use. By default, the different plugins are
tried (starting with imageio) until a suitable
candidate is found. If not given and fname is a tiff file, the
tifffile plugin will be used.
check_contrast : bool, optional
Check for low contrast and print warning (default: True).
Other Parameters
----------------
plugin_args : keywords
Passed to the given plugin.
Notes
-----
When saving a JPEG, the compression ratio may be controlled using the
``quality`` keyword argument which is an integer with values in [1, 100],
where 1 is worst quality and smallest file size, and 100 is the best quality
and largest file size (default 75). This is only available when using
the PIL and imageio plugins.
"""
if isinstance(fname, pathlib.Path):
fname = str(fname.resolve())
if plugin is None and hasattr(fname, 'lower'):
if fname.lower().endswith(('.tiff', '.tif')):
plugin = 'tifffile'
if arr.dtype == bool:
warn(
f'{fname} is a boolean image: setting True to 255 and False to 0. '
'To silence this warning, please convert the image using '
'img_as_ubyte.',
stacklevel=2,
)
arr = arr.astype('uint8') * 255
if check_contrast and is_low_contrast(arr):
warn(f'{fname} is a low contrast image')
return call_plugin('imsave', fname, arr, plugin=plugin, **plugin_args)
def imshow(arr, plugin=None, **plugin_args):
"""Display an image.
Parameters
----------
arr : ndarray or str
Image data or name of image file.
plugin : str
Name of plugin to use. By default, the different plugins are
tried (starting with imageio) until a suitable candidate is found.
Other Parameters
----------------
plugin_args : keywords
Passed to the given plugin.
"""
if isinstance(arr, str):
arr = call_plugin('imread', arr, plugin=plugin)
return call_plugin('imshow', arr, plugin=plugin, **plugin_args)
def imshow_collection(ic, plugin=None, **plugin_args):
"""Display a collection of images.
Parameters
----------
ic : :class:`ImageCollection`
Collection to display.
plugin : str
Name of plugin to use. By default, the different plugins are
tried until a suitable candidate is found.
Other Parameters
----------------
plugin_args : keywords
Passed to the given plugin.
"""
return call_plugin('imshow_collection', ic, plugin=plugin, **plugin_args)
@require("matplotlib", ">=3.3")
def show():
"""Display pending images.
Launch the event loop of the current GUI plugin, and display all
pending images, queued via `imshow`. This is required when using
`imshow` from non-interactive scripts.
A call to `show` will block execution of code until all windows
have been closed.
Examples
--------
.. testsetup::
>>> import pytest; _ = pytest.importorskip('matplotlib')
>>> import skimage.io as io
>>> rng = np.random.default_rng()
>>> for i in range(4):
... ax_im = io.imshow(rng.random((50, 50)))
>>> io.show() # doctest: +SKIP
"""
return call_plugin('_app_show')