diff --git a/monai/data/image_reader.py b/monai/data/image_reader.py index 003ec2cf0b..0d07020cb9 100644 --- a/monai/data/image_reader.py +++ b/monai/data/image_reader.py @@ -1110,6 +1110,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 f94f11eca9..780674ca4a 100644 --- a/monai/transforms/inverse.py +++ b/monai/transforms/inverse.py @@ -21,7 +21,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 ( @@ -197,6 +197,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 2b80034a07..b4171f2003 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 @@ -520,6 +521,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 3463a92e4b..3d8c18a6a3 100644 --- a/monai/utils/enums.py +++ b/monai/utils/enums.py @@ -529,6 +529,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