Pydicom: Error with exception when reading a file

Created on 20 Mar 2017  路  14Comments  路  Source: pydicom/pydicom

I haven't tracked down what is wrong with the file I am trying to read, but this has highlighted a bug in one of the exceptions (assuming that e.message exists):

In [1]: import pydicom

In [2]: d = pydicom.read_file('image-000001.dcm')

In [3]: d.pixel_array
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
/Users/tom/miniconda3/envs/dev/lib/python3.6/site-packages/pydicom/dataset.py in _get_PIL_supported_compressed_pixeldata(self)
    654                     fio = io.BytesIO(UncompressedPixelData)
--> 655                     decompressed_image = PILImg.open(fio)
    656                 except IOError as e:

/Users/tom/miniconda3/envs/dev/lib/python3.6/site-packages/PIL/Image.py in open(fp, mode)
   2348     raise IOError("cannot identify image file %r"
-> 2349                   % (filename if filename else fp))
   2350 

OSError: cannot identify image file <_io.BytesIO object at 0x10ac61ca8>

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
/Users/tom/miniconda3/envs/dev/lib/python3.6/site-packages/pydicom/dataset.py in pixel_array(self)
    708         try:
--> 709             return self._get_pixel_array()
    710         except AttributeError:

/Users/tom/miniconda3/envs/dev/lib/python3.6/site-packages/pydicom/dataset.py in _get_pixel_array(self)
    694                 # print("Pixel Data is compressed")
--> 695                 self._pixel_array = self._compressed_pixel_data_numpy()
    696                 self._pixel_id = id(self.PixelData)  # is this guaranteed to work if memory is re-used??

/Users/tom/miniconda3/envs/dev/lib/python3.6/site-packages/pydicom/dataset.py in _compressed_pixel_data_numpy(self)
    582         if self.file_meta.TransferSyntaxUID in pydicom.uid.PILSupportedCompressedPixelTransferSyntaxes:
--> 583             UncompressedPixelData = self._get_PIL_supported_compressed_pixeldata()
    584         elif self.file_meta.TransferSyntaxUID in pydicom.uid.JPEGLSSupportedCompressedPixelTransferSyntaxes:

/Users/tom/miniconda3/envs/dev/lib/python3.6/site-packages/pydicom/dataset.py in _get_PIL_supported_compressed_pixeldata(self)
    656                 except IOError as e:
--> 657                     raise NotImplementedError(e.message)
    658                 UncompressedPixelData = decompressed_image.tobytes()

AttributeError: 'OSError' object has no attribute 'message'

During handling of the above exception, another exception occurred:

PropertyError                             Traceback (most recent call last)
<ipython-input-3-56ab90a1fe8a> in <module>()
----> 1 d.pixel_array

/Users/tom/miniconda3/envs/dev/lib/python3.6/site-packages/pydicom/dataset.py in pixel_array(self)
    712             val = PropertyError("AttributeError in pixel_array property: " +
    713                                 e.args[0])
--> 714             compat.reraise(PropertyError, val, tb)
    715 
    716     # Format strings spec'd according to python string formatting options

/Users/tom/miniconda3/envs/dev/lib/python3.6/site-packages/pydicom/compat.py in reraise(tp, value, tb)
     29 else:
     30     def reraise(tp, value, tb):
---> 31         raise value.with_traceback(tb)

/Users/tom/miniconda3/envs/dev/lib/python3.6/site-packages/pydicom/dataset.py in pixel_array(self)
    707         """Return the pixel data as a NumPy array"""
    708         try:
--> 709             return self._get_pixel_array()
    710         except AttributeError:
    711             t, e, tb = sys.exc_info()

/Users/tom/miniconda3/envs/dev/lib/python3.6/site-packages/pydicom/dataset.py in _get_pixel_array(self)
    693             try:
    694                 # print("Pixel Data is compressed")
--> 695                 self._pixel_array = self._compressed_pixel_data_numpy()
    696                 self._pixel_id = id(self.PixelData)  # is this guaranteed to work if memory is re-used??
    697                 return self._pixel_array

/Users/tom/miniconda3/envs/dev/lib/python3.6/site-packages/pydicom/dataset.py in _compressed_pixel_data_numpy(self)
    581                             self.BitsAllocated))
    582         if self.file_meta.TransferSyntaxUID in pydicom.uid.PILSupportedCompressedPixelTransferSyntaxes:
--> 583             UncompressedPixelData = self._get_PIL_supported_compressed_pixeldata()
    584         elif self.file_meta.TransferSyntaxUID in pydicom.uid.JPEGLSSupportedCompressedPixelTransferSyntaxes:
    585             UncompressedPixelData = self._get_jpeg_ls_supported_compressed_pixeldata()

/Users/tom/miniconda3/envs/dev/lib/python3.6/site-packages/pydicom/dataset.py in _get_PIL_supported_compressed_pixeldata(self)
    655                     decompressed_image = PILImg.open(fio)
    656                 except IOError as e:
--> 657                     raise NotImplementedError(e.message)
    658                 UncompressedPixelData = decompressed_image.tobytes()
    659         except:

PropertyError: AttributeError in pixel_array property: 'OSError' object has no attribute 'message'

Most helpful comment

Same error here! :'(

Happens on:
python 2.7 and 3.6.5
pillow-5.3.0
pydicom-1.2.1 and 1.2.0
Windows 10 and Ubuntu 16.04

Update: FIXED! 馃帀

UPDATE for Python 2.7: I fixed the error after downgrading pydicom and installing an extra dependency, gdcm which when present will be used instead of Pillow. Not sure if this is the most precise fix, but it works for me on Ubuntu 16.04 with Python 2.7 only.

