reading and writng a dicom image

Hi,

In the following simple piece of code I’m trying to read a DICOM image as sitkImage and its tags as a python dictionary. then I call another function to write that image in another location with the same tags reading from the dictionary.

yet the output dicom folder is shown as 180 separate slices in the output folder (when I open the folder with a DICOM viewer) and not as a single multi slice image.

here’s the code:

    import SimpleITK as sitk
    import sys, os, json, time

    dicom_directory = "D:\\0-image_orig"
    output_directory = "D:\\1-image_copy"
    #reads DICOM, returns dicom tags and image3D
    def read_dicom_tags(dicom_dir):
        series_IDs = sitk.ImageSeriesReader.GetGDCMSeriesIDs(dicom_dir)
        series_file_names = sitk.ImageSeriesReader.GetGDCMSeriesFileNames(
            dicom_dir, series_IDs[0])

        series_reader = sitk.ImageSeriesReader()
        series_reader.SetFileNames(series_file_names)

        series_reader.MetaDataDictionaryArrayUpdateOn()
        series_reader.LoadPrivateTagsOn()
        image = series_reader.Execute()

        tags_dict = {}
        for j, key in enumerate(series_reader.GetMetaDataKeys(1)):
            if(key != "ITK_non_uniform_sampling_deviation"):
                tags_dict[key] = series_reader.GetMetaData(0, key)

        dicom_tags_file_address = os.path.join(dicom_dir, '../', dicom_dir.split('\\')[-1]+'_tags.json')
        with open(os.path.join(dicom_dir, '../', dicom_dir.split('\\')[-1]+'_tags.json'), 'w') as f:
            json.dump(tags_dict, f)
        return dicom_tags_file_address, tags_dict, image

    #writes image3D with the dicom tags
    def write_dicom_image_with_tags(image, dicom_tags, output_dir):
        for i in range(image.GetDepth()):
            writer = sitk.ImageFileWriter()
            writer.KeepOriginalImageUIDOn()
            image_slice = image[:, :, i]
            # Tags shared by the series.
            for j, key in enumerate(dicom_tags):
                image_slice.SetMetaData(key, dicom_tags[key])
            # Write to the output directory and add the extension dcm, to force writing in DICOM format.
            image_slice.SetMetaData("0008|0012", time.strftime("%Y%m%d")) # Instance Creation Date
            image_slice.SetMetaData("0008|0013", time.strftime("%H%M%S")) # Instance Creation Time
            image_slice.SetMetaData("0020|0032", '\\'.join(map(str,image3D.TransformIndexToPhysicalPoint((0,0,i))))) # Image Position (Patient)
            image_slice.SetMetaData("0020,0013", str(i)) # Instance Number
            writer.SetFileName(os.path.join(output_dir, str(i) + '.dcm'))
            writer.Execute(image_slice)

    tagsFile, tagsDict, image3D = read_dicom_tags(dicom_directory)
    write_dicom_image_with_tags(image3D, tagsDict, output_directory)

any thoughts on what am I missing in here?
Thanks in advance

Hello @sarbabi,

In your write_dicom_image_with_tags function the study instance UID (0020|000D) and series instance UID (0020|000E) are set independently for each of the written images. I don’t think they exist in your dicom_tags parameter.

If you want to add this processed volume into the existing study, just take the study UID from the original data and create a new series instance UID (see example). Otherwise create study and series UIDs and pass those as part of the dicom_tags parameter.

2 Likes

Hi @zivy ,

Thank you, in the example you mentioned I’m just changing the directory address for original and output image and get this error:

Traceback (most recent call last):
  File "example.py", line 111, in <module>
    writer.Execute(image_slice)
  File "Python39\lib\site-packages\simpleitk-2.0.0rc2.dev908+g8244e-py3.9-win-amd64.egg\SimpleITK\SimpleITK.py", line 8172, in Execute
    return _SimpleITK.ImageFileWriter_Execute(self, *args)
RuntimeError: Exception thrown in SimpleITK ImageFileWriter_Execute: \SimpleElastix\ITK\Modules\IO\GDCM\src\itkGDCMImageIO.cxx:1154:
itk::ERROR: GDCMImageIO(0000021536F5E630): A Floating point buffer was passed but the stored pixel type was not specified.This is currently not supported

then I do a casting like:

castFilter = sitk.CastImageFilter()
castFilter.SetOutputPixelType(sitk.sitkInt16)

# Convert floating type image (imgSmooth) to int type (imgFiltered)
filtered_image2 = castFilter.Execute(filtered_image)

and this time it writes the image but the slices are still separated in DICOM viewer and not a single multi-slice image.

So I saved this example in example.py, then ran this in command line:

$ python example.py “source” “destination”

and I get the same error:

Traceback (most recent call last):
  File "example.py", line 111, in <module>
    writer.Execute(image_slice)
  File "Python39\lib\site-packages\simpleitk-2.0.0rc2.dev908+g8244e-py3.9-win-amd64.egg\SimpleITK\SimpleITK.py", line 8172, in Execute
    return _SimpleITK.ImageFileWriter_Execute(self, *args)
RuntimeError: Exception thrown in SimpleITK ImageFileWriter_Execute: \SimpleElastix\ITK\Modules\IO\GDCM\src\itkGDCMImageIO.cxx:1154:
itk::ERROR: GDCMImageIO(0000021536F5E630): A Floating point buffer was passed but the stored pixel type was not specified.This is currently not supported

Is it like the example lacks something or am I missing something?

Hello @sarbabi,

From the error message it appears you aren’t actually working directly with SimpleITK. You appear to be working with SimpleElastix that took SimpleITK and added components to it. Also appears to be referring to SimpleITK release candidate 2 for the SimpleITK release 2.0.0.

I would recommend installing SimpleITK directly and working with that (the example does work with the official SimpleITK releases).

1 Like

Thank you @zivy,
actually I’m trying to save the result of a SimpleElastix registration task as a DICOM image.
So knowing what you just mentioned, how would suggest to do that?

Hello @sarbabi,

You should post the issue on the SimpleElastix GitHub issues as it should work the way the example I pointed you to works. In the official SimpleITK releases this code is just fine.

A hack workaround:

  1. Create another virtual environment with the official SimpleITK (not SimpleElastix calling itself SimpleITK).
  2. Run the registration using your SimpleElastix environment and write the result of the registration transform using an ITK supported format.
  3. Switch to the SimpleITK virtual environment, read the transform, read the images, resample and write the output as a DICOM series.
1 Like