[Python] Duplicate Frames When Converting NIfTI to DICOM SEG Using itkimage2segimage

Discussão em 'Python' iniciado por Stack, Dezembro 1, 2024.

  1. Stack

    Stack Membro Participativo

    I'm converting a NIfTI file with multiple segmentations (e.g., Liver and Spleen) into a DICOM SEG file using the itkimage2segimage tool from dcmqi.

    For example:

    • Input NIfTI: 203 slices with 2 labels (Liver, Spleen).
    • Output DICOM SEG: 406 slices (203 slices per label).

    How can I modify the code to produce a combined segmentation or you can say multilayer segmentation for all 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 - code files

    Continue reading...

Compartilhe esta Página