pip uninstall pydicom
pip install pydicom==1.1.0
sudo apt-get install python-gdcm

UPDATE for Python 3.7: To work around this Pillow error on python3 and use gdcm you can follow these instructions for Ubuntu 16.04 and Python 3.7.

sudo apt-get install python3.7-dev libpython3.7-dev virtualenv
sudo apt-get install python3-tk # for matplotlib
sudo apt-get install python-gdcm # for pydicom
virtualenv -p python3.7 python3.7venv
cd python3.7venv/
. bin/activate
pip3.7 install numpy pydicom
git clone --branch master https://github.com/HealthplusAI/python3-gdcm.git && cd python3-gdcm && dpkg -i build_1-1_amd64.deb && apt-get install -f
cp /usr/local/lib/gdcm.py ./lib/python3.7/site-packages/
cp /usr/local/lib/gdcmswig.py ./lib/python3.7/site-packages/
cp /usr/local/lib/_gdcmswig.so ./lib/python3.7/site-packages/
cp /usr/local/lib/libgdcm* ./lib/python3.7/site-packages/
ldconfig

Quick test that everything works:

import pydicom
from matplotlib import pyplot as plt
filename = "94862596.dcm"
ds = pydicom.dcmread(filename)
data = ds.pixel_array
plt.imshow(data, cmap='gray')
plt.show()

All 14 comments

Could you upload an anonymised version of the file you're using somewhere? I've been working on the testing for that section of the code and it would be helpful.

I tried to read the files from here: http://www.dicomlibrary.com/?manage=02ef8f31ea86a45cfce6eb297c274598 (click 'download' under 'Download Anonymized DICOM Study')

I am pretty sure this is python 3 vs python 2. Python 2's BaseException defines a message, but it has been deprecated since 2.6. The "str" conversion is prefered in py 3. However, py2 still has the str/unicode issue, so the best I could come up with in 15 minutes of looking was:

                    try:
                        message = str(e)
                    except:
                        try:
                            message = unicode(e)
                        except:
                            message = ''
                    raise NotImplementedError(message)

I'm using Python 3.6, so that makes sense

I'm not having any issues with Dataset.pixel_array for any of the image-000001.dcm files in that study. Could you post the version info for pydicom and pillow?

I'm using pydicom 1.0.0a1 (999254e), pillow 4.0.0, python 2.7/3.5.

Your pillow probably has jpeg lossless support (OpenJPEG 2.x libraries). It isn't really that common on most platforms. If you remove the OpenJPEG libraries and reinstall Pillow, you can likely reproduce this. The issue is described in pep-0352 and also mentioned in deprecationwarning-baseexception-message-has-been-deprecated-as-of-python-2-6

@rhaxton - didn't you fix this already?

@mrbean-bremen Yes, this has been fixed. Though I wish I had something better than what I did (try..except, try..except)

In this specific case (IOError) there is indeed a better solution - this has been changed by @cancan101 in #401.

@mrbean-bremen Aha, I see that now. IOError.strerror prints a shortened version of the error message without the filename (which might be unicode), but there isn't any filename in this case anyway. Also, str(IOError) returns a mangled version of a unicode filename suitable for printing in all cases.

I have the same error with pillow 5.1.0, python 3.6, pydicom 1.2.1, and the exact same DICOM file as

I tried to read the files from here: http://www.dicomlibrary.com/?manage=02ef8f31ea86a45cfce6eb297c274598 (click 'download' under 'Download Anonymized DICOM Study')

What should I do? Did I miss some support libraries? Did you solved it? @astrofrog

Same error here! :'(

Happens on:
python 2.7 and 3.6.5
pillow-5.3.0
pydicom-1.2.1 and 1.2.0
Windows 10 and Ubuntu 16.04

Update: FIXED! 馃帀

UPDATE for Python 2.7: I fixed the error after downgrading pydicom and installing an extra dependency, gdcm which when present will be used instead of Pillow. Not sure if this is the most precise fix, but it works for me on Ubuntu 16.04 with Python 2.7 only.

pip uninstall pydicom
pip install pydicom==1.1.0
sudo apt-get install python-gdcm

UPDATE for Python 3.7: To work around this Pillow error on python3 and use gdcm you can follow these instructions for Ubuntu 16.04 and Python 3.7.

sudo apt-get install python3.7-dev libpython3.7-dev virtualenv
sudo apt-get install python3-tk # for matplotlib
sudo apt-get install python-gdcm # for pydicom
virtualenv -p python3.7 python3.7venv
cd python3.7venv/
. bin/activate
pip3.7 install numpy pydicom
git clone --branch master https://github.com/HealthplusAI/python3-gdcm.git && cd python3-gdcm && dpkg -i build_1-1_amd64.deb && apt-get install -f
cp /usr/local/lib/gdcm.py ./lib/python3.7/site-packages/
cp /usr/local/lib/gdcmswig.py ./lib/python3.7/site-packages/
cp /usr/local/lib/_gdcmswig.so ./lib/python3.7/site-packages/
cp /usr/local/lib/libgdcm* ./lib/python3.7/site-packages/
ldconfig

Quick test that everything works:

import pydicom
from matplotlib import pyplot as plt
filename = "94862596.dcm"
ds = pydicom.dcmread(filename)
data = ds.pixel_array
plt.imshow(data, cmap='gray')
plt.show()

python-gdcm

Thanks. How do we do the same thing for Windows10?

Best use MiniConda under Windows to install gdcm (see also here).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

T4mmi picture T4mmi  路  9Comments

anxingle picture anxingle  路  4Comments

wanghaisheng picture wanghaisheng  路  8Comments

vsoch picture vsoch  路  9Comments

amandagb picture amandagb  路  8Comments