def DATA_AUGMENTATION(self, data_set_ids, augmentation_factor): """ Perform data augmentation operations on a dataset - Data are augmented "augmentation_factor" times data_set_ids : [(PET_id_1,CT_id_1,MASK_id_1),(PET_id_2,CT_id_2,MASK_id_2)...] """ n_patients = len(data_set_ids) new_data_set_ids = [] for i, data_set_id in enumerate(data_set_ids): # load files PET_id, CT_id, MASK_id = data_set_id PET_img = sitk.ReadImage(PET_id, sitk.sitkFloat32) CT_img = sitk.ReadImage(CT_id, sitk.sitkFloat32) MASK = sitk.ReadImage(MASK_id, sitk.sitkUInt8) # display a loading bar display_loading_bar(iteration=i, length=n_patients, add_char=basename(MASK_id) + ' ') for factor in range(1, augmentation_factor): # generate random deformation def_ratios = self.DATA_AUGMENTATION_DeformationRatios() # apply same transformation to PET / CT / Mask new_PET_img = self.DATA_AUGMENTATION_AffineTransformation( image=PET_img, interpolator=sitk.sitkBSpline, deformations=def_ratios) new_CT_img = self.DATA_AUGMENTATION_AffineTransformation( image=CT_img, interpolator=sitk.sitkBSpline, deformations=def_ratios) new_MASK_img = self.DATA_AUGMENTATION_AffineTransformation( image=MASK, interpolator=sitk.sitkNearestNeighbor, deformations=def_ratios) # generates names new_PET_id = splitext(PET_id)[0] + '_augm' * factor + '.nii' new_CT_id = splitext(CT_id)[0] + '_augm' * factor + '.nii' new_Mask_id = splitext(MASK_id)[0] + '_augm' * factor + '.nii' # saves sitk.WriteImage(new_PET_img, new_PET_id) sitk.WriteImage(new_CT_img, new_CT_id) sitk.WriteImage(new_MASK_img, new_Mask_id) new_data_set_ids.append((new_PET_id, new_CT_id, new_Mask_id)) return new_data_set_ids
def PREPROCESS(self, data_set_ids, path_output, output_shape=None, pixel_size=None, resample=True, normalize=True): """ Perform preprocessing and save new datas from a dataset data_set_ids : [(PET_id_1,CT_id_1,MASK_id_1),(PET_id_2,CT_id_2,MASK_id_2)...] """ n_patients = len(data_set_ids) preprocessed_data_set_ids = [] for i, data_set_id in enumerate(data_set_ids): # display a loading bar display_loading_bar(iteration=i, length=n_patients, add_char=basename(data_set_id[0]) + ' ') # load data set self.PET_id, self.CT_id, self.MASK_id = data_set_id self.PET_img = sitk.ReadImage(self.PET_id, sitk.sitkFloat32) self.CT_img = sitk.ReadImage(self.CT_id, sitk.sitkFloat32) self.MASK_img = sitk.ReadImage(self.MASK_id, sitk.sitkUInt8) if normalize: self.PREPROCESS_normalize() if resample: self.PREPROCESS_resample_CT_to_TEP() self.PREPROCESS_resample_TEPCT_to_CNN( output_shape[::-1], pixel_size[::-1]) #reorder to [x,y,z] # save preprocess data new_PET_id = path_output + '/' + splitext(basename( data_set_id[0]))[0] + '.nii' new_CT_id = path_output + '/' + splitext(basename( data_set_id[1]))[0] + '.nii' new_MASK_id = path_output + '/' + splitext(basename( data_set_id[2]))[0] + '.nii' preprocessed_data_set_ids.append( (new_PET_id, new_CT_id, new_MASK_id)) self.PREPROCESS_save(new_filenames=preprocessed_data_set_ids[i]) # clear del self.PET_id, self.CT_id, self.MASK_id del self.PET_img, self.CT_img, self.MASK_img return preprocessed_data_set_ids
def PREDICT_MASK(self, data_set_ids, path_predictions, trained_model): """ Perform and save prediction on a data set filenames data_set_ids : [(PET_id_1,CT_id_1),(PET_id_2,CT_id_2)...] """ # generates folder if not os.path.exists(path_predictions): os.makedirs(path_predictions) filenames_predicted_masks = [] n_patients = len(data_set_ids) for i, data_set_id in enumerate(data_set_ids): # display a loading bar display_loading_bar(iteration=i, length=n_patients, add_char=basename(data_set_id[0]) + ' ') PET_id, CT_id = data_set_id # load files and prepare model input PET_scan = tf.constant(sitk.GetArrayFromImage( sitk.ReadImage(PET_id, sitk.sitkFloat32)), dtype=tf.float32) CT_scan = tf.constant(sitk.GetArrayFromImage( sitk.ReadImage(CT_id, sitk.sitkFloat32)), dtype=tf.float32) scan = tf.stack((PET_scan, CT_scan), axis=-1) scan = tf.expand_dims(scan, axis=0) scan_dataset = tf.data.Dataset.from_tensor_slices(scan).batch(1) prediction = trained_model.predict(scan_dataset) prediction = tf.argmax(prediction, axis=-1) # output from a multiclass softmax prediction = tf.squeeze(prediction).numpy() # conversion in unsigned int 8 to store mask with less memory requirement mask = np.asarray(prediction, dtype=np.uint8) new_filename = path_predictions + "/pred_" + splitext( basename(data_set_id[0]))[0] + '.nii' filenames_predicted_masks.append(new_filename) sitk.WriteImage(sitk.GetImageFromArray(mask), new_filename) return filenames_predicted_masks
def GENERATES_MIP_PREDICTION(self, path_output, data_set_ids, pred_ids, filename=None): """ Generate MIP projection of PET/CT files with its predicted mask data_set_ids : [(PET_id_1,CT_id_1),(PET_id_2,CT_id_2)...] """ if filename is None: filename = path_output + "/PETCT_MIP_" + time.strftime( "%m%d%H%M%S") + ".pdf" else: filename = path_output + '/' + filename # generates folder if not os.path.exists(path_output): os.makedirs(path_output) n_patients = len(data_set_ids) transparency = 0.7 color_CT = plt.cm.gray color_PET = plt.cm.plasma color_MASK = copy(plt.cm.Greys) color_MASK.set_bad('white', 0.0) with PdfPages(filename) as pdf: # loop on files to get MIP visualisation for i, (DataSet_id, Pred_id) in enumerate(zip(data_set_ids, pred_ids)): display_loading_bar(iteration=i, length=n_patients, add_char=basename(DataSet_id[0]) + ' ') # load imgs PET_id, CT_id = DataSet_id PET_scan = sitk.GetArrayFromImage(sitk.ReadImage(PET_id)) CT_scan = sitk.GetArrayFromImage(sitk.ReadImage(CT_id)) PRED = sitk.GetArrayFromImage(sitk.ReadImage(Pred_id)) # for TEP visualisation PET_scan = np.where(PET_scan > 1.0, 1.0, PET_scan) PET_scan = np.where(PET_scan < 0.0, 0.0, PET_scan) # for CT visualisation CT_scan = np.where(CT_scan > 1.0, 1.0, CT_scan) CT_scan = np.where(CT_scan < 0.0, 0.0, CT_scan) # for correct visualisation PET_scan = np.flip(PET_scan, axis=0) CT_scan = np.flip(CT_scan, axis=0) PRED = np.flip(PRED, axis=0) # stacked projections PET_scan = np.hstack((np.amax(PET_scan, axis=1), np.amax(PET_scan, axis=2))) CT_scan = np.hstack( (np.amax(CT_scan, axis=1), np.amax(CT_scan, axis=2))) PRED = np.hstack((np.amax(PRED, axis=1), np.amax(PRED, axis=2))) ################################################################## f = plt.figure(figsize=(15, 10)) f.suptitle(splitext(basename(PET_id))[0], fontsize=15) plt.subplot(121) plt.imshow(CT_scan, cmap=color_CT, origin='lower') plt.imshow(PET_scan, cmap=color_PET, alpha=transparency, origin='lower') plt.axis('off') plt.title('PET/CT', fontsize=20) plt.subplot(122) plt.imshow(CT_scan, cmap=color_CT, origin='lower') plt.imshow(PET_scan, cmap=color_PET, alpha=transparency, origin='lower') plt.imshow(np.where(PRED, 0, np.nan), cmap=color_MASK, origin='lower') plt.axis('off') plt.title('Prediction', fontsize=20) pdf.savefig() # saves the current figure into a pdf page plt.close()
def POSTPROCESS(self, path_output, data_set_ids, prediction_ids, input_pixel_size, resize=True): """ Perform postprocessing on a prediction mask, based on data its corresponding data set TODO : /!\ by default postprocess to PET size TODO : /!\ add all header parameters when generating postprocess mask data_set_ids : [(PET_id_1,CT_id_1),(PET_id_2,CT_id_2)...] """ new_filenames = [] n_patient = len(data_set_ids) for i, (data_set_id, pred_id) in enumerate(zip(data_set_ids, prediction_ids)): display_loading_bar(iteration=i, length=n_patient, add_char=basename(data_set_id[0]) + ' ') # load data set PET_id, CT_id = data_set_id PET_img = sitk.ReadImage(PET_id, sitk.sitkFloat32) # gather input parameters PET_shape = list(PET_img.GetSize()) PET_shape.reverse() # axis order is reversed when img->array PET_pixelsize = list(PET_img.GetSpacing()) PET_pixelsize.reverse() # axis order is reversed when img->array # ordered as [z,y,x] prediction = sitk.GetArrayFromImage( sitk.ReadImage(pred_id, sitk.sitkUInt8)) if resize: prediction = isometric_resample( prediction, input_pixel_size=input_pixel_size, output_shape=PET_shape, output_pixel_size=PET_pixelsize, interpolation_order=0) # save postprocessed data new_filename = path_output + '/' + splitext( basename(pred_id))[0] + '.nii' # save spacing a.k.a pixel size in the file sitk_img = sitk.GetImageFromArray(prediction) sitk_img.SetSpacing(PET_pixelsize[::-1]) sitk.WriteImage(sitk_img, new_filename) new_filenames.append(new_filename) return new_filenames
def VISUALISATION_MIP_PREDICTION(self, path_output, data_set_ids, pred_ids, filename=None): """ Generate MIP projection of PET/CT files with its predicted mask data_set_ids : [(PET_id_1,CT_id_1),(PET_id_2,CT_id_2)...] """ if filename is None: filename = path_output + "/PETCT_MIP_" + time.strftime( "%m%d%H%M%S") + ".pdf" else: filename = path_output + '/' + filename # generates folder if not os.path.exists(path_output): os.makedirs(path_output) n_patients = len(data_set_ids) transparency = 0.7 color_CT = plt.cm.gray color_PET = plt.cm.plasma color_MASK = copy(plt.cm.Greys) color_MASK.set_bad('white', 0.0) with PdfPages(filename) as pdf: ############################ BOXPLOTS GENERATION ############################################# # get boxplots num_class = len(self.labels_numbers) # initialize values board Conf = np.zeros((num_class, num_class), dtype=np.int32) TruePos = [] GTsum = [] PRsum = [] TruePos, GTsum, PRsum = self.compute_metrics( data_set_ids, pred_ids) accuracy_TAB = TruePos / PRsum dice_TAB = (2 * TruePos + 0.1) / (GTsum + PRsum + 0.1) f = plt.figure(figsize=(15, 10)) f.suptitle('Metrics evaluation', fontsize=15) plt.subplot(121) plt.boxplot(accuracy_TAB[:, :], sym='x', whis=5, labels=self.labels_names) accuracy_median_tumor = np.median(accuracy_TAB[:, 1]) plt.ylim(0.1) plt.title("Accuracy Boxplot : tumor=%5.3f" % accuracy_median_tumor, fontsize=15) plt.subplot(122) plt.boxplot(dice_TAB[:, :], sym='x', whis=5, labels=self.labels_names) dice_median_tumor = np.median(dice_TAB[:, 1]) plt.ylim(0.1) plt.title("Dice Boxplot : tumor=%5.3f" % dice_median_tumor, fontsize=15) pdf.savefig() # saves the current figure into a pdf page plt.close() ############################# MIP GENERATION ################################################ # loop on files to get MIP visualisation for i, (DataSet_id, Pred_id) in enumerate(zip(data_set_ids, pred_ids)): display_loading_bar(iteration=i, length=n_patients, add_char=basename(DataSet_id[0]) + ' ') # load imgs PET_id, CT_id, Mask_id = DataSet_id PET_scan = sitk.GetArrayFromImage(sitk.ReadImage(PET_id)) CT_scan = sitk.GetArrayFromImage(sitk.ReadImage(CT_id)) MASK = sitk.GetArrayFromImage(sitk.ReadImage(Mask_id)) PRED = sitk.GetArrayFromImage(sitk.ReadImage(Pred_id)) # for TEP visualisation PET_scan = np.where(PET_scan > 1.0, 1.0, PET_scan) PET_scan = np.where(PET_scan < 0.0, 0.0, PET_scan) # for CT visualisation CT_scan = np.where(CT_scan > 1.0, 1.0, CT_scan) CT_scan = np.where(CT_scan < 0.0, 0.0, CT_scan) # for correct visualisation PET_scan = np.flip(PET_scan, axis=0) CT_scan = np.flip(CT_scan, axis=0) MASK = np.flip(MASK, axis=0) PRED = np.flip(PRED, axis=0) # stacked projections PET_scan = np.hstack((np.amax(PET_scan, axis=1), np.amax(PET_scan, axis=2))) CT_scan = np.hstack( (np.amax(CT_scan, axis=1), np.amax(CT_scan, axis=2))) MASK = np.hstack((np.amax(MASK, axis=1), np.amax(MASK, axis=2))) PRED = np.hstack((np.amax(PRED, axis=1), np.amax(PRED, axis=2))) ################################################################## f = plt.figure(figsize=(15, 10)) f.suptitle(splitext(basename(PET_id))[0], fontsize=15) plt.subplot(121) plt.imshow(CT_scan, cmap=color_CT, origin='lower') plt.imshow(PET_scan, cmap=color_PET, alpha=transparency, origin='lower') plt.imshow(np.where(MASK, 0, np.nan), cmap=color_MASK, origin='lower') plt.axis('off') plt.title('Ground Truth', fontsize=20) plt.subplot(122) plt.imshow(CT_scan, cmap=color_CT, origin='lower') plt.imshow(PET_scan, cmap=color_PET, alpha=transparency, origin='lower') plt.imshow(np.where(PRED, 0, np.nan), cmap=color_MASK, origin='lower') plt.axis('off') plt.title('Prediction', fontsize=20) pdf.savefig() # saves the current figure into a pdf page plt.close()