Skip to content

Commit a7835ab

Browse files
authored
3565 - adds metadata when loading dicom series (#3566)
* adds metadata when loading dicom series Signed-off-by: Wenqi Li <wenqil@nvidia.com> * fixes timed tests Signed-off-by: Wenqi Li <wenqil@nvidia.com> * update based on comments Signed-off-by: Wenqi Li <wenqil@nvidia.com>
1 parent 9417ff2 commit a7835ab

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

monai/data/image_reader.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,19 +159,27 @@ class ITKReader(ImageReader):
159159
If ``False``, the spatial indexing follows the numpy convention;
160160
otherwise, the spatial indexing convention is reversed to be compatible with ITK. Default is ``False``.
161161
This option does not affect the metadata.
162+
series_meta: whether to load the metadata of the DICOM series (using the metadata from the first slice).
163+
This flag is checked only when loading DICOM series. Default is ``False``.
162164
kwargs: additional args for `itk.imread` API. more details about available args:
163165
https://github.com/InsightSoftwareConsortium/ITK/blob/master/Wrapping/Generators/Python/itk/support/extras.py
164166
165167
"""
166168

167169
def __init__(
168-
self, channel_dim: Optional[int] = None, series_name: str = "", reverse_indexing: bool = False, **kwargs
170+
self,
171+
channel_dim: Optional[int] = None,
172+
series_name: str = "",
173+
reverse_indexing: bool = False,
174+
series_meta: bool = False,
175+
**kwargs,
169176
):
170177
super().__init__()
171178
self.kwargs = kwargs
172179
self.channel_dim = channel_dim
173180
self.series_name = series_name
174181
self.reverse_indexing = reverse_indexing
182+
self.series_meta = series_meta
175183

176184
def verify_suffix(self, filename: Union[Sequence[PathLike], PathLike]) -> bool:
177185
"""
@@ -221,7 +229,17 @@ def read(self, data: Union[Sequence[PathLike], PathLike], **kwargs):
221229
series_identifier = series_uid[0] if not self.series_name else self.series_name
222230
name = names_generator.GetFileNames(series_identifier)
223231

224-
img_.append(itk.imread(name, **kwargs_))
232+
_obj = itk.imread(name, **kwargs_)
233+
if self.series_meta:
234+
_reader = itk.ImageSeriesReader.New(FileNames=name)
235+
_reader.Update()
236+
_meta = _reader.GetMetaDataDictionaryArray()
237+
if len(_meta) > 0:
238+
# TODO: using the first slice's meta. this could be improved to filter unnecessary tags.
239+
_obj.SetMetaDataDictionary(_meta[0])
240+
img_.append(_obj)
241+
else:
242+
img_.append(itk.imread(name, **kwargs_))
225243
return img_ if len(filenames) > 1 else img_[0]
226244

227245
def get_data(self, img):

tests/test_load_image.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,15 @@ def test_my_reader(self):
254254
out = LoadImage()("test", reader=_MiniReader(is_compatible=False))
255255
self.assertEqual(out[1]["name"], "my test")
256256

257+
def test_itk_meta(self):
258+
"""test metadata from a directory"""
259+
out, meta = LoadImage(reader="ITKReader", pixel_type=itk.UC, series_meta=True)("tests/testing_data/CT_DICOM")
260+
idx = "0008|103e"
261+
label = itk.GDCMImageIO.GetLabelFromTag(idx, "")[1]
262+
val = meta[idx]
263+
expected = "Series Description=Routine Brain "
264+
self.assertEqual(f"{label}={val}", expected)
265+
257266

258267
if __name__ == "__main__":
259268
unittest.main()

tests/test_timedcall_dist.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from tests.utils import TimedCall
1818

1919

20-
@TimedCall(seconds=10 if sys.platform == "linux" else 60, force_quit=False)
20+
@TimedCall(seconds=20 if sys.platform == "linux" else 60, force_quit=False)
2121
def case_1_seconds(arg=None):
2222
time.sleep(1)
2323
return "good" if not arg else arg

0 commit comments

Comments
 (0)