dcmqi: PixelData is encoded incorrectly when frame size is not divisible by 8
This issue was discovered while adding corresponding test dataset in #334.
Frame pixel data is initialized in dcmqi here: https://github.com/QIICR/dcmqi/blob/master/libsrc/ImageSEGConverter.cpp#L320-L328.
The frames are then concatenated to form SEG object PixelData
in DcmSegmentation::concatFrames
here: https://github.com/commontk/DCMTK/blob/patched-DCMTK-3.6.3_20180205/dcmseg/libsrc/segdoc.cc#L1314.
It appears that something is not quite right with the concatenation. The issue of incorrect pixel data encoding can be easily reproduced with the python code below (this code works with Python 3 and the only extra dependency is pydicom) and this sample dataset from #334.
import pydicom, sys
d = pydicom.read_file(sys.argv[1])
print(d.Rows)
print(d.Columns)
print(d.NumberOfFrames)
print(d.PixelData)
totalPixels = int(d.Rows*d.Columns*d.NumberOfFrames/8)
if totalPixels%8:
totalPixels = totalPixels + 1
totalPixels = totalPixels + (totalPixels % 2)
print("Total pixels expected: %i" % totalPixels)
print("Total pixels actual: %i" % len(d.PixelData))
for f in range(d.NumberOfFrames):
print("Frame %i" % f)
for i in range(d.Rows):
for j in range(d.Columns):
pixelNumber = f*d.Rows*d.Columns+i*d.Columns+j
byteNumber = int(pixelNumber/8)
bitPosition = pixelNumber % 8
value = (d.PixelData[byteNumber] >> bitPosition) & 1
sys.stdout.write(str(value))
print("")
The output of the code above appears to be identical to the image generated with dcm2pnm
, as shown in https://github.com/QIICR/dcmqi/pull/334#issuecomment-370449995.
Relevant part of the DICOM standard detailing how bits should be packed in multiframe is in PS3.5 8.1.1 Pixel Data Encoding of Related Data Elements. The most important part is there should be no gap/padding between the encoded consecutive frames, and DCMTK implementation is expected to follow that rule, based on earlier communication and debugging.
@michaelonken I have not yet identified the specific problem in the DCMTK concatenation function, but it looks like that is the culprit. I will look into this later next week, but I need to work on something else now and decided to create the issue with the details, in case you want to investigate.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 47 (36 by maintainers)
Commits related to this issue
- BUG: fix handling of bit-packed PixelData This commit aims to fix the functionality originally introduced in #293: * bits were unpacked from the left, which was incorrect, see discussion in https://... — committed to QIICR/pydicom by fedorov 6 years ago
- Fix handling of bit-packed PixelData This commit aims to fix the functionality originally introduced in #293: * bits were unpacked from the left, which was incorrect, see discussion in https://githu... — committed to QIICR/pydicom by fedorov 6 years ago
- Fix handling of bit-packed PixelData This commit aims to fix the functionality originally introduced in #293: * bits were unpacked from the left, which was incorrect, see discussion in https://githu... — committed to QIICR/pydicom by fedorov 6 years ago
- Fix handling of bit-packed PixelData This commit aims to fix the functionality originally introduced in #293: * bits were unpacked from the left, which was incorrect, see discussion in https://githu... — committed to QIICR/pydicom by fedorov 6 years ago
- Fix handling of bit-packed PixelData This commit aims to fix the functionality originally introduced in #293: * bits were unpacked from the left, which was incorrect, see discussion in https://githu... — committed to QIICR/pydicom by fedorov 6 years ago
- BUG: Update DCMTK to fix output of DICOM Segmentation objects This commit includes an important bug fix that prevented output for DICOM Segmentation objects with the number of pixels in the frame not... — committed to Slicer/SlicerGitSVNArchive by jcfr 6 years ago
- ENH: update DCMTK to 3.6.6 patched for seg See https://github.com/QIICR/dcmqi/issues/341#issuecomment-778253753 — committed to fedorov/dcmqi by fedorov 3 years ago
- ENH: update DCMTK to version 3.6.6 re #5510 and https://github.com/QIICR/dcmqi/issues/341#issuecomment-707053566 Update to official 3.6.6 release plus an extra backported patch: https://git.dcmtk.o... — committed to fedorov/Slicer by fedorov 3 years ago
- ENH: update DCMTK to version 3.6.6 re #5510 and https://github.com/QIICR/dcmqi/issues/341#issuecomment-707053566 Update to official 3.6.6 release plus an extra backported patch: https://git.dcmtk.o... — committed to Slicer/Slicer by fedorov 3 years ago
- [backport] ENH: update DCMTK to version 3.6.6 re #5510 and https://github.com/QIICR/dcmqi/issues/341#issuecomment-707053566 Update to official 3.6.6 release plus an extra backported patch: https://... — committed to KitwareMedical/Slicer by fedorov 3 years ago
I had time to look at this recently and I agree with you: https://github.com/DCMTK/dcmtk/blob/master/dcmseg/libsrc/segdoc.cc#L1213 is where it happens.
It should read
remainder = bytesRequired % 8;
instead since bytesRequired takes into account the number of pixels not for a single frame (old buggy code) but for all frames.
Did you already check whether this does the trick for the files you have at hand, @hmeine?
I will look into this. Right now I have no time so it can take a few days…thanks for spending time to isolate this, Hans.
I just wanted to give information which I believe is related to this issue: In MeVisLab, we originally exported SEG files without padding. Then, we got back such files as “invalid” from an important customer who claimed that
rows“something”frames had to be padded to multiples of816 bits, and we could not find information in an older DICOM standard version that prohibited that. Nowadays, the standard explicitly states that applications shall be prepared to support padded frames since this was not forbidden in older standard versions (Part 5, 8.1.1).We now have example files without padding (which seem to be the recommended encoding by today’s standard) that make dcmqi crash, apparently because of an “Invalid Tag” error from dcmtk.
yes I recently pushed that into DCMTK master. I am having a report on the same issue from another party, and I am about to check whether matches this one (I think it does), that is why I did not update this thread so far. However, the patch is ok and tested, so the report may be unrelated (or deals with the same problem).
@hmeine OK, should I open one?
No, and I do not have my own dcmtk build at hand right now. If you could compile dcmqi against a patched dcmtk, however, you could test running
segimage2itkimage
on the file I attached above: https://github.com/QIICR/dcmqi/files/5458825/Lesions1.dcm.zipI think there is an issue in DCMTK, and this line should also multiply by the number of frames: https://github.com/DCMTK/dcmtk/blob/master/dcmseg/libsrc/segdoc.cc#L1213.
Attached you find a Lesions1.dcm, zipped for GitHub which contains the described mask. The file is pseudonymized and only contains a lesion mask, so I got permission to share it with you.
Thanks to @michaelonken DCMTK has now been updated with the fix.
On Mon, Jun 11, 2018 at 1:01 AM, Michael Onken wrote: