diff --git a/monai/data/image_reader.py b/monai/data/image_reader.py index 515bf38a39..9438582656 100644 --- a/monai/data/image_reader.py +++ b/monai/data/image_reader.py @@ -1112,6 +1112,8 @@ def get_data(self, img) -> tuple[np.ndarray, dict]: for i, filename in zip(ensure_tuple(img), self.filenames): header = self._get_meta_dict(i) + if MetaKeys.PIXDIM in header: + header[MetaKeys.ORIGINAL_PIXDIM] = np.array(header[MetaKeys.PIXDIM], copy=True) header[MetaKeys.AFFINE] = self._get_affine(i) header[MetaKeys.ORIGINAL_AFFINE] = self._get_affine(i) header["as_closest_canonical"] = self.as_closest_canonical diff --git a/monai/transforms/inverse.py b/monai/transforms/inverse.py index 2f57f4614a..ecf918f47a 100644 --- a/monai/transforms/inverse.py +++ b/monai/transforms/inverse.py @@ -22,7 +22,7 @@ from monai import transforms from monai.data.meta_obj import MetaObj, get_track_meta from monai.data.meta_tensor import MetaTensor -from monai.data.utils import to_affine_nd +from monai.data.utils import affine_to_spacing, to_affine_nd from monai.transforms.traits import InvertibleTrait from monai.transforms.transform import Transform from monai.utils import ( @@ -224,6 +224,9 @@ def track_transform_meta( else: raise out_obj.meta[MetaKeys.AFFINE] = convert_to_tensor(affine, device=torch.device("cpu"), dtype=torch.float64) + if MetaKeys.PIXDIM in out_obj.meta: + spacing = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) + out_obj.meta[MetaKeys.PIXDIM][1 : 1 + len(spacing)] = spacing if not (get_track_meta() and transform_info and transform_info.get(TraceKeys.TRACING)): if isinstance(data, Mapping): diff --git a/monai/transforms/spatial/dictionary.py b/monai/transforms/spatial/dictionary.py index a61d794183..c1a10957c2 100644 --- a/monai/transforms/spatial/dictionary.py +++ b/monai/transforms/spatial/dictionary.py @@ -29,6 +29,7 @@ from monai.data.box_utils import BoxMode, StandardMode from monai.data.meta_obj import get_track_meta from monai.data.meta_tensor import MetaTensor +from monai.data.utils import is_supported_format from monai.networks.layers.simplelayers import GaussianFilter from monai.transforms.croppad.array import CenterSpatialCrop from monai.transforms.inverse import InvertibleTransform @@ -521,6 +522,13 @@ def __call__(self, data: Mapping[Hashable, torch.Tensor], lazy: bool | None = No output_spatial_shape=output_shape_k if should_match else None, lazy=lazy_, ) + if isinstance(d[key], MetaTensor): + meta_keys = [k for k in d.keys() if k is not None and k.startswith(f"{key}_")] + for meta_key in meta_keys: + if "filename_or_obj" in d[key].meta and is_supported_format( + d[key].meta["filename_or_obj"], ["nii", "nii.gz"] + ): + d[meta_key].update(d[key].meta) if output_shape_k is None: output_shape_k = d[key].peek_pending_shape() if isinstance(d[key], MetaTensor) else d[key].shape[1:] return d diff --git a/monai/utils/enums.py b/monai/utils/enums.py index f5bb6c4c5b..be00b27d73 100644 --- a/monai/utils/enums.py +++ b/monai/utils/enums.py @@ -542,6 +542,8 @@ class MetaKeys(StrEnum): Typical keys for MetaObj.meta """ + PIXDIM = "pixdim" # MetaTensor.pixdim + ORIGINAL_PIXDIM = "original_pixdim" # the pixdim after image loading before any data processing AFFINE = "affine" # MetaTensor.affine ORIGINAL_AFFINE = "original_affine" # the affine after image loading before any data processing SPATIAL_SHAPE = "spatial_shape" # optional key for the length in each spatial dimension