Repository navigation
Description
The contributor explanation below was written by leecoring in Korean and translated with OpenAI Codex. The technical clarification, reproduction code and diagnostic report were prepared with Codex. A friend originally suggested this bug candidate.
Contributor explanation
When saving multiple images with the same saver, the channel-axis setting from the first image can remain in the saver. A setting that should apply only to that image is then reused for later images, even when those images have a different channel layout, causing incorrect saving in SaveImage.
Previously, the saver kept and applied that modified setting. With the fix, it retains the original configuration and uses a separate copy of the settings for the current image during the actual save.
Technical clarification — assisted by Codex
The verified trigger is saving a channel-less array, using spatial_shape metadata, and then saving a channel-first volume with the same SaveImage instance. The first call sets the instance's data_kwargs["channel_dim"] to None. The later call then interprets its dimensions incorrectly. A fresh instance saves the same channel-first volume correctly.
Reproduction code — prepared with Codex
Run from an unmodified checkout of the official dev commit listed below, with PyTorch, NumPy and NiBabel installed:
import tempfile
from pathlib import Path
import nibabel as nib
import numpy as np
from monai.transforms import SaveImage
volume = np.arange(24, dtype=np.float32).reshape(2, 3, 4)
metadata = {"spatial_shape": volume.shape}
with tempfile.TemporaryDirectory() as directory:
saver = SaveImage(writer="NibabelWriter", resample=False, print_log=False)
saver(volume, metadata, filename=Path(directory) / "without_channel")
saver(volume[None], metadata, filename=Path(directory) / "with_channel")
saved = nib.load(Path(directory) / "with_channel.nii.gz")
print(saved.shape)
np.testing.assert_array_equal(saved.get_fdata(), volume)Expected and observed behavior — Codex-run local diagnostics
Expected: the second file has shape (2, 3, 4) and preserves all 24 voxel values.
Observed before the fix: the second file has shape (1, 2, 3) and retains only 6 values. The first file is correct. The failure also occurs without metadata on the second call. SaveImaged can reproduce this when a channel-less image and a channel-first label share its saver.
A local fix using a per-call copy of the data options preserves all values. Nine regression cases fail before that fix and pass afterward. The patch and tests are available locally for a follow-up PR.
Environment
- Official MONAI
devcommit:4e9b19ccb5199df8648e1dcdd3002a19f9103e8a. - macOS 15.5, arm64; Python 3.14.7; PyTorch 2.15.0; NumPy 2.5.4; NiBabel 5.4.2.
- Inputs are small synthetic arrays; no patient data is used.
Public GitHub searches for SaveImage, SaveImaged and "data_kwargs" on 2026-10-30 returned 97 distinct Issue/PR records. No matching open fix was identified within that search scope.
Activity