I have an original DICOM file that has DICOM tags BitsAllocated (0028|0100)=16 and BitsStored (0028|0101)=12. I use SimpleITK to read this series, modify it and then I would like to save it again as a DICOM series using the same values for the two tags specified above. After modifying the dataset the data format is uint16.
This is the code I use:
writer = sitk.ImageFileWriter()
writer.KeepOriginalImageUIDOn()
# Copy relevant tags from the original meta-data dictionary (private tags are also accessible).
tags_to_copy = ["0010|0010", # Patient Name
"0010|0020", # Patient ID
"0010|0030", # Patient Birth Date
"0020|000D", # Study Instance UID, for machine consumption
"0020|0010", # Study ID, for human consumption
"0008|0020", # Study Date
"0008|0030", # Study Time
"0008|0050", # Accession Number
"0008|0060" # Modality
]
modification_time = time.strftime("%H%M%S")
modification_date = time.strftime("%Y%m%d")
# Copy some of the tags and add the relevant tags indicating the change.
# For the series instance UID (0020|000e), each of the components is a number, cannot start
# with zero, and separated by a '.' We create a unique series ID using the date and time.
# tags of interest:
direction = sitk_stack.GetDirection()
series_tag_values = [(k, rs.GetMetaData(0, k)) for k in tags_to_copy if rs.HasMetaDataKey(0, k)] + \
[("0008|0031", modification_time), # Series Time
("0008|0021", modification_date), # Series Date
("0008|0008", "DERIVED\\SECONDARY"), # Image Type
("0020|000e", "1.2.826.0.1.3680043.2.1125." + modification_date + ".1" + modification_time), # Series Instance UID
("0020|0037", '\\'.join(map(str, (direction[0], direction[3], direction[6], # Image Orientation (Patient)
direction[1], direction[4], direction[7])))),
("0008|103e", rs.GetMetaData(0, "0008|103e") + " Processed-SimpleITK"),
("0028|0101", '12'), # gray values window
("0028|0102", '11'), # gray values window
("0028|0100", '16'),
('0028|0103', '0'), ]
for i in range(sitk_stack.GetDepth()):
image_slice = sitk_stack[:, :, i]
# Tags shared by the series.
for tag, value in series_tag_values:
image_slice.SetMetaData(tag, value)
# Slice specific tags.
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, sitk_stack.TransformIndexToPhysicalPoint((0, 0, i))))) # Image Position (Patient)
image_slice.SetMetaData("0020,0013", str(i)) # Instance Number
# Write to the output directory and add the extension dcm, to force writing in DICOM format.
writer.SetFileName(os.path.join(output_dir, str(i) + '.dcm'))
writer.Execute(image_slice)
'''
When I look at the images afterwards using MeVisLab, I notice that the BitsAlocated and BitsStored are both 16 rather than 16 and 12. What am I doing wrong? Is it possible to store the images using only 12 bits?
SimpleITK doesn't support 12-bit pixels, so it cannot write them. Because of that, when a 12-bit pixel image is read, it automatically gets converted to 16-bit.
I don't know of python DICOM packages that support writing of 12-bit pixel images. SimpleITK uses GDCM or DCMTK for DICOM I/O. If you use those libraries directly, you might be able to do it, although I don't know. But via SimpleITK you can't.