Пример #1
0
def run(case):
  global PARAMS, ROOT, TEMP_DIR
  ptLogger = logging.getLogger('radiomics.batch')

  feature_vector = OrderedDict(case)

  try:
    # set thread name to patient name
    threading.current_thread().name = case['Patient']

    filename = r'features_' + str(case['Reader']) + '_' + str(case['Patient']) + '.csv'
    output_filename = os.path.join(ROOT, TEMP_DIR, filename)

    if os.path.isfile(output_filename):
      # Output already generated, load result (prevents re-extraction in case of interrupted process)
      with open(output_filename, 'w') as outputFile:
        reader = csv.reader(outputFile)
        headers = reader.rows[0]
        values = reader.rows[1]
        feature_vector = OrderedDict(zip(headers, values))

      ptLogger.info('Patient %s read by %s already processed...', case['Patient'], case['Reader'])

    else:
      t = datetime.now()

      imageFilepath = case['Image']  # Required
      maskFilepath = case['Mask']  # Required
      label = case.get('Label', None)  # Optional

      # Instantiate Radiomics Feature extractor

      extractor = RadiomicsFeatureExtractor(PARAMS)

      # Extract features
      feature_vector.update(extractor.execute(imageFilepath, maskFilepath), label=label)

      # Store results in temporary separate files to prevent write conflicts
      # This allows for the extraction to be interrupted. Upon restarting, already processed cases are found in the
      # TEMP_DIR directory and loaded instead of re-extracted
      with open(output_filename, 'w') as outputFile:
        writer = csv.DictWriter(outputFile, fieldnames=list(feature_vector.keys()), lineterminator='\n')
        writer.writeheader()
        writer.writerow(feature_vector)

      # Display message

      delta_t = datetime.now() - t

      ptLogger.info('Patient %s read by %s processed in %s', case['Patient'], case['Reader'], delta_t)

  except Exception:
    ptLogger.error('Feature extraction failed!', exc_info=True)

  return feature_vector
Пример #2
0
def get_diameter(mask_path: str, pet_path: str,
                 number_bigger_roi: int) -> tuple:
    """get 2D and 3D diameter of the biggest ROI in MASK

    Args:
        mask_path ([str]): [path of nifti mask (3D image, PixelVector type), size (x,y,z)]
        pet_path ([str]): [path of nifti PET]
        number_bigger_roi ([int]): [Number of the bigger ROI (in volume)]

    Returns:
        [tuple]: [Return 2D and 3D float diameter]
    """
    #PET
    img_pet = sitk.ReadImage(pet_path)
    origin = img_pet.GetOrigin()
    direction = img_pet.GetDirection()
    spacing = img_pet.GetSpacing()
    pet_array = sitk.GetArrayFromImage(img_pet).transpose()
    size = pet_array.shape

    #MASK
    img_mask = sitk.ReadImage(mask_path)
    mask_array = sitk.GetArrayFromImage(img_mask)
    mask_array = np.transpose(mask_array, (3, 0, 1, 2)).transpose()  #(x,y,z,c)

    #seuillage 41%
    mask_array = threshold_matrix(mask_array, pet_array, 0.41)

    if len(mask_array.shape) == 4:
        bigger_roi = mask_array[:, :, :, number_bigger_roi - 1]

    else:
        if np.max(mask_array) == 1.0:
            bigger_roi = mask_array
        else:
            x, y, z = np.where(mask_array == number_bigger_roi - 1)
            bigger_roi = np.zeros(size)
            bigger_roi[x, y, z] = 1

    new_mask_img = sitk.GetImageFromArray(bigger_roi.transpose())
    new_mask_img.SetOrigin(origin)
    new_mask_img.SetDirection(direction)
    new_mask_img.SetSpacing(spacing)

    extractor = RadiomicsFeatureExtractor()
    results = extractor.execute(img_pet, new_mask_img)
    diameter_3d = results['original_shape_Maximum3DDiameter']
    diameter_2d = results['original_shape_Maximum2DDiameterSlice']
    return float(diameter_2d), float(diameter_3d)
Пример #3
0
 def singleRun(self):
     self.extractor = RadiomicsFeatureExtractor(**self.setting)
     self.extractor.enableImageTypes(Original={},
                                     LoG={},
                                     Wavelet={},
                                     SquareRoot={},
                                     Square={},
                                     Logarithm={},
                                     Gradient={},
                                     Exponential={},
                                     LBP3D={},
                                     )
     i = 1
     for case in self.cases:
         print("\rdealing with the " + str(i) + "/" + str(len(self.cases)) + " image...")
         i += 1
         self.singleCal(case)
     print("calculate successfully!")
