Skip to content

Reading Dicom: Rescaling does not allow pixel format change #5290

@PtiLuky

Description

@PtiLuky

Description

I have a dicom image stored as short, which has a rescaling into the "unsigned short" domain that cannot be loaded with ITK.

Bits allocated 16
Bits stored 16
High Bit 15
Pixel Representation 1

Rescale Intercept 32768
Rescale Slope 1
Rescale Type US

When itk::GDCMImageIO::ReadImageInformationis called, there is an exception raised "Pixel type larger than output type".

Steps to Reproduce

High level snippet:

    using ReaderType = itk::ImageFileReader<itk::Image<uint16_t, 2>>;
    typename ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName(a_path);
    reader->SetImageIO(itk::GDCMImageIO::New());
    reader->Update();

Minimal code snippet:

auto a_imageIO = itk::GDCMImageIO::New();
a_imageIO->SetFileName(dicomPath.c_str()); // this file has the tags listed above
a_imageIO->ReadImageInformation(); // This raises the exception and refuse to load

This is also reproducible with the code taken directly from void GDCMImageIO::InternalReadImageInformation() https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/IO/GDCM/src/itkGDCMImageIO.cxx#L538

       // snippet with code taken from "void GDCMImageIO::InternalReadImageInformation()"
        gdcm::ImageReader reader;
        reader.SetFileName(dicomPath.c_str());
        reader.Read();
        const gdcm::Image& image = reader.GetImage();
        const gdcm::PixelFormat& pixeltype = image.GetPixelFormat(); // This is "INT16" (value 5)

       // note this is slightly changed from GDCMImageIO::InternalReadImageInformation (where it's conditionally done)
        const float rescaleSlope = 1.;  // This part comes from the dicom tags reader, but is simplified here for ease of reproducibility
        const float rescaleIntercept = 32768.;  // This part comes from the dicom tags reader, but is simplified here for ease of reproducibility
        gdcm::Rescaler r;
        r.SetIntercept(rescaleIntercept );
        r.SetSlope(rescaleSlope );
        r.SetPixelFormat(pixeltype);
        auto outputpt = r.ComputeInterceptSlopePixelType(); // This is "UINT16" (value 4)
        // Note: end of the "changed" part, the following condition is in current ITK master branch

        if (pixeltype > outputpt) { // INT16 > UINT16, despite the fact that after rescaling result will fit in UINT16...
            itkAssertInDebugOrThrowInReleaseMacro("Pixel type larger than output type")
        }

Expected behavior

Load image correctly without any exception. Like in other readers such as VTK or MicroDicom.

Actual behavior

Exception raised "Pixel type larger than output type".
Printed logs:

"<redacted>\\InsightToolkit-5.2.1\\Modules\\IO\\GDCM\\src\\itkGDCMImageIO.cxx:524:\nITK ERROR: Pixel type larger than output type"

Reproducibility

All the time given the problematic input image.

Versions

Currently testing with 5.2.1, but I see the problematic check still done in master branch.

Environment

Windows 10, MSVC

Additional Information

I do not see any reason for this check to be done, it means if my stored data is int32 and I have a rescale/slope that project the result into a int8 range itk raises an error? I see nothing wrong with that...

   if (pixeltype > outputpt) {
        itkAssertInDebugOrThrowInReleaseMacro("Pixel type larger than output type")
    }

Would there be any workaround other than removing the rescaling from the tags, load the image, and then reapply it manually afterward?

Metadata

Metadata

Assignees

No one assigned

    Labels

    type:BugInconsistencies or issues which will cause an incorrect result under some or all circumstances

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions