Home > Software design >  Error when converting DICOM image to pixel_array using tensorflow_io
Error when converting DICOM image to pixel_array using tensorflow_io

Time:01-31

I am trying to create a TensorFlow Dataset from DICOM images using the tf.data API and tensorflow_io, and I want to perform some pre-processing using Hounsfield units from the images. The DICOM images have a shape of (512,512). I have extracted the PixelData from the image and want to convert it to a numpy array of appropriate shape using the following code:

image_bytes = tf.io.read_file(image_path)
PixelData = tfio.image.decode_dicom_data(image_bytes, tfio.image.dicom_tags.PixelData).numpy()
pixel_array = np.frombuffer(PixelData, dtype=tf.uint16)
pixel_array = np.reshape(pixel_array, (512,512))
print(pixel_array)

This code should be equivalent to

Image = pydicom.dcmread(image_path)
pixel_array = Image.pixel_array
print(pixel_array)

and

Image = pydicom.dcmread(image_path)
PixelData = Image.PixelData
pixel_array = np.frombuffer(PixelData, dtype=np.uint16)
pixel_array = np.reshape(pixel_array, (512,512))
print(pixel_array)

The DICOM tags are the same ones used by pydicom, and are given here. The PixelData should return the raw byte values of the DICOM image. I have confirmed through pydicom that the raw pixel data is stored as np.uint16 values. However, when I try to convert the byte data given by tensorflow into a numpy array using the np.frombuffer function, I get an error of buffer size not being divisible by the element length.

When I run the above scripts, these are the following output shapes

  1. Tensorflow: Doesn't run with tf.uint16, gives output shape (1310719,) when using tf.uint8
  2. Pydicom direct pixel_array: Output shape of (512,512)
  3. Pydicom PixelData to pixel_array: Output shape of (512,512)

The pydicom examples provide identical outputs in both cases, however the tensorflow DICOM tag seems to provide a completely different result. Please find attached an example DICOM file here. Is there something wrong with the library or my implementation?

CodePudding user response:

The function tfio.image.decode_dicom_data decodes the tag information and not the pixel information.

To read the pixel data use tfio.image.decode_dicom_image instead.

import tensorflow_io as tfio

image_bytes = tf.io.read_file(image_path)
pixel_data = tfio.image.decode_dicom_image(
    image_bytes,
    dtype=tf.uint16)

# type conversion and reshaping is not required
# as can be checked with the print statement
print(pixel_data.dtype, pixel_data.shape)

# if required the pixel_data can be converted to a numpy array
# but calculations like scaling and offset correction can 
# be done on tensors as well
pixel_data_nparray = pixel_data.numpy()

# reading tag information, e.g. rescale intercept and slope
intersept = tfio.image.decode_dicom_data(
    image_bytes, 
    tfio.image.dicom_tags.RescaleIntercept)
slope = tfio.image.decode_dicom_data(
    image_bytes,
    tfio.image.dicom_tags.RescaleSlope)

print(intersept)
print(slope)

Please checkout the docs for further information:

  •  Tags:  
  • Related