-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Closed
Description
Intro
The other day, I tried to speed up the training process of our project by saving training images after the deterministic transformations had been executed. (Resampling in particular). I encountered the following problem:
Expectation
Saved images are equal or almost equal (np.allclose(X, X_hat) == True)
Procedure
- Loading images
- Performing transformations (It turned out, the culprit is the resampling procedure) and getting X
- save image X to file but also keep it in memory. By default, it resamples the image back to the original affine_matrix. So, turn resampling off. It is possible to delete the original affine matrix, but that is not preferable.
- load file and store it in X_hat
- Check for equality, turns out, it is not.
Concluding thoughts
It seems that the orientation changes during saving, even if resampling is off. Is this by design, or is this a bug? I have tried all kinds of saving images, i.e. NiftiSaver, the transformation, etcetera. idem for the loader, i.e. LoadImage, ImageDataset, etcetera. Probably, they all share the same implementation, so that does not really help.
kind regards,
Code
import numpy as np
import monai
def create_random_img():
Random = np.random.default_rng()
image = Random.standard_normal((256, 256, 35))
original_affine = np.asarray(
[
[1.1e-2, -4e-3, 4.3, 3.3e1],
[-7e-1, -1e-2, 6.5e-2, 2.1e2],
[-1e-2, 7e1, 2.9e-2, -1.9e2],
[0, 0, 0, 1],
]
) # Copied from a dataset (So a valid sample!)
original_file_name = "Test.nii.gz"
meta_data = {
"affine": original_affine,
"original_affine": original_affine,
"filename_or_obj": original_file_name,
}
return {"img": image, "img_meta_dict": meta_data}
def resample_image(image):
RESAMPLERD = monai.transforms.SpacingD(
keys=["img"], pixdim=[1, 1, 12], diagonal=True
)
return RESAMPLERD(image)
def save_image(image):
SAVER = monai.data.NiftiSaver(resample=False)
SAVER.save(image["img"], meta_data=image["img_meta_dict"])
new_file_name = "./Test/Test_seg.nii.gz" # Trust me on this
return image, new_file_name
def load_image(file_name):
LOADER = monai.transforms.LoadImage()
return LOADER(file_name)
def main():
image = create_random_img()
resampled_img = resample_image(image)
X = resampled_img
X["img"] = np.expand_dims(X["img"], 0)
_, file_name = save_image(X)
X_hat = load_image(file_name)
# This should (imo) not be necessary, but let's give it a go
image_hat = np.moveaxis(X_hat[0], [0, 2], [2, 0])
print(np.allclose(X["img"], image_hat)) # Expecting True (It is False)
if __name__ == "__main__":
main()Metadata
Metadata
Assignees
Labels
No labels