Does anyone have issues displaying PET and MR series in Slicer. Try these and please let me know if you have any ideas on why this happens…
(link has been removed until it is confirmed that the images do not contain PHI)
Thanks.
Does anyone have issues displaying PET and MR series in Slicer. Try these and please let me know if you have any ideas on why this happens…
(link has been removed until it is confirmed that the images do not contain PHI)
Thanks.
The DICOM header specifies that the pixel values are signed (PixelRepresentation=1):
[0028,0002] SamplesPerPixel 1 US 2
[0028,0004] PhotometricInterpretation MONOCHROME2 CS 12
[0028,0010] Rows 128 US 2
[0028,0011] Columns 128 US 2
[0028,0030] PixelSpacing [2] 5.46875, 5.46875 DS 16
[0028,0051] CorrectedImage [8] DECY, ATTN, SCAT, DTIM, RAN, DCAL, SLSENS, NORM CS 40
[0028,0100] BitsAllocated 16 US 2
[0028,0101] BitsStored 15 US 2
[0028,0102] HighBit 14 US 2
[0028,0103] PixelRepresentation 1 US 2
[0028,0106] SmallestImagePixelValue 0 SS 2
[0028,0107] LargestImagePixelValue 32766 SS 2
[0028,1050] WindowCenter 8438.388323078 DS 14
[0028,1051] WindowWidth 16876.776646156 DS 16
[0028,1052] RescaleIntercept 0 DS 2
[0028,1053] RescaleSlope 0.453101 DS 8
[0028,2110] LossyImageCompression 00 CS 2
To me, it seems that Slicer interprets the image correctly and image acquisition device created an incorrect DICOM header, but maybe there are some special cases that I’m not aware of.
Here is a sample image slice:
https://1drv.ms/u/s!Arm_AFxB9yqHxeRDMH6PKINz6CbeQA?e=SjnUk8
Slicer renders it like this:
While it should look like this:
@pieper @issakomi @Chris_Rorden Do you have any insights?
Hi @dougPorter -
I agree Slicer appears to be interpreting the pixel values according to the header.
Can you doublecheck that these files are representative of the files you need to support? I hope these are not like your real clinical images, because they have several inconsistencies as @lassoan points out. My guess is that these are some kind of old research files that were made by a non-standard process so they have errors that wouldn’t occur with real data. (Some vendors aren’t perfect in their dicom data, but these are particularly bad).
For example when I run this standard validation tool there are many red flags.
% dciodvfy /tmp/TestImages/PET/0.dcm
Warning - Retired attribute - (0x0032,0x1000) DA Scheduled Study Start Date
Warning - Retired attribute - (0x0032,0x1001) TM Scheduled Study Start Time
Warning - Retired attribute - (0x0032,0x1050) DA Study Completion Date
Warning - Retired attribute - (0x0032,0x1051) TM Study Completion Time
Warning - Dicom dataset contains retired attributes
PETImage
Error - Missing attribute Type 1 Required Element=<FileMetaInformationGroupLength> Module=<FileMetaInformation>
Warning - is only permitted to be empty when actually unknown; should be absent (not empty) if an unpaired body part, and have a value if a paired body part - attribute <Laterality>
Error - May not be present when PatientOrientationCodeSequence is present - attribute <PatientPosition>
Warning - Unrecognized defined term <SLSENS> for value 7 of attribute <Corrected Image>
Warning - Coding Scheme Designator is deprecated - attribute <CodingSchemeDesignator> = <SNM3>
Warning - Coding Scheme Designator is deprecated - attribute <CodingSchemeDesignator> = <SNM3>
Warning - Coding Scheme Designator is deprecated - attribute <CodingSchemeDesignator> = <SNM3>
Warning - Coding Scheme Designator is deprecated - attribute <CodingSchemeDesignator> = <SNM3>
Error - Missing attribute Type 1 Required Element=<FrameOfReferenceUID> Module=<FrameOfReference>
Error - Unrecognized enumerated value <0xf> for value 1 of attribute <Bits Stored>
Error - Unrecognized enumerated value <0xe> for value 1 of attribute <High Bit>
Error - Attribute present when condition unsatisfied (which may not be present otherwise) Type 1C Conditional Element=<TriggerTime> Module=<PETImage>
Error - Attribute present when condition unsatisfied (which may not be present otherwise) Type 1C Conditional Element=<FrameTime> Module=<PETImage>
Warning - Coding Scheme Designator is deprecated - attribute <CodingSchemeDesignator> = <SRT>
Warning - Attribute is not present in standard DICOM IOD - (0x0032,0x1000) DA Scheduled Study Start Date
Warning - Attribute is not present in standard DICOM IOD - (0x0032,0x1001) TM Scheduled Study Start Time
Warning - Attribute is not present in standard DICOM IOD - (0x0032,0x1032) PN Requesting Physician
Warning - Attribute is not present in standard DICOM IOD - (0x0032,0x1050) DA Study Completion Date
Warning - Attribute is not present in standard DICOM IOD - (0x0032,0x1051) TM Study Completion Time
Warning - Attribute is not present in standard DICOM IOD - (0x0008,0x0100) SH Code Value
Warning - Attribute is not present in standard DICOM IOD - (0x0008,0x0102) SH Coding Scheme Designator
Warning - Attribute is not present in standard DICOM IOD - (0x0008,0x0104) LO Code Meaning
Warning - Attribute is not present in standard DICOM IOD - (0x0054,0x0412) SQ Patient Orientation Modifier Code Sequence
Warning - Dicom dataset contains attributes not present in standard DICOM IOD - this is a Standard Extended SOP Class
and
% dciodvfy /tmp/TestImages/MR/0.dcm
Warning - Retired attribute - (0x0008,0x0040) US Data Set Type
Warning - Retired attribute - (0x0008,0x0041) LO Data Set Subtype
Warning - Retired attribute - (0x0032,0x1000) DA Scheduled Study Start Date
Warning - Retired attribute - (0x0032,0x1001) TM Scheduled Study Start Time
Warning - Retired attribute - (0x0032,0x1050) DA Study Completion Date
Warning - Retired attribute - (0x0032,0x1051) TM Study Completion Time
Warning - Dicom dataset contains retired attributes
MRImage
Error - Missing attribute Type 1 Required Element=<FileMetaInformationGroupLength> Module=<FileMetaInformation>
Warning - is only permitted to be empty when actually unknown; should be absent (not empty) if an unpaired body part, and have a value if a paired body part - attribute <Laterality>
Error - Missing attribute Type 1 Required Element=<FrameOfReferenceUID> Module=<FrameOfReference>
Warning - Unrecognized defined term <FAST_GEMS> for value 1 of attribute <Scan Options>
Error - Attribute present when condition unsatisfied (which may not be present otherwise) Type 2C Conditional Element=<InversionTime> Module=<MRImage>
Warning - Attribute is not present in standard DICOM IOD - (0x0008,0x0040) US Data Set Type
Warning - Attribute is not present in standard DICOM IOD - (0x0008,0x0041) LO Data Set Subtype
Warning - Attribute is not present in standard DICOM IOD - (0x0020,0x9056) SH Stack ID
Warning - Attribute is not present in standard DICOM IOD - (0x0020,0x9057) UL In-Stack Position Number
Warning - Attribute is not present in standard DICOM IOD - (0x0032,0x1000) DA Scheduled Study Start Date
Warning - Attribute is not present in standard DICOM IOD - (0x0032,0x1001) TM Scheduled Study Start Time
Warning - Attribute is not present in standard DICOM IOD - (0x0032,0x1032) PN Requesting Physician
Warning - Attribute is not present in standard DICOM IOD - (0x0032,0x1050) DA Study Completion Date
Warning - Attribute is not present in standard DICOM IOD - (0x0032,0x1051) TM Study Completion Time
Warning - Attribute is not present in standard DICOM IOD - (0x0040,0x0242) SH Performed Station Name
Warning - Attribute is not present in standard DICOM IOD - (0x0040,0x0243) SH Performed Location
Warning - Dicom dataset contains attributes not present in standard DICOM IOD - this is a Standard Extended SOP Class
OK, I’ll get some more recent images. QREADS and RDICOM apps may be more tolerable of invalid DICOM elements. I’ll let you know.
Darn it! Still there for image done today
What in the header do you think might be causing the problem?
Thanks
Hmm, that’s bad. Can you describe what vendor and processing pathway that is? We’ve worked with tons of PET data over the year with no issues like that.
Can you try running the tool I linked above (DICOM Validator - dciodvfy) and see if you get the same errors with the new data?
The problem is that PixelRepresentation
is set to 1, which means that the value is signed.
Could you check the source code of QREADS how it decides to read the voxel value as signed or unsigned short? For example, I saw another viewer checked the minimum pixel value tag and it set the value to unsigned if was >=0. It looked like an ugly workaround but if this is applied in many viewers then we may consider doing this, too.
@David_Clunie what would you recommend?
I also think there is an issue with bits stored and pixel representation. Look, in PET series - bits stored are 15, pixel representation 1 (signed) and values up to 32767, it is wrong, either bits stored should be 16 or pixel representation 0 (unsigned). Signed is valid for JPEG Lossless Transfer Syntaxes, but here is probably not required, no negative values, there were several bugs with processing of signed JPEG compressed data (actually in Slicer - no problem), so safer to avoid, if not required, IMHO.
In MR series bits stored vary from frame to frame 5-12 and pixel representation is also signed, i didn’t check values, but probably there is the same error.
I have tried to modify bits stored/high bit values (16/15) and left pixel representation signed, the data is not modified, of course, only above attributes. Seems that Slicer can load series.
Thanks for checking @issakomi - if this is a common enough pattern we could consider adding it to the DICOMPatcher. I’m still curious how these are being created as it would be better to fix at the source rather than in Slicer.
OK, so for instance, in the following case…
0028,0100] BitsAllocated 16 `
[0028,0101] BitsStored 15
[0028,0102] HighBit 14
[0028,0103] PixelRepresentation 1
[0028,0106] SmallestImagePixelValue 0
[0028,0107] LargestImagePixelValue 32766
[0028,1050] WindowCenter 8438.388323078
[0028,1051] WindowWidth 16876.776646156
[0028,1052] RescaleIntercept 0
[0028,1053] RescaleSlope 0.453101
I won't allow my module to run if this condition is present...
if ( BitsStored < 16 or HighBit < 15 or PixelRepresentation > 0)
Then Do Not Display
Also, what if the RescaleSlope were 1.0? Would that make a difference?
Also, does the DICOM standard indicate that the PixelRepresentation applies only to the pixel values before applying the RescaleSlope? I know the W/L is post.
Thanks
These images have been cleared for PHI. They can be made public. Thanks.
That might be possible to do as we create the DICOM files for the module but may cause too long of a delay in launching the module. We’ll consider that.
I wonder if the correct way to think about this is …
if (SmallestImagePixelValue > 0 and PixelRepresentation = 1) then bad DICOM.
They seem contradictory. What do you think?
Thanks
Interesting: Here is the display from Slicer version 4.5.0-1 running on a Mac:
So, at some point Slicer displayed it. Probably assumed high bit = 15 and Bits Stored 16.
With the help of someone more knowledgeable than I about our images, I learned that the corresponding images in long term storage are correct. This was changed at some point in the process of compression and decompression only for the purpose of displaying in our host app that creates DCMs and launches the Slicer module. I think I understand now what’s happening and I’ll keep you posted on my solution.
Thanks you so much!
I’ve checked the images and the problem is not with zeroing. The file stores values between 0-32767, which can be represented on 15 bits if unsigned. Disabling unused bit zeroing will not fix the issue, the numbers will be still negative.
Only the PixelRepresentation value is incorrect. If I edit the DICOM file to set the pixel representation to 0 then the image appears correctly:
@dougPorter there are two things you could do to help moving forward:
Ask on the ITK forum what could have changed in ITK between current version and about 2 years ago that changes the appearance of these images.
Check in your QREADS software how it decides to interpret voxel values as signed/unsigned.
We will find a way to fix this on our end.
Is there a way to change header elements in the Python script prior to displaying so that the change can take effect? Just curious. Not proposing as a solution, but just a general dev question.
Thanks
Yes, have a look at the DICOMPatcher module which does that kind of operation.