Пример #4
0
                            except:
                                print('Warning:%s`s %s_%s have problems!!!' %
                                      (patient, m, name))
        row += 1
    file.save(
        os.path.join('/home/lyu/PythonProjects/radiomics/Feature/Multi model',
                     'test_multi_modal_%s.xlsx' % name))


# import settings file
params = './mine.yaml'
# params = './MR.yaml'

# obtain the feature extractor class with the setting file
extractor = RadiomicsFeatureExtractor(params)
# enable or disable
extractor.addProvenance(provenance_on=False)

setVerbosity(60)

file = Workbook()
table = file.create_sheet('data')
dataDir = '/media/lyu/841G/DATA/Gliomas/ALL'
ROIDir = '/media/lyu/841G/DATA/Gliomas/Converted_ROI'

# 分四个list存不同的ROI
nangbian_mask, shizhi_mask, zhongliu_mask, shuizhong_mask, bingbian_mask = fileHanding.classifyROI(
    ROIDir)
# modal = ['3DT1','rCBF','ADC','Dfast','Dslow','_f']
modal = ['3DT1']
Пример #5
0
    def _calculate(self, case):
        ptLogger = logging.getLogger('radiomics.batch')
        feature_vector = OrderedDict(case)
        # to suggest the temp file is valid/invalid
        p=0

        try:
            # set thread name to patient name
            threading.current_thread().name = case['Subject']
            filename = r'features_' + '_' + str(case['Patient']) + '.csv'
            output_filename = os.path.join(self.ROOT, self.TEMP_DIR, filename)
            newFeatureVector = {}
            if os.path.isfile(output_filename):
                with open(output_filename, 'w') as outputFile:
                    reader = csv.reader(outputFile)
                    try:
                        headers = reader.rows[0]
                        values = reader.rows[1]
                    except Exception:
                        p=1
                        rLogger.debug("the temp file ", output_filename, "is damaging,please delete it")
            if os.path.isfile(output_filename) and p ==0:
                with open(output_filename, 'w') as outputFile:
                    reader = csv.reader(outputFile)
                    try:
                        headers = reader.rows[0]
                        values = reader.rows[1]
                        feature_vector = OrderedDict(zip(headers, values))
                        # filter some feature that isn't number
                        for featureName in feature_vector.keys():
                            if featureName not in self.notDisplayType:
                                if not isinstance(feature_vector[featureName], (list, dict, tuple)):
                                    newFeatureVector[featureName] = feature_vector[featureName]
                    except Exception:
                        rLogger.debug("Erro ++:::++The temp file", output_filename, "is damaging,please delete it")
                        return {"Subject": case['Subject']}
                ptLogger.info('Subject %s  already processed...', case['Patient'])
            else:
                t = datetime.now()
                imageFilepath = case['Image']  # Required
                maskFilepath = case['Mask']  # Required
                label = case.get('Label', None)  # Optional
                extractor = RadiomicsFeatureExtractor(**(self.setting))
                extractor.enableImageTypes(Original={},
                                           LoG={},
                                           Wavelet={},
                                           SquareRoot={},
                                           Square={},
                                           Logarithm={},
                                           Gradient={},
                                           Exponential={},
                                           LBP3D={},
                                           )
                extractor.enableAllFeatures()
                feature_vector.update(extractor.execute(imageFilepath, maskFilepath), label=label)
                # filter some feature that isn't number
                for featureName in feature_vector.keys():
                    if featureName not in notDisplayType:
                        if not isinstance(feature_vector[featureName], (list, dict, tuple)):
                            newFeatureVector[featureName] = feature_vector[featureName]
                # Store results in temporary separate files to prevent write conflicts
                # This allows for the extraction to be interrupted. Upon restarting, already processed cases are found in the
                # TEMP_DIR directory and loaded instead of re-extracted
                with open(output_filename, 'w') as outputFile:
                    writer = csv.DictWriter(outputFile, fieldnames=list(newFeatureVector.keys()), lineterminator='\n')
                    writer.writeheader()
                    writer.writerow(newFeatureVector)
                # Display message
                delta_t = datetime.now() - t
                ptLogger.info('Subject %s read by %s processed in', case['Patient'], delta_t)
        except Exception as e:
            ptLogger.error("Compute Error ! Error ! Error ! Error !\r\n"+str(e))
            newFeatureVector["diagnostics_Image-original_Mean"] = "Calculate ERRO ! , please check your data!"
            newFeatureVector["Image"]=feature_vector.get("Image")
            newFeatureVector["Mask"] = feature_vector.get("Mask")
            newFeatureVector["Subject"] =feature_vector.get("Subject")
        finally:
            return newFeatureVector
