Re: [pydicom] Need help creating dcm file from jpeg

2,359 views
Skip to first unread message

Jonathan Suever

unread,
May 11, 2012, 8:38:33 AM5/11/12
to pyd...@googlegroups.com
Juan,

So the main problem here is the creation of your pixel data. You are simply reading the JPEG file directly into the PixelArray field. The problem with this is that you are including the JPEG header along with the COMPRESSED image information. What you really want to do, is open the image file and then convert this to a string and assign it to ds.PixelData

You should replace this: 
ds1.PixelData = file(img_fname, "rb").read()
 
with:
img = Image.open(img_fname)
ds1.PixelData = img.tostring()

Now the problem with this is that pixel data is ordered incorrectly. It will display using PIL as a raw buffer since you used this to create it, but if you want to use a DICOM viewer, you're going to have to make some modifications

# Get the numpy array
arr = ds1.pixel_array
# Reshape it so the third dimension is RGB
arr = arr.reshape(arr.shape[1],arr.shape[2],arr.shape[0])
# Now transpose it back so that RGB becomes the first dimension (what DICOM viewers would expect)
arr = arr.transpose(1,2,0)
# Now reassign back to the image data
ds1.PixelData = arr.tostring()

There may be a more elegant way to go about this, but this should make your JPEG viewable in any dicom viewer

Hope this helps.

-Jonathan


On Thu, May 10, 2012 at 3:23 PM, Juan Jordá <ju...@jorda.org> wrote:
Hi all,

I am new to pydicom.

I am playing, trying to create a new dicom file wich contains the jpeg
image located at:
http://tindogdp.files.wordpress.com/2012/03/dv.jpg

I read old posts and and i rewrote some old code from there:

#PYTHON CODE

import os, sys, dicom
from PIL import Image

img_fname = "dv.jpg"
filename = r"vader.dcm"

ds = dicom.dataset.Dataset()
ds.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.7' # CT Image
Storage
ds.MediaStorageSOPInstanceUID = "1.2.3" # !! Need valid UID here for
real work
ds.ImplementationClassUID = "1.2.3.4" # !!! Need valid UIDs here

ds1 = dicom.dataset.FileDataset(filename, {}, file_meta=ds,
preamble="\0"*128)
ds1.PatientName = "Vader"
ds1.PatientId = "123456"
ds1.is_little_endian = True
ds1.is_implicit_VR = True
ds1.PixelData = file(img_fname, "rb").read()
ds1.PixelRepresentation = 0
ds1.BitsAllocated = 8
ds1.SamplesPerPixel = 3
ds1.NumberOfFrames = 1

img = Image.open(img_fname) #Open Image to get width and height
ds1.Columns = img.size[0] #img width
ds1.Rows = img.size[1] #img height

ds1.save_as(filename) #save DICOM data in file

ds = dicom.read_file(filename)
print ds

#option "FROMARRAY"
im = Image.fromarray(ds.pixel_array)

#option "FROMBUFFER"
#im = Image.frombuffer('RGB', img.size, ds.PixelData, 'raw', 'RGB', 0,
1)
im.show()

#END OF PYTHON CODE

When i run that, i got:

kat@ubuntu:~/dicom$ python creadicom.py
(0010, 0010) Patient's Name                      PN: 'Vader'
(0028, 0002) Samples per Pixel                   US: 3
(0028, 0008) Number of Frames                    IS: '1'
(0028, 0010) Rows                                US: 403
(0028, 0011) Columns                             US: 350
(0028, 0100) Bits Allocated                      US: 8
(0028, 0103) Pixel Representation                US: 0
(7fe0, 0010) Pixel Data                          OW or OB: Array of
22532 bytes
Traceback (most recent call last):
 File "creadicom.py", line 33, in <module>
   im = Image.fromarray(ds.pixel_array)
 File "/usr/local/lib/python2.6/dist-packages/dicom/dataset.py", line
405, in _get_pixel_array
   return self._getPixelArray()
 File "/usr/local/lib/python2.6/dist-packages/dicom/dataset.py", line
400, in _getPixelArray
   self._PixelArray = self._PixelDataNumpy()
 File "/usr/local/lib/python2.6/dist-packages/dicom/dataset.py", line
378, in _PixelDataNumpy
   arr = arr.reshape(self.SamplesPerPixel, self.Rows, self.Columns)
ValueError: total size of new array must be unchanged

If i comment option "FROMARRAY" and use option "FROMBUFFER" the
results are:

kat@ubuntu:~/dicom$ python creadicom.py
(0010, 0010) Patient's Name                      PN: 'Vader'
(0028, 0002) Samples per Pixel                   US: 3
(0028, 0008) Number of Frames                    IS: '1'
(0028, 0010) Rows                                US: 403
(0028, 0011) Columns                             US: 350
(0028, 0100) Bits Allocated                      US: 8
(0028, 0103) Pixel Representation                US: 0
(7fe0, 0010) Pixel Data                          OW or OB: Array of
22532 bytes
Traceback (most recent call last):
 File "creadicom.py", line 36, in <module>
   im = Image.frombuffer('RGB', img.size, ds.PixelData, 'raw', 'RGB',
0, 1)
 File "/usr/lib/python2.6/dist-packages/PIL/Image.py", line 1858, in
frombuffer
   return fromstring(mode, size, data, decoder_name, args)
 File "/usr/lib/python2.6/dist-packages/PIL/Image.py", line 1797, in
fromstring
   im.fromstring(data, decoder_name, args)
 File "/usr/lib/python2.6/dist-packages/PIL/Image.py", line 594, in
fromstring
   raise ValueError("not enough image data")
ValueError: not enough image data

I need some help.

I am using:
- Linux ubuntu 2.6.32-41-generic #88-Ubuntu SMP Thu Mar 29 13:08:43
UTC 2012 i686 GNU/Linux
- Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
- pydicom 0.9.7
- numpy 1.3.0
- PIL (Image.VERSION) 1.1.7

Thanks in advance

--
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 this group at http://groups.google.com/group/pydicom?hl=en.


Reply all
Reply to author
Forward
0 new messages