AIM-Harvard / pyradiomics

Open-source python package for the extraction of Radiomics features from 2D and 3D images and binary masks. Support: https://discourse.slicer.org/c/community/radiomics
http://pyradiomics.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
1.11k stars 485 forks source link

Finding the relevant label for extracting radiomics features #852

Closed ToniTannoury closed 7 months ago

ToniTannoury commented 7 months ago

Hello , I am a research fellow at an hospital in beirut where we started diving into radiomics. I am currently working on a script that extracts radiomic features from a folder containing multiple CT images for the patient and another file in RTSTRUCT for the contours . These images where downloaded from the cancer imaging archive.The issue i am facing is that i am getting the below error File “C:\Users\toni\AppData\Local\Programs\Python\Python310\lib\site-packages\radiomics\imageoperations.py”, line 51, in getMask raise ValueError(‘Label (%g) not present in mask. Choose from %s’ % (label, labels[labels != 0])) ValueError: Label (1) not present in mask. Choose from [ 2 4 5 8 9 10 11 13 14 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 4294967267 4294967268 4294967269 4294967270 4294967271 4294967272 4294967273 4294967274 4294967275 4294967276 4294967277 4294967278 4294967279 4294967280 4294967281 4294967282 4294967283 4294967284 4294967285 4294967286 4294967287 4294967288 4294967292 4294967293] even tho I am only passing the contour for the tumor .I think the issue is not specifying the label in my main file here results = extractor.execute(image, mask ,return_labels=True).GetLabels() (Code will be provided at the end ) but i do not know how to choose the appropriate label. Help would be very much appreciated and a huge help for our radiomics studies. Thank you in advance :slight_smile:

Python Code :import os import matplotlib.pyplot as plt import numpy as np import SimpleITK as sitk import pydicom from radiomics import featureextractor

def load_dicom_series(directory): reader = sitk.ImageSeriesReader() dicom_names = reader.GetGDCMSeriesFileNames(directory) reader.SetFileNames(dicom_names) return reader.Execute()

def load_rtstruct(file_path): rtstruct = pydicom.read_file(file_path) return rtstruct

def extract_radiomic_features(image, mask): parameters =[ 25, [1, 1, 1] ]

lsif = sitk.LabelStatisticsImageFilter() extractor = featureextractor.RadiomicsFeatureExtractor(parameters)

results = extractor.execute(image, mask ,return_labels=True).GetLabels() imageNode, maskNode = extractor.loadImage(image, mask)

lsif.Execute(imageNode, maskNode) counter = 0 for result in results: counter +=1

if counter != 3:
    continue
boundingBox = np.array(lsif.GetBoundingBox(result))

ndims = np.sum((boundingBox[1::2] - boundingBox[0::2] + 1) > 1)
if ndims > 1 :
    results = extractor.execute(image, mask ,result)
    break
raise Exception("No labels picked")

return results def main():

dicom_directory = r’C:\Users\toni\Desktop\manifest-1700734196925\4D-Lung\115_HM10395\04-26-2000-NA-p4-06742\1.000000-P4P115S300I00007 Gated 30.0A-41594’ file_path = os.path.join( “C:\Users\toni\Desktop\manifest-1700734196925\4D-Lung\115_HM10395\04-26-2000-NA-p4-06742\1.000000-P4P115S300I00007 Gated 30.0A-734.4\1-1.dcm”) rtstruct = pydicom.read_file(file_path) tumor_id = None contours_list = rtstruct.StructureSetROISequence._list

for contour in contours_list: if "tumor" in contour.ROIName.casefold(): tumor_id = contour.ROINumber

image = load_dicom_series(dicom_directory)

contours_list = rtstruct.ROIContourSequence._list contour_sequence = list(filter(lambda element: element.ReferencedROINumber == tumor_id, contours_list))[ 0].ContourSequence

num_slices = len(contour_sequence) contour_data_reshaped = []

max_contour_elements = max(len(seq.ContourData) for seq in contour_sequence)

for i in range(num_slices): contour_data = contour_sequence[i].ContourData

contour_data_list = list(contour_data) + [0.0] * (max_contour_elements - len(contour_data))
contour_data_padded = np.array(contour_data_list).reshape((-1, 3))
contour_data_reshaped.append(contour_data_padded)

mask = sitk.GetImageFromArray(np.array(contour_data_reshaped)) mask.SetSpacing((1.0, 1.0, 1.0))

resampler = sitk.ResampleImageFilter() resampler.SetSize(image.GetSize()) resampler.SetOutputSpacing(image.GetSpacing()) resampler.SetOutputOrigin(image.GetOrigin()) resampler.SetOutputDirection(image.GetDirection()) mask = resampler.Execute(mask)

print(image.GetSize()) print(mask.GetSize()) features = extract_radiomic_features(image, mask)

for key, value in features.items(): print(f"{key}: {value}") if name == “main”: main()