You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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)
dcmqi currently does not support multilayered segmentations. You would need to store your segmentation as a single-channel labelmap (if labels do not overlap), or as separate files (if they do overlap).
Pull request implementing improvements to support multilayer input would definitely be welcomed!
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:
Conversion command used in above python script
To help debug this issue, I am sharing the files - link
The text was updated successfully, but these errors were encountered: