Save Segmentation as DICOM file with Simple ITK and Python

I want to write the image an numpy array (with zeros and ones only) which is the result of the segmentation of a CT image.

How can I save it using sitk? I don’t know how to set some of the metadata as: high bit, bits allocated, bits stored, pixel representation…

Also, should I cast my image to what type? sitk.sitkUInt16?

Some code I have tried:

img = sitk.GetImageFromArray(np.asarray(array).astype(np.uint16))

img = sitk.Cast(img , sitk.sitkUInt16)

writer = sitk.ImageFileWriter()

img.SetDirection(original_volume.GetDirection())
img.SetOrigin(original_volume.GetOrigin())
img.SetSpacing(original_volume.GetSpacing())

writer.SetFileName(output_PATH)
writer.Execute(img)

Hello @riba,

Please see this SimpleITK example which does what you want.

Hi @zivy,

thanks for the answer.

However, some metadata are still not recorded, such as the spacing even when doing

img.SetSpacing(original_volume.GetSpacing())

or, for example,
img.SetMetaData('0028|0030', '2.5\2.5')

NOTE:
Opening the saved DICOM file in 3D slicer I can see all the metadata I defined, but ITK SNAP cannot read some metadata (like pixel spacing) and if I use the validator on All CIODs – DICOM Standard Browser it also says that some metadata tags are missing

Hello @riba,

Setting the meta-data explicitly (i.e. img.SetMetaData('0028|0030', '2.5\2.5')) is ignored. ITK/SimpleITK will use the spacing from the actual image. The SetSpacing should do what you want. It does work for the images I’ve worked with, so not sure what is going on with your code.

ITK-SNAP does read the pixel spacing, it just doesn’t display it under the “Metadata” tab of the image information. You will find it under the “Info” tab.

With respect to the complaints about missing tags, the example is generic and the documentation states that it is up to the developer to create the relevant tags and set them correctly, comment starting with “# IMPORTANT: There are many DICOM tags that need to be updated when you modify…”

Generally speaking, saving a segmentation this way is a “hack”. The official way is to use DICOM-SEG. If you want to go that route, I’d recommend looking into using highdicom or dcmqi.