Пример #6
0
class feature:
    def __init__(self, outputfile, cases, settings={}, tempDir="_TEMP", root=os.getcwd(), notDisplayType={}):
        self.setting = settings
        self.ROOT = root
        self.TEMP_DIR = tempDir
        self._filename = outputfile
        self.notDisplayType = notDisplayType
        self.cases = cases
        self.NUM_OF_WORKERS = cpu_count() - 5
        self.inputHeader = 0
        self.t_list = []
        if self.NUM_OF_WORKERS < 1:
            self.NUM_OF_WORKERS = 1
        self.REMOVE_TEMP_DIR = True
        if (len(self.cases) < self.NUM_OF_WORKERS):
            self.NUM_OF_WORKERS = len(self.cases)
        if not os.path.isdir(os.path.join(self.ROOT, self.TEMP_DIR)):
            print('Creating temporary output directory %s', os.path.join(self.ROOT, self.TEMP_DIR))
            os.mkdir(os.path.join(self.ROOT, self.TEMP_DIR))
        #self.pool = Pool(self.NUM_OF_WORKERS)

    def _calculate(self, case):
        ptLogger = logging.getLogger('radiomics.batch')
        feature_vector = OrderedDict(case)
        # to suggest the temp file is valid/invalid
        p=0

        try:
            # set thread name to patient name
            threading.current_thread().name = case['Subject']
            filename = r'features_' + '_' + str(case['Patient']) + '.csv'
            output_filename = os.path.join(self.ROOT, self.TEMP_DIR, filename)
            newFeatureVector = {}
            if os.path.isfile(output_filename):
                with open(output_filename, 'w') as outputFile:
                    reader = csv.reader(outputFile)
                    try:
                        headers = reader.rows[0]
                        values = reader.rows[1]
                    except Exception:
                        p=1
                        rLogger.debug("the temp file ", output_filename, "is damaging,please delete it")
            if os.path.isfile(output_filename) and p ==0:
                with open(output_filename, 'w') as outputFile:
                    reader = csv.reader(outputFile)
                    try:
                        headers = reader.rows[0]
                        values = reader.rows[1]
                        feature_vector = OrderedDict(zip(headers, values))
                        # filter some feature that isn't number
                        for featureName in feature_vector.keys():
                            if featureName not in self.notDisplayType:
                                if not isinstance(feature_vector[featureName], (list, dict, tuple)):
                                    newFeatureVector[featureName] = feature_vector[featureName]
                    except Exception:
                        rLogger.debug("Erro ++:::++The temp file", output_filename, "is damaging,please delete it")
                        return {"Subject": case['Subject']}
                ptLogger.info('Subject %s  already processed...', case['Patient'])
            else:
                t = datetime.now()
                imageFilepath = case['Image']  # Required
                maskFilepath = case['Mask']  # Required
                label = case.get('Label', None)  # Optional
                extractor = RadiomicsFeatureExtractor(**(self.setting))
                extractor.enableImageTypes(Original={},
                                           LoG={},
                                           Wavelet={},
                                           SquareRoot={},
                                           Square={},
                                           Logarithm={},
                                           Gradient={},
                                           Exponential={},
                                           LBP3D={},
                                           )
                extractor.enableAllFeatures()
                feature_vector.update(extractor.execute(imageFilepath, maskFilepath), label=label)
                # filter some feature that isn't number
                for featureName in feature_vector.keys():
                    if featureName not in notDisplayType:
                        if not isinstance(feature_vector[featureName], (list, dict, tuple)):
                            newFeatureVector[featureName] = feature_vector[featureName]
                # Store results in temporary separate files to prevent write conflicts
                # This allows for the extraction to be interrupted. Upon restarting, already processed cases are found in the
                # TEMP_DIR directory and loaded instead of re-extracted
                with open(output_filename, 'w') as outputFile:
                    writer = csv.DictWriter(outputFile, fieldnames=list(newFeatureVector.keys()), lineterminator='\n')
                    writer.writeheader()
                    writer.writerow(newFeatureVector)
                # Display message
                delta_t = datetime.now() - t
                ptLogger.info('Subject %s read by %s processed in', case['Patient'], delta_t)
        except Exception as e:
            ptLogger.error("Compute Error ! Error ! Error ! Error !\r\n"+str(e))
            newFeatureVector["diagnostics_Image-original_Mean"] = "Calculate ERRO ! , please check your data!"
            newFeatureVector["Image"]=feature_vector.get("Image")
            newFeatureVector["Mask"] = feature_vector.get("Mask")
            newFeatureVector["Subject"] =feature_vector.get("Subject")
        finally:
            return newFeatureVector

    def run(self, Q=None):
        mainLogger = logging.getLogger('radiomics.batch')
        threading.current_thread().name = 'Main'
        cnt = 1
        results = []
        for result in self.pool.imap_unordered(self._calculate, self.cases):
            print('processing the images,done   %d/%d...' % (cnt, len(self.cases)))
            cnt += 1
            if Q != None:
                Q.put(int((cnt - 1) / len(self.cases) * 100))
            results.append(result)
        try:
            results = sorted(results, key=lambda r: r.get("Subject"))
        except Exception as e:
            mainLogger.debug(str(e))
        finally:
            try:
                self._writeResults(results)
            except Exception:
                mainLogger.debug('Error |||| storing results into single file!', str(e))

    def singleCal(self, case):
        print("case",case)
        image = sitk.ReadImage(str(case.get("Image")))
        mask = sitk.ReadImage(str(case.get("Mask")))
        mask = sitk.Cast(mask, sitk.sitkInt8)
        featureVector = OrderedDict(case)
        featureVector.update(self.extractor.execute(image, mask))
        with open(self._filename, 'a+') as csvfile:
            if (self.inputHeader == 0):
                for featureName in featureVector.keys():
                    if featureName not in self.notDisplayType:
                        if not isinstance(featureVector[featureName], (list, dict, tuple)):
                            self.t_list.append(featureName)
                writer = csv.DictWriter(csvfile, fieldnames=self.t_list, lineterminator='\n')
                writer.writeheader()
                self.inputHeader = 1
            else:
                writer = csv.DictWriter(csvfile, fieldnames=self.t_list, lineterminator='\n')
            new = {k: v for k, v in featureVector.items() if k in self.t_list}
            writer.writerow(new)

    def singleRun(self):
        self.extractor = RadiomicsFeatureExtractor(**self.setting)
        self.extractor.enableImageTypes(Original={},
                                        LoG={},
                                        Wavelet={},
                                        SquareRoot={},
                                        Square={},
                                        Logarithm={},
                                        Gradient={},
                                        Exponential={},
                                        LBP3D={},
                                        )
        i = 1
        for case in self.cases:
            print("\rdealing with the " + str(i) + "/" + str(len(self.cases)) + " image...")
            i += 1
            self.singleCal(case)
        print("calculate successfully!")

    def _writeResults(self, results):
        with open(self._filename, mode='w') as outputFile:
            writer = csv.DictWriter(outputFile,
                                    fieldnames=list(results[0].keys()),
                                    restval='',
                                    extrasaction='raise',
                                    lineterminator='\n')
            writer.writeheader()
            writer.writerows(results)
        if self.REMOVE_TEMP_DIR:
            logger.info('Removing temporary directory %s (contains individual case results files)',
                        os.path.join(self.ROOT, self.TEMP_DIR))
            shutil.rmtree(os.path.join(self.ROOT, self.TEMP_DIR))
            print("completed!")

    def __getstate__(self):
        self_dict = self.__dict__.copy()
        del self_dict['pool']
        return self_dict

    def __setstate__(self, state):
        self.__dict__.update(state)
