PET and MR display issues

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:

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

image

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!

1 Like

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:

  1. 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.

  2. 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.