saim1309 commited on
Commit
05e0516
·
verified ·
1 Parent(s): 1c676ad

Upload LoadImage.py

Browse files
Files changed (1) hide show
  1. LoadImage.py +161 -0
LoadImage.py ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import tifffile as tif
3
+ import skimage.io as io
4
+ from typing import Optional, Sequence, Union
5
+ from monai.config import DtypeLike, PathLike, KeysCollection
6
+ from monai.utils import ensure_tuple
7
+ from monai.data.utils import is_supported_format, optional_import, ensure_tuple_rep
8
+ from monai.data.image_reader import ImageReader, NumpyReader
9
+ from monai.transforms import LoadImage, LoadImaged
10
+ from monai.utils.enums import PostFix
11
+
12
+ DEFAULT_POST_FIX = PostFix.meta()
13
+ itk, has_itk = optional_import("itk", allow_namespace_pkg=True)
14
+
15
+ __all__ = [
16
+ "CustomLoadImaged",
17
+ "CustomLoadImageD",
18
+ "CustomLoadImageDict",
19
+ "CustomLoadImage",
20
+ ]
21
+
22
+
23
+ class CustomLoadImage(LoadImage):
24
+ """
25
+ Load image file or files from provided path based on reader.
26
+ If reader is not specified, this class automatically chooses readers
27
+ based on the supported suffixes and in the following order:
28
+
29
+ - User-specified reader at runtime when calling this loader.
30
+ - User-specified reader in the constructor of `LoadImage`.
31
+ - Readers from the last to the first in the registered list.
32
+ - Current default readers: (nii, nii.gz -> NibabelReader), (png, jpg, bmp -> PILReader),
33
+ (npz, npy -> NumpyReader), (nrrd -> NrrdReader), (DICOM file -> ITKReader).
34
+
35
+ [!Caution] This overriding replaces the original ITK with Custom UnifiedITKReader.
36
+ """
37
+
38
+ def __init__(
39
+ self,
40
+ reader=None,
41
+ image_only: bool = False,
42
+ dtype: DtypeLike = np.float32,
43
+ ensure_channel_first: bool = False,
44
+ *args,
45
+ **kwargs,
46
+ ) -> None:
47
+ super(CustomLoadImage, self).__init__(
48
+ reader, image_only, dtype, ensure_channel_first, *args, **kwargs
49
+ )
50
+
51
+ # Adding TIFFReader. Although ITK Reader supports ".tiff" files, sometimes fails to load images.
52
+ self.readers = []
53
+ self.register(UnifiedITKReader(*args, **kwargs))
54
+
55
+
56
+ class CustomLoadImaged(LoadImaged):
57
+ """
58
+ Dictionary-based wrapper of `CustomLoadImage`.
59
+ """
60
+
61
+ def __init__(
62
+ self,
63
+ keys: KeysCollection,
64
+ reader: Optional[Union[ImageReader, str]] = None,
65
+ dtype: DtypeLike = np.float32,
66
+ meta_keys: Optional[KeysCollection] = None,
67
+ meta_key_postfix: str = DEFAULT_POST_FIX,
68
+ overwriting: bool = False,
69
+ image_only: bool = False,
70
+ ensure_channel_first: bool = False,
71
+ simple_keys=False,
72
+ allow_missing_keys: bool = False,
73
+ *args,
74
+ **kwargs,
75
+ ) -> None:
76
+ super(CustomLoadImaged, self).__init__(
77
+ keys,
78
+ reader,
79
+ dtype,
80
+ meta_keys,
81
+ meta_key_postfix,
82
+ overwriting,
83
+ image_only,
84
+ ensure_channel_first,
85
+ simple_keys,
86
+ allow_missing_keys,
87
+ *args,
88
+ **kwargs,
89
+ )
90
+
91
+ # Assign CustomLoader
92
+ self._loader = CustomLoadImage(
93
+ reader, image_only, dtype, ensure_channel_first, *args, **kwargs
94
+ )
95
+ if not isinstance(meta_key_postfix, str):
96
+ raise TypeError(
97
+ f"meta_key_postfix must be a str but is {type(meta_key_postfix).__name__}."
98
+ )
99
+ self.meta_keys = (
100
+ ensure_tuple_rep(None, len(self.keys))
101
+ if meta_keys is None
102
+ else ensure_tuple(meta_keys)
103
+ )
104
+ if len(self.keys) != len(self.meta_keys):
105
+ raise ValueError("meta_keys should have the same length as keys.")
106
+ self.meta_key_postfix = ensure_tuple_rep(meta_key_postfix, len(self.keys))
107
+ self.overwriting = overwriting
108
+
109
+
110
+ class UnifiedITKReader(NumpyReader):
111
+ """
112
+ Unified Reader to read ".tif" and ".tiff files".
113
+ As the tifffile reads the images as numpy arrays, it inherits from the NumpyReader.
114
+ """
115
+
116
+ def __init__(
117
+ self, channel_dim: Optional[int] = None, **kwargs,
118
+ ):
119
+ super(UnifiedITKReader, self).__init__(channel_dim=channel_dim, **kwargs)
120
+ self.kwargs = kwargs
121
+ self.channel_dim = channel_dim
122
+
123
+ def verify_suffix(self, filename: Union[Sequence[PathLike], PathLike]) -> bool:
124
+ """Verify whether the file format is supported by TIFF Reader."""
125
+
126
+ suffixes: Sequence[str] = ["tif", "tiff", "png", "jpg", "bmp", "jpeg",]
127
+ return has_itk or is_supported_format(filename, suffixes)
128
+
129
+ def read(self, data: Union[Sequence[PathLike], PathLike], **kwargs):
130
+ """Read Images from the file."""
131
+ img_ = []
132
+
133
+ filenames: Sequence[PathLike] = ensure_tuple(data)
134
+ kwargs_ = self.kwargs.copy()
135
+ kwargs_.update(kwargs)
136
+
137
+ for name in filenames:
138
+ name = f"{name}"
139
+
140
+ if name.endswith(".tif") or name.endswith(".tiff"):
141
+ _obj = tif.imread(name)
142
+ else:
143
+ try:
144
+ _obj = itk.imread(name, **kwargs_)
145
+ _obj = itk.array_view_from_image(_obj, keep_axes=False)
146
+ except:
147
+ _obj = io.imread(name)
148
+
149
+ if len(_obj.shape) == 2:
150
+ _obj = np.repeat(np.expand_dims(_obj, axis=-1), 3, axis=-1)
151
+ elif len(_obj.shape) == 3 and _obj.shape[-1] > 3:
152
+ _obj = _obj[:, :, :3]
153
+ else:
154
+ pass
155
+
156
+ img_.append(_obj)
157
+
158
+ return img_ if len(filenames) > 1 else img_[0]
159
+
160
+
161
+ CustomLoadImageD = CustomLoadImageDict = CustomLoadImaged