Пример #7
0
for c in classes:
    im_list=paths.list_images(os.path.join(base_path,c))
    for i in im_list:
        if "mask" not in i:
            X.append(load_img(i))
            y.append(c)
        else:
            if "mask_" not in i:
                masks.append(load_mask(i))




settings = {'interpolator': sitk.sitkBSpline,'label': 255}
extractor = RadiomicsFeatureExtractor(**settings)
extractor.enableAllImageTypes()


results=[]
for i in range(len(X)):
    if i%50==0:
        print(f"[INFO] Evaluating {i+1}/{len(X)}")
    d=dict(extractor.execute(X[i],masks[i]))
    status={"status":y[i]}
    d.update(status)
    results.append(d)

print(f"[INFO] Saving results to radiomics_features_extracted.csv")

df=pd.DataFrame.from_dict(results)
Пример #8
0
    def extraction(image, image_mask, label):

        settings = {}
        #settings['binWidth'] = 25

        settings['verbose'] = False
        settings['distances']  = [1, 2, 5, 10]
        extractor = RadiomicsFeatureExtractor(**settings)
        #binWidth=20

        # Enable a filter (in addition to the 'Original' filter already enabled)
        #extractor.enableInputImageByName('LoG')
        #extractor.enableInputImages(wavelet= {'level': 2})


        #extractor.enableAllFeatures()
        extractor.disableAllFeatures()
        extractor.enableFeatureClassByName('firstorder')#19
        extractor.enableFeatureClassByName('glcm')#24
        extractor.enableFeatureClassByName('glrlm')#16   
        extractor.enableFeatureClassByName('glszm')#16
        extractor.enableFeatureClassByName('ngtdm')#5
        extractor.enableFeatureClassByName('gldm')#14


        
        #extractor.enableFeatureClassByName('glszm')
        #extractor.enableFeatureClassByName('gldm')
        #extractor.enableFeatureClassByName('ngtdm')



        result = extractor.execute(image, image_mask, label=label)
        #result = extractor.execute(image, image_mask)
        features_names = []
        #features_values = {}
        features_values = []
        
        for k,v in result.items():
            if k.startswith('original_'): 
                features_names.append(k)
                features_values.append(v.tolist())
        #print("RAD size features", len(features_values))
                #features_values.append(v.tolist()[0])
        """ 
        for k,v in features_values.items():
            print(k, v)
        """
        return features_names, features_values
