-
Notifications
You must be signed in to change notification settings - Fork 64
Open
Description
I am trying to convert a multilayer NIFTI file to a DICOM SEG file using the itkimage2segimage tool from dcmqi. After conversion the output DICOM SEG file contains two times the actual number of frames.
For example:
If input NIFTI has 203 frames and 2 labels segmentations (e.g., Liver, Spleen).
My multilayer output Dicom SEG file contains 2 × 203 = 406 frames, with each set of 203 frames corresponding to a single label. however the expected multilayer output DICOM SEG file should contains 203 frames only, where each frame contains the combined segmentation for both labels.
Here is the Python code I used to perform the conversion:
import nibabel as nib # To validate NIfTI labels
import subprocess
import os
import pydicom
import json
def get_unique_labels_from_nifti(nifti_file):
"""
Extracts unique labels from the NIfTI file.
Args:
nifti_file (str): Path to the NIfTI file.
Returns:
list: Sorted unique labels (intensity values) in the NIfTI file.
"""
nifti_data = nib.load(nifti_file).get_fdata()
unique_labels = sorted(set(nifti_data.flatten()))
return [int(label) for label in unique_labels if label > 0] # Exclude background (0)
def convert_nifti_to_dcm_seg(nifti_file, dicom_dir, output_seg_file):
"""
Converts a NIfTI segmentation file to DICOM SEG using itkimage2segimage.
Args:
nifti_file (str): Path to the input NIfTI file.
dicom_dir (str): Directory containing the DICOM files.
output_seg_file (str): Path to save the output DICOM SEG file.
"""
# Ensure output directory exists
os.makedirs(os.path.dirname(output_seg_file), exist_ok=True)
# Extract the StudyInstanceUID from one of the DICOM files in the directory
dicom_file = os.path.join(dicom_dir, os.listdir(dicom_dir)[0])
study_instance_uid = pydicom.dcmread(dicom_file).StudyInstanceUID
# Validate the labels in the NIfTI file
labels_in_nifti = get_unique_labels_from_nifti(nifti_file)
print(f"Unique labels in NIfTI file: {labels_in_nifti}")
# Generate segment attributes for each class
segment_attributes = []
# Example descriptions for each label
descriptions = {
labels_in_nifti[0]: "Liver",
labels_in_nifti[1]: "Spleen"
}
for i, label in enumerate(labels_in_nifti):
segment_attributes.append({
"SegmentNumber": i+1,
"labelID": label,
"SegmentDescription": descriptions.get(label, "Unknown"),
"SegmentAlgorithmType": "AUTOMATIC",
"SegmentAlgorithmName": "TotalSegmentator",
"SegmentedPropertyCategoryCodeSequence": {
"CodeValue": "T-D0050" if label == labels_in_nifti[0] else "T-62000",
"CodingSchemeDesignator": "SCT",
"CodeMeaning": "Anatomical Structure"
},
"SegmentedPropertyTypeCodeSequence": {
"CodeValue": "10200004" if label == labels_in_nifti[0] else "10200005",
"CodingSchemeDesignator": "SCT",
"CodeMeaning": descriptions.get(label, "Unknown")
}
})
# Construct metadata
metadata = {
"ContentCreatorName": "Reader1",
"ClinicalTrialSeriesID": "Session1",
"ClinicalTrialTimePointID": "1",
"SeriesDescription": "Segmentation",
"SeriesNumber": "300",
"InstanceNumber": "1",
"BodyPartExamined": "Liver and Spleen",
"segmentAttributes": [segment_attributes],
"ContentLabel": "SEGMENTATION",
"ContentDescription": "Image segmentation",
"ClinicalTrialCoordinatingCenterName": "dcmqi"
}
# Save metadata to a JSON file
metadata_file = os.path.join(os.path.dirname(output_seg_file), "metadata.json")
with open(metadata_file, "w") as f:
json.dump(metadata, f, indent=4)
# Construct the command to convert the NIfTI to DICOM SEG
cmd = [
r'/media/zain/New Volume/PycharmProjects/XRAD/.venv/lib/python3.10/site-packages/dcmqi/bin/itkimage2segimage',
"--inputImageList", nifti_file,
"--inputMetadata", metadata_file,
"--outputDICOM", output_seg_file,
"--inputDICOMDirectory", dicom_dir,
"--skip", "0"
]
try:
# Execute the command
result = subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print("Conversion successful!")
print("Output:", result.stdout)
except subprocess.CalledProcessError as e:
# Handle errors
print("Error during conversion:")
print("Output:", e.stdout)
print("Error:", e.stderr)
# Example usage
nifti_file = "niftis/2.25.1937671288494678696440169598763456789/2.25.1937671288494678696440169598763456789_seg.nii.gz" # Path to your NIfTI file
dicom_dir = "dicoms/2.25.1937671288494678696440169598763456789/" # Directory containing the DICOM files
output_seg_file = "./output/multi_class_seg.dcm" # Path to save the DICOM SEG file
convert_nifti_to_dcm_seg(nifti_file, dicom_dir, output_seg_file)
Conversion command used in above python script
itkimage2segimage --inputImageList <nifti_file> \
--inputMetadata <metadata.json> \
--outputDICOM <output_seg_file> \
--inputDICOMDirectory <dicom_dir> \
--skip 0
To help debug this issue, I am sharing the files - link