1# -*- coding: utf-8 -*-
2# imageio is distributed under the terms of the (new) BSD License.
3
4""" Read/Write images using SimpleITK.
5
6Backend: `Insight Toolkit <https://itk.org/>`_
7
8.. note::
9 To use this plugin you have to install its backend::
10
11 pip install imageio[itk]
12
13The ItkFormat uses the ITK or SimpleITK library to support a range of
14ITK-related formats. It also supports a few common formats (e.g. PNG and JPEG).
15
16Parameters
17----------
18None
19
20"""
21
22from ..core import Format, has_module
23
24_itk = None # Defer loading to load_lib() function.
25
26
27def load_lib():
28 global _itk, _read_function, _write_function
29 try:
30 import itk as _itk
31
32 _read_function = _itk.imread
33 _write_function = _itk.imwrite
34 except ImportError:
35 try:
36 import SimpleITK as _itk
37
38 _read_function = _itk.ReadImage
39 _write_function = _itk.WriteImage
40 except ImportError:
41 raise ImportError(
42 "itk could not be found. "
43 "Please try "
44 " python -m pip install itk "
45 "or "
46 " python -m pip install simpleitk "
47 "or refer to "
48 " https://itkpythonpackage.readthedocs.io/ "
49 "for further instructions."
50 )
51 return _itk
52
53
54# Split up in real ITK and all supported formats.
55ITK_FORMATS = (
56 ".gipl",
57 ".ipl",
58 ".mha",
59 ".mhd",
60 ".nhdr",
61 "nia",
62 "hdr",
63 ".nrrd",
64 ".nii",
65 ".nii.gz",
66 ".img",
67 ".img.gz",
68 ".vtk",
69 "hdf5",
70 "lsm",
71 "mnc",
72 "mnc2",
73 "mgh",
74 "mnc",
75 "pic",
76)
77ALL_FORMATS = ITK_FORMATS + (
78 ".bmp",
79 ".jpeg",
80 ".jpg",
81 ".png",
82 ".tiff",
83 ".tif",
84 ".dicom",
85 ".dcm",
86 ".gdcm",
87)
88
89
90class ItkFormat(Format):
91 """See :mod:`imageio.plugins.simpleitk`"""
92
93 def _can_read(self, request):
94 # If the request is a format that only this plugin can handle,
95 # we report that we can do it; a useful error will be raised
96 # when simpleitk is not installed. For the more common formats
97 # we only report that we can read if the library is installed.
98 if request.extension in ITK_FORMATS:
99 return True
100 if has_module("itk.ImageIOBase") or has_module("SimpleITK"):
101 return request.extension in ALL_FORMATS
102
103 def _can_write(self, request):
104 if request.extension in ITK_FORMATS:
105 return True
106 if has_module("itk.ImageIOBase") or has_module("SimpleITK"):
107 return request.extension in ALL_FORMATS
108
109 # -- reader
110
111 class Reader(Format.Reader):
112 def _open(self, pixel_type=None, fallback_only=None, **kwargs):
113 if not _itk:
114 load_lib()
115 args = ()
116 if pixel_type is not None:
117 args += (pixel_type,)
118 if fallback_only is not None:
119 args += (fallback_only,)
120 self._img = _read_function(self.request.get_local_filename(), *args)
121
122 def _get_length(self):
123 return 1
124
125 def _close(self):
126 pass
127
128 def _get_data(self, index):
129 # Get data
130 if index != 0:
131 error_msg = "Index out of range while reading from itk file"
132 raise IndexError(error_msg)
133
134 # Return array and empty meta data
135 return _itk.GetArrayFromImage(self._img), {}
136
137 def _get_meta_data(self, index):
138 error_msg = "The itk plugin does not support meta data, currently."
139 raise RuntimeError(error_msg)
140
141 # -- writer
142 class Writer(Format.Writer):
143 def _open(self):
144 if not _itk:
145 load_lib()
146
147 def _close(self):
148 pass
149
150 def _append_data(self, im, meta):
151 _itk_img = _itk.GetImageFromArray(im)
152 _write_function(_itk_img, self.request.get_local_filename())
153
154 def set_meta_data(self, meta):
155 error_msg = "The itk plugin does not support meta data, currently."
156 raise RuntimeError(error_msg)