Пример #9
0
base = os.path.dirname(__file__)
model_path = os.path.abspath(
    os.path.join(
        base,
        '../models/svmclassifier.C30_coef01.0_degree3_kernelpoly_selected_features100_histomics_rgb_color_histogram_rgb.joblib.pkl'
    ))
model = joblib.load(model_path)

scaler_path = os.path.abspath(
    os.path.join(base, '../utils/scaler_gui_100_features.joblib.pkl'))
scaler = joblib.load(scaler_path)

tiles = []
tile_width, tile_height = 50, 50

r_chan_extractor = RadiomicsFeatureExtractor()
r_chan_extractor.settings = r_chan_extractor_params['setting']
r_chan_extractor.imageType = r_chan_extractor_params['imageType']
r_chan_extractor.enabledFeatures = r_chan_extractor_params['featureClass']

g_chan_extractor = RadiomicsFeatureExtractor()
g_chan_extractor.settings = g_chan_extractor_params['setting']
g_chan_extractor.imageType = g_chan_extractor_params['imageType']
g_chan_extractor.enabledFeatures = g_chan_extractor_params['featureClass']

b_chan_extractor = RadiomicsFeatureExtractor()
b_chan_extractor.settings = b_chan_extractor_params['setting']
b_chan_extractor.imageType = b_chan_extractor_params['imageType']
b_chan_extractor.enabledFeatures = b_chan_extractor_params['featureClass']

