Skip to content

Recommended reader for .nrrd files? NRRDReader gives wrong output for non-diagonal orientations #7371

Closed
@surajpaib

Description

@surajpaib

Describe the bug

The default reader for '.nrrd' file extensions is the NRRDReader as shown in the docs, (https://docs.monai.io/en/stable/transforms.html#loadimage) as well as used by LoadImage when trying to load the file type (all dependencies are installed)

However, NRRDReader does not work accurately for non-diagonal orientation matrices.

ITKReader seems to work reliably for each use case, whereas NRRDReader doesn't.

Is there a reason why NRRDReader is preferred over the ITKReader? Also, since ITKReader reads nifti files, why is it not the default reader selected for all such formats?

To Reproduce

Code using the default NRRDReader:

import monai
import matplotlib.pyplot as plt

nrrd_datalist = ["path_to_nrrd_file"]

transform = monai.transforms.Compose([
                                      monai.transforms.LoadImage(image_only=True, ensure_channel_first=True),
                                      monai.transforms.DataStats(additional_info=lambda x: x.affine, prefix="On load"),
                                      monai.transforms.Orientation(axcodes="LPS"), 
                                      monai.transforms.Transpose(indices=[0, 3, 2, 1]),
                                      monai.transforms.DataStats(additional_info=lambda x: x.affine, prefix="After transform")
                                      ])

out = transform(nrrd_datalist)


# Get the mid indexes for each dimension
img = out[0][0]
mid_dim0 = img.shape[0] // 2
mid_dim1 = img.shape[1] // 2
mid_dim2 = img.shape[2] // 2

# Plot mid-axial, sagittal and coronal views
fig, axs = plt.subplots(1, 3, figsize=(15, 5))
axs[0].imshow(img[mid_dim0, :, :], cmap='gray')
axs[0].set_title('Mid dim0')
axs[1].imshow(img[:, mid_dim1, :], cmap='gray')
axs[1].set_title('Mid dim1')
axs[2].imshow(img[:, :, mid_dim2], cmap='gray')
axs[2].set_title('Mid dim2')
plt.show()

On load statistics:
Type: <class 'monai.data.meta_tensor.MetaTensor'> torch.float32
Shape: torch.Size([1, 512, 512, 78])
Value range: (-1024.0, 3071.0)
Additional info: tensor([[ 0.0000, -0.4941, 0.0000, -262.2529],
[ 0.4941, 0.0000, 0.0000, 56.2529],
[ 0.0000, 0.0000, 1.5000, 59.5000],
[ 0.0000, 0.0000, 0.0000, 1.0000]], dtype=torch.float64)

After transform statistics:
Type: <class 'monai.data.meta_tensor.MetaTensor'> torch.float32
Shape: torch.Size([1, 78, 512, 512])
Value range: (-1024.0, 3071.0)
Additional info: tensor([[ -0.4941, 0.0000, 0.0000, -262.2529],
[ 0.0000, -0.4941, 0.0000, 308.7588],
[ 0.0000, 0.0000, 1.5000, 59.5000],
[ 0.0000, 0.0000, 0.0000, 1.0000]], dtype=torch.float64)

image

Code using ITKReader:

import monai
import matplotlib.pyplot as plt

nrrd_datalist = ["path_to_nrrd_file"]

transform = monai.transforms.Compose([
                                      monai.transforms.LoadImage(image_only=True, ensure_channel_first=True, reader="ITKReader"),
                                      monai.transforms.DataStats(additional_info=lambda x: x.affine, prefix="On load"),
                                      monai.transforms.Orientation(axcodes="LPS"), 
                                      monai.transforms.Transpose(indices=[0, 3, 2, 1]),
                                      monai.transforms.DataStats(additional_info=lambda x: x.affine, prefix="After transform")
                                      ])

out = transform(nrrd_datalist)


# Get the mid indexes for each dimension
img = out[0][0]
mid_dim0 = img.shape[0] // 2
mid_dim1 = img.shape[1] // 2
mid_dim2 = img.shape[2] // 2

# Plot mid-axial, sagittal and coronal views
fig, axs = plt.subplots(1, 3, figsize=(15, 5))
axs[0].imshow(img[mid_dim0, :, :], cmap='gray')
axs[0].set_title('Mid dim0')
axs[1].imshow(img[:, mid_dim1, :], cmap='gray')
axs[1].set_title('Mid dim1')
axs[2].imshow(img[:, :, mid_dim2], cmap='gray')
axs[2].set_title('Mid dim2')
plt.show()

On load statistics:
Type: <class 'monai.data.meta_tensor.MetaTensor'> torch.float32
Shape: torch.Size([1, 512, 512, 78])
Value range: (-1024.0, 3071.0)
Additional info: tensor([[ 0.0000, 0.4941, 0.0000, -262.2529],
[ -0.4941, 0.0000, 0.0000, 56.2529],
[ 0.0000, 0.0000, 1.5000, 59.5000],
[ 0.0000, 0.0000, 0.0000, 1.0000]], dtype=torch.float64)

After transform statistics:
Type: <class 'monai.data.meta_tensor.MetaTensor'> torch.float32
Shape: torch.Size([1, 78, 512, 512])
Value range: (-1024.0, 3071.0)
Additional info: tensor([[-0.4941, 0.0000, 0.0000, -9.7471],
[ 0.0000, -0.4941, 0.0000, 56.2529],
[ 0.0000, 0.0000, 1.5000, 59.5000],
[ 0.0000, 0.0000, 0.0000, 1.0000]], dtype=torch.float64)

image

Environment
monai_env_config.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions