Re: Viewing compressed images in DICOM files

2,066 views
Skip to first unread message

Darcy Mason

unread,
Jan 23, 2013, 8:40:02 AM1/23/13
to pyd...@googlegroups.com
I was just composing some notes for a pydicom roadmap document yesterday ... and the decompression issue was on that list. It has also been on the issues list for a long time (issue 16: https://code.google.com/p/pydicom/issues/detail?id=16). Unfortunately, it is not an easy one to solve and other priorities have always been higher.

Short answer: there isn't a simple way to do what you want. The usual advice is to convert through e.g. dcmtk (there is a command-line program which will do it) and then read the uncompressed file in pydicom. Of course, just to view, you could use any of the many DICOM viewer programs out there.

Out of curiosity, which kind of compression is your file? Look at ds.file_meta and the Transfer Syntax UID. I'd be interested to hear which compression formats people most commonly encounter.

-Darcy


On Wednesday, January 23, 2013 4:46:02 AM UTC-5, Luca Matteis wrote:
Hello pydicom community! I am having issues with viewing the images inside DICOM files that contain compressed images. I constantly get "Pixel Data is compressed in a format pydicom does not yet handle. Cannot return array". After reading this page http://code.google.com/p/pydicom/wiki/WorkingWithPixelData it seems I can get the raw bytes inside .PixelData. But when I try and save this to a file (the raw bytes), and open it using a standard image viewing program (like GIMP), I can't view the image.

Is there a way to simply read the compressed image file? If so, how can I do it?
Thanks.

Luca Matteis

unread,
Jan 24, 2013, 9:56:11 AM1/24/13
to pyd...@googlegroups.com
Darcy, thanks for the answer. Actually I am just trying to view the compressed image. So if the DICOM file contains a JPEG, I should still be able to read it with any JPEG viewer, using the raw .PixelData data, right? Or am I missing something?

Most of the DICOM files I'm testing are the ones I find online, and they rarely work with pydicom (I can rarely display an image without some sort of error showing up). Here's a few I'm testing:


Any advice how I can get to view these with pydicom? Can't use dcmtk as I'm testing my app using only native python code. I simply don't understand how I cannot open a compressed JPEG data file extracted using pydicom, and why I would need a tool such as dcmtk.

Thanks,
Luca

Jonathan Suever

unread,
Jan 24, 2013, 11:10:03 AM1/24/13
to pyd...@googlegroups.com
Luca, 

The compressed data is a little more complicated than that. It may work the way that you want in a very simple case but I'm not sure.

Sometimes, the pixel data is encapsulated. This means that the image data is essentially broken into chunks of data and stored as essentially a SQ. Depending on whether the image is a multi-frame image or a single image, the data in these groups should be concatenated to makeup the entire raw data or each chunk represents each individual slice. If they represent different images, then each one is compressed separately. So simply writing the PixelData value to a file will rarely (never in my experience) result in a viewable jpeg.

I guess some more work could be done in pydicom to parse out this data and provide raw jpeg streams to the user but the actual decompression of pixel data remains a bigger issue.

-Jonathan


--
You received this message because you are subscribed to the Google Groups "pydicom" group.
To post to this group, send email to pyd...@googlegroups.com.
To unsubscribe from this group, send email to pydicom+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Luca Matteis

unread,
Jan 24, 2013, 12:24:42 PM1/24/13
to pyd...@googlegroups.com
I see. Well could any of this be achieved with PIL only? I am using it with App Engine and would love to keep it Python standard only. I could wet my hands with it and try to make it work with the DICOM files I listed earlier that don't work. But have no clue about images and compression algorithms in general.

Jonathan Suever

unread,
Jan 24, 2013, 1:01:41 PM1/24/13
to pyd...@googlegroups.com
PIL does support JPEG decompression; however, it requires the user to install libjpeg (a C library) first. The goal of pydicom is to also remain pure python which is why this route hasn't been used.

-Jonathan

Darcy Mason

unread,
Jan 24, 2013, 1:47:03 PM1/24/13
to pyd...@googlegroups.com
I agree with everything Jonathan said, and I will add that all the usual image routes are trickier with DICOM, in part due to the encapsulation Jonathan mentioned, but also because images are often 12 bit and lossless, neither of which (in the past at least) were handled well by any standard image libraries, or jpeg viewers for that matter. Actually the lossless jpeg is not really even jpeg compressed in the usual way, it is a "predictor"-based compression, i.e. each pixel just stores the difference from the previous one.

If you read through issue 16, you'll see that I did once get 8-bit lossy to work with PIL, but that was years ago and I'm sure I would not find the code now. Actually, I just remembered -- part of it does exist -- it is in the encaps.py file in the pydicom source. It handles turning the fragments into a single string of bytes. So we do have that piece. I think I was then able to pass that to PIL (but just for an 8-bit lossy jpeg image as I mentioned; I didn't get 12-bit to work).

Luca, if you do play around with that and get something working, please let us know.  My latest thoughts for anything other than 8-bit lossy were to try to model the code in dcmtk, which (IIRC) uses an extended version of the IJG code.

-Darcy

Alex Rothberg

unread,
Jul 2, 2014, 7:59:33 PM7/2/14
to pyd...@googlegroups.com
Darcy, a few questions:

1) How do you use dcmtk for compressed filed?
2) It looks like defragment_data is complaing:

dicom.encaps.defragment_data(data.PixelData)
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-134-af3c0e258b2f> in <module>()
----> 1 dicom.encaps.defragment_data(data.PixelData)

/usr/local/lib/python2.7/site-packages/dicom/encaps.pyc in defragment_data(data)
     35     fp = DicomBytesIO(data)
     36     fp.is_little_endian = True  # DICOM standard requires this
---> 37     BasicOffsetTable = read_item(fp)
     38     seq = []
     39     while True:

/usr/local/lib/python2.7/site-packages/dicom/encaps.pyc in read_item(fp)
     51     """Read and return a single Item in the fragmented data stream"""
     52     try:
---> 53         tag = fp.read_tag()
     54     except EOFError:  # already read delimiter before passing data here, so should just run out
     55         return None

/usr/local/lib/python2.7/site-packages/dicom/filebase.pyc in read_le_tag(self)
     32         if len(bytes_read) < 4:
     33             raise EOFError  # needed for reading "next" tag when at end of file
---> 34         return unpack(bytes_read, b"<HH")
     35 
     36     def read_be_tag(self):

error: unpack requires a string argument of length 0

3) There is a comment in defrag about multi-frame files: "If PixelData has multiple frames, then should separate out before calling this routine." What is the best way to go about doing that? Is there a method somewhere?

Alex Rothberg

unread,
Jul 3, 2014, 9:46:35 AM7/3/14
to pyd...@googlegroups.com
I answered 1) myself, use: dcmdjpeg
Reply all
Reply to author
Forward
0 new messages