Пример #10
0
def get_center_of_mass(mask_path: str,
                       thresh: float = 0.41,
                       pet_path: str = None) -> list:
    """Get the list of every ROIs center

    Args:
        mask_path ([str]): [path of nifti mask (3D image, PixelVector type), size (x,y,z)]
        thresh (float, optional): [If choose to threshold the mask, set a threshold. Instead, thresh=None]. Defaults to 0.41.
        pet_path ([str], optional): [If thresh is True, nifti PET path]. Defaults to None.

    Returns:
        [list]: [Return a list of list of x,y,z physical coordonates of every ROIs center.]
    """
    center = []
    if pet_path != None:
        pet_img = sitk.ReadImage(pet_path)
        pet_array = sitk.GetArrayFromImage(pet_img).transpose()  #(x,y,z)
    mask_img = sitk.ReadImage(mask_path)
    mask_array = sitk.GetArrayFromImage(mask_img)  #(z, x, y, c)
    mask_array = np.transpose(mask_array, (3, 0, 1, 2)).transpose()  #(x,y,z,c)
    type_ = None
    if len(mask_array.shape) != 3:
        type_ = '4D'
        origin = mask_img.GetOrigin()
        direction = mask_img.GetDirection()
        spacing = mask_img.GetSpacing()
        size = mask_img.GetSize()
        pet_arr = np.random.randint(10, size=(size)).transpose()
        if pet_path is None:
            pet_img = sitk.GetImageFromArray(pet_arr)
            pet_img.SetOrigin(origin)
            pet_img.SetDirection(direction)
            pet_img.SetSpacing(spacing)

    else:
        type_ = '3D'
        origin = mask_img.GetOrigin()
        direction = mask_img.GetDirection()
        spacing = mask_img.GetSpacing()
        size = mask_img.GetSize()
        pet_arr = np.random.randint(10, size=(size)).transpose()
        if pet_path is None:
            pet_img = sitk.GetImageFromArray(pet_arr)
            pet_img.SetOrigin(origin)
            pet_img.SetDirection(direction)
            pet_img.SetSpacing(spacing)

    if type_ == '3D':
        if thresh == None:
            number_of_roi = int(np.max(mask_array))
            for i in range(1, number_of_roi + 1):
                extractor = RadiomicsFeatureExtractor()
                results = extractor.execute(pet_img, mask_img, label=i)
                x, y, z = results['diagnostics_Mask-original_CenterOfMass']
                center.append([x, y, z])

        else:
            if np.max(mask_array) == 1.0:
                mask_threshold = threshold_matrix(mask_array, pet_array,
                                                  thresh)
                mask_threshold = mask_threshold.transpose()
                new_mask = sitk.GetImageFromArray(mask_threshold)
                new_mask.SetOrigin(origin)
                new_mask.SetDirection(direction)
                new_mask.SetSpacing(spacing)
                extractor = RadiomicsFeatureExtractor()
                results = extractor.execute(pet_img, new_mask)
                x, y, z = results['diagnostics_Mask-original_CenterOfMass']
                center.append([x, y, z])

            else:
                number_of_roi = int(np.max(mask_array))
                mask_threshold = threshold_matrix(mask_array, pet_array,
                                                  thresh)
                mask_threshold = mask_threshold.transpose()
                new_mask = sitk.GetImageFromArray(mask_threshold)
                new_mask.SetOrigin(origin)
                new_mask.SetDirection(direction)
                new_mask.SetSpacing(spacing)
                for i in range(1, number_of_roi + 1):
                    extractor = RadiomicsFeatureExtractor()
                    results = extractor.execute(pet_img, new_mask, label=i)
                    x, y, z = results['diagnostics_Mask-original_CenterOfMass']
                    center.append([x, y, z])

    if type_ == '4D':
        if thresh == None:
            for i in range(mask_array.shape[3]):
                mask_3d = mask_array[:, :, :, i].astype('int8')
                mask_3d = mask_3d.transpose().astype('int8')
                if len(np.unique(mask_3d)) > 1:
                    new_mask = sitk.GetImageFromArray(mask_3d)
                    new_mask.SetOrigin(origin)
                    new_mask.SetDirection(direction)
                    new_mask.SetSpacing(spacing)
                    extractor = RadiomicsFeatureExtractor()
                    results = extractor.execute(pet_img, new_mask)
                    x, y, z = results['diagnostics_Mask-original_CenterOfMass']
                    center.append([x, y, z])
                else:
                    pass

        else:
            for i in range(mask_array.shape[3]):
                mask_3d = mask_array[:, :, :, i].astype('int8')
                mask_3d = threshold_matrix(mask_3d, pet_array,
                                           thresh).astype('int8')
                x, y, z = np.where(mask_3d != 0)
                if len(x) != 0 and len(np.unique(x)) > 1:
                    mask_3d = mask_3d.transpose().astype('int8')
                    new_mask = sitk.GetImageFromArray(mask_3d)
                    new_mask.SetOrigin(origin)
                    new_mask.SetDirection(direction)
                    new_mask.SetSpacing(spacing)
                    extractor = RadiomicsFeatureExtractor()
                    results = extractor.execute(pet_img, new_mask)
                    x, y, z = results['diagnostics_Mask-original_CenterOfMass']
                    center.append([x, y, z])
                else:
                    pass

    return center