def save_metrics_images(data, metric_names, viz_obj: MedicalImageVisualizer):
    # ************** Plot and save Metrics for ROI *****************
    data.loc['AVG'] = data.mean()  # Compute all average values
    title = ''
    input_dics = []
    for c_metric in metric_names:
        title += F"{c_metric}: {data.loc['AVG'][c_metric]:.3f}"
        input_dics.append(data[c_metric].dropna().to_dict())

    viz_obj.plot_multiple_bar_plots(input_dics,
                                    title=title,
                                    legends=metric_names,
                                    file_name='Mean_Performance.png')
 def __init__(self, **kwargs):
     self.viz_obj = MedicalImageVisualizer(
         output_folder="/data/UM/COVID/PREPROC/2D/output_imgs",
         disp_images=False
     )  # TODO it should be a unique object but is not working
     # All the arguments that are passed to the constructor of the class MUST have its name on it.
     for arg_name, arg_value in kwargs.items():
         self.__dict__["_" + arg_name] = arg_value
def preprocess_imgs_and_ctrs(input_folder, output_folder, resampling,
                             img_names, ctr_names_orig, out_img_names,
                             out_ctr_names_orig, match_whole_w_ctr,
                             normalize_imgs, ctr_folder_names,
                             bias_corrections, fix_adc, options):
    """
    Generates nrrd files from dicom files. It does it for contours and series
    :param input_folder: Path to the DICOM files
    :param output_folder: Path to output nrrd files
    :param resampling: Array with 3 values indicating each resolution x,y,z
    :param img_names: Array Names of the images we want to transform
    :param ctr_names: Array Name of the contours we want to read
    :param out_img_names: Output img names
    :param out_ctr_names: Output ctr names
    :param match_whole_w_ctr: Bool array Indicate if we need to match the name of the contours exactly or as a RegEx
    :param normalize_imgs: Bool array Indicates if we need to perform percentile normalization to the images
    :param ctr_folder_names: Str Array With the name of the 'folder' names to search for contours
    :return:
    """
    viz_obj = MedicalImageVisualizer()

    ctr_names = ctr_names_orig.copy(
    )  # Patch to avoid problems with global variable
    out_ctr_names = out_ctr_names_orig.copy(
    )  # Patch to avoid problems with global variable

    create_folder(output_folder)

    # ******************** READS DATA *******************
    print('\tReading data....')

    [orig_imgs,
     final_img_names] = read_dicom_mri_series(input_folder, img_names,
                                              out_img_names)

    [orig_ctrs, final_ctr_names
     ] = read_rtstruct_mri_series(input_folder,
                                  ctr_folder_names=ctr_folder_names,
                                  in_ctr_names=ctr_names,
                                  out_ctr_names=out_ctr_names,
                                  ref_img_itk=orig_imgs[0],
                                  match_whole_word=match_whole_w_ctr)

    # Saves original images without bias correction
    write_itk_imgs(output_folder, 'img', orig_imgs, final_img_names)
    write_itk_imgs(output_folder, 'ctr', orig_ctrs, final_ctr_names)

    # ************** Correcting ADC intensities  *************
    for idx_fix_adc, c_fix_adc in enumerate(fix_adc):
        if c_fix_adc:
            print(
                '\tFixing ADC, changing "black" values on original images ....'
            )
            orig_imgs[idx_fix_adc] = correct_adc_itk(orig_imgs[idx_fix_adc])

    # ************** Normalize images (N4K bias correction) *************
    if options[PreprocParams.bias_correction]:
        print("\tBias correction.....")
        pretxt = 'img_n4k'
        for ii in range(len(orig_imgs)):
            if bias_corrections[ii]:
                # First try to read an existing file, if not, compute it
                file_name = join(
                    output_folder, '{}_{}.nrrd'.format(pretxt,
                                                       final_img_names[ii]))
                if exists(file_name):
                    print('\t\tReading previous n4k file...')
                    orig_imgs[ii] = sitk.ReadImage(file_name)
                else:
                    orig_imgs[ii] = n4itk(orig_imgs[ii])
        # Saving bias corrected images
        write_itk_imgs(output_folder, pretxt, orig_imgs, final_img_names)

    norm_perc = options[PreprocParams.normalize_percentiles]
    for idx_img in range(len(orig_imgs)):
        if normalize_imgs[idx_img]:
            print(F'\tNormalizing intensities ... {img_names[idx_img]}')
            orig_imgs[idx_img] = normalize_to_percentiles([orig_imgs[idx_img]],
                                                          norm_perc[0],
                                                          norm_perc[1])[0]

    # *********** Resample to [.5,.5,.5] and interpolate with optical flow ******************
    if options[PreprocParams.resample]:
        print("\tResampling .....")
        # viz_obj.plot_img_and_ctrs_itk(orig_imgs[0], orig_ctrs, slices=SliceMode.MIDDLE, title='Befor resampling')
        resampled_imgs, resampled_ctrs = reample_imgs_and_ctrs(
            orig_imgs, orig_ctrs, resampling)
        # viz_obj.plot_img_and_ctrs_itk(resampled_imgs[0], resampled_ctrs, slices=SliceMode.MIDDLE,title='RESAMPLED')
        if options[PreprocParams.optical_flow_ctr_interpolation]:
            print('\t\tOptical flow ....')
            resampled_ctrs = optical_flow_interpolation(resampled_ctrs)
        write_itk_imgs(output_folder, 'hr', resampled_imgs, final_img_names)
        write_itk_imgs(output_folder, 'hr_ctr', resampled_ctrs,
                       final_ctr_names)

    # *********** Crop and normalize to 0 and 1 ************
    if options[PreprocParams.compute_roi_from_intersection]:
        print("\tCropping.....")
        roi_imgs, roi_ctrs, startROI_final, sizeROI_final = getCroppedIsotropicImgsOZ(
            resampled_imgs, resampled_ctrs)

        if options[PreprocParams.smooth_ctrs]:
            print("\t\tSmoothing ctrs.....")
            # viz_obj.plot_img_and_ctrs_itk(roi_ctrs[0], slices=SliceMode.MIDDLE,title='Before smoothing')
            roi_ctrs = smoothContours(roi_ctrs)
            # viz_obj.plot_img_and_ctrs_itk(roi_ctrs[0], slices=SliceMode.MIDDLE,title='After smoothing')

        # Saves the size and start position of the ROI, used when running the model
        np.savetxt(join(output_folder, 'start_ROI.csv'), startROI_final)
        np.savetxt(join(output_folder, 'size_ROI.csv'), sizeROI_final)
        # Save the roi images
        write_itk_imgs(output_folder, 'roi', roi_imgs, final_img_names)
        write_itk_imgs(output_folder, 'roi_ctr', roi_ctrs, final_ctr_names)

    # viz_obj.plot_imgs_and_ctrs_itk(roi_imgs, roi_ctrs, slices=SliceMode.MIDDLE, title='Final ROIs')
    print("DONE!!!!...")
def preprocess_imgs(input_folder, output_folder, resampling, img_names,
                    out_img_names, normalize_imgs, bias_corrections, fix_adc,
                    options, save_imgs: bool):
    """
    Generates preprocessesd images only, this can be used when making classifications of the test
    dataset of the NN.
    :param input_folder: Path to the DICOM files
    :param output_folder: Path to output nrrd files
    :param resampling: Array with 3 values indicating each resolution x,y,z
    :param img_names: Array Names of the images we want to transform
    :param out_img_names: Output img names
    :param normalize_imgs: Bool array Indicates if we need to perform percentile normalization to the images
    :param save_imgs: Bool indicates if we need to save or not the output images
    :return:
    """
    viz_ob = MedicalImageVisualizer()
    create_folder(output_folder)

    # ******************** READS DATA *******************
    print('\tReading data....')

    [orig_imgs,
     final_img_names] = read_dicom_mri_series(input_folder, img_names,
                                              out_img_names)

    # Saves original images without bias correction
    if save_imgs:
        write_itk_imgs(output_folder, 'img', orig_imgs, final_img_names)

    if len(fix_adc) == len(orig_imgs):
        for idx_fix_adc, c_fix_adc in enumerate(fix_adc):
            if c_fix_adc:
                print(
                    '\tFixing ADC, changing "black" values on original images ....'
                )
                orig_imgs[idx_fix_adc] = correct_adc_itk(
                    orig_imgs[idx_fix_adc])
    else:
        print('\tNone ADC img is being fixed')

    # ************** Normalize images (N4K bias correction) *************
    if options[PreprocParams.bias_correction]:
        print("\tBias correction.....")
        pretxt = 'img_n4k'
        for ii in range(len(orig_imgs)):
            if bias_corrections[ii]:
                # First try to read an existing file, if not, compute it
                orig_imgs[ii] = n4itk(orig_imgs[ii])
        # Saving bias corrected images
        if save_imgs:
            write_itk_imgs(output_folder, pretxt, orig_imgs, final_img_names)

    norm_perc = options[PreprocParams.normalize_percentiles]
    for idx_img in range(len(orig_imgs)):
        if normalize_imgs[idx_img]:
            print(F'\tNormalizing intensities ... {img_names[idx_img]}')
            orig_imgs[idx_img] = normalize_to_percentiles([orig_imgs[idx_img]],
                                                          norm_perc[0],
                                                          norm_perc[1])[0]

    # *********** Resample to [.5,.5,.5] and interpolate with optical flow ******************
    if options[PreprocParams.resample]:
        print("\tResampling .....")
        # viz_obj.plot_img_and_ctrs_itk(orig_imgs[0], slices=SliceMode.MIDDLE,title='Befor resampling')
        resampled_imgs, _ = reample_imgs_and_ctrs(orig_imgs, [], resampling)
        # viz_obj.plot_img_and_ctrs_itk(resampled_imgs[0], slices=SliceMode.MIDDLE,title='RESAMPLED')
        if save_imgs:
            write_itk_imgs(output_folder, 'hr', resampled_imgs,
                           final_img_names)

    # *********** Crop and normalize to 0 and 1 ************
    if options[PreprocParams.compute_roi_from_intersection]:
        print("\tCropping.....")
        roi_imgs, _, startROI_final, sizeROI_final = getCroppedIsotropicImgsOZ(
            resampled_imgs, [])

        # Saves the size and start position of the ROI, used when running the model
        np.savetxt(join(output_folder, 'start_ROI.csv'), startROI_final)
        np.savetxt(join(output_folder, 'size_ROI.csv'), sizeROI_final)
        # Save the roi images
        if save_imgs:
            write_itk_imgs(output_folder, 'roi', roi_imgs, final_img_names)

    return orig_imgs, resampled_imgs, roi_imgs
Beispiel #5
0
 def __init__(self, **kwargs):
     self.viz_obj = MedicalImageVisualizer(disp_images=True)
     # All the arguments that are passed to the constructor of the class MUST have its name on it.
     for arg_name, arg_value in kwargs.items():
         self.__dict__["_" + arg_name] = arg_value
from Preproc.UtilsPreproc import resample_to_reference_itk
from preproc.UtilsItk import copyItkImage

# -------------- Test example -----------------
# input_image = sitk.ReadImage("/data/UM/COVID/Kaggle_Mosmed/studies/study_0001.nii")
# segmentation = mask.apply(input_image)  # default model is U-net(R231)
# viz_obj = MedicalImageVisualizer(disp_images=False, output_folder="/home/olmozavala/Dropbox/MyProjects/UM/Covid19_Prognosis/COVID_DL_Segmentation/LungSegmentationSoftware/OUTPUT")
# viz_obj.plot_img_and_ctrs_np(sitk.GetArrayFromImage(input_image), [segmentation],
#                               title="Test Lung seg")

# Visualizing Mosmed data
data_folder = "/data/UM/COVID/Kaggle_Mosmed"
output_folder = "/data/UM/COVID/Kaggle_Mosmed/lung_masks"

viz_obj = MedicalImageVisualizer(output_folder=join(data_folder,
                                                    "output_imgs"),
                                 disp_images=False)
mask_files = os.listdir(join(data_folder, "masks"))
mask_files.sort()
for c_mask_file_name in mask_files:
    c_case = int(c_mask_file_name.split("_")[1])
    c_img_file_name = F"study_0{c_case:03d}.nii"
    c_img_file = join(data_folder, "studies", c_img_file_name)
    print(F"--- Working with {c_img_file} ---")
    itk_img = sitk.ReadImage(c_img_file)

    np_lung_mask = mask.apply(itk_img)  # default model is U-net(R231)
    itk_lung_mask = copyItkImage(itk_img, np_lung_mask)
    viz_obj.plot_img_and_ctrs_itk(itk_img, [itk_lung_mask],
                                  title=c_img_file_name,
                                  draw_only_ctrs=True,
def make_3d_segmentation(config):
    """
    :param config:
    :return:
    """

    # *********** Reads the parameters ***********

    cases = config[ClassificationParams.cases]
    save_segmented_ctrs = config[ClassificationParams.save_segmented_ctrs]

    input_folder = config[ClassificationParams.input_folder]
    input_img_names = config[ClassificationParams.input_img_file_names]
    output_folder = config[ClassificationParams.output_folder]
    output_imgs_folder = config[ClassificationParams.output_imgs_folder]
    output_file_name = config[ClassificationParams.output_file_name]
    model_weights_file = config[ClassificationParams.model_weights_file]
    compute_metrics = config[ClassificationParams.compute_metrics]
    compute_original_resolution = config[
        ClassificationParams.compute_original_resolution]

    save_imgs = config[ClassificationParams.save_imgs]
    if save_imgs:
        save_imgs_planes = config[ClassificationParams.save_img_planes]
        save_imgs_slices = config[ClassificationParams.save_img_slices]

    # Builds the visualization object
    viz_obj = MedicalImageVisualizer(
        disp_images=config[ClassificationParams.show_imgs],
        output_folder=output_imgs_folder)

    if compute_metrics:
        output_ctr_file_names = config[
            ClassificationParams.output_ctr_file_names]
    else:
        output_ctr_file_names = []
    # *********** Chooses the proper model ***********
    print('Reading model ....')
    model = select_3d_model(config)

    # *********** Reads the weights***********
    print('Reading weights ....')
    model.load_weights(model_weights_file)

    examples = select_cases_from_folder(input_folder, cases)
    create_folder(output_imgs_folder)

    # *********** Makes a dataframe to contain the DSC information **********
    metrics_params = config[ClassificationParams.metrics]
    metrics_dict = {met.name: met.value for met in metrics_params}

    # Check if the output fiels already exist, in thtat case read the df from it.
    if os.path.exists(join(output_imgs_folder, output_file_name)):
        data = pd.read_csv(join(output_imgs_folder, output_file_name),
                           index_col=0)
    else:
        data_columns = list(metrics_dict.values())
        if compute_original_resolution:
            # In this case we add all the desired metrics, but append 'original at the beginnig'
            data_columns = {
                *data_columns,
                *[F'{ORIGINAL_TXT}_{col}' for col in data_columns]
            }
        data = DataFrame(index=examples, columns=data_columns)

    # *********** Iterates over each case *********
    segmentation_type = config[ClassificationParams.segmentation_type]
    for id_folder, current_folder in enumerate(examples):
        print(F'******* Computing folder {current_folder} ************')
        t0 = time.time()
        try:
            # -------------------- Reading data -------------
            print('\t Reading data....')
            # All these names are predefined, for any other 3d segmentation we will need to create a different configuration
            imgs_itk, ctrs_itk, size_roi, start_roi, _ = read_preproc_imgs_and_ctrs_itk(
                input_folder,
                folders_to_read=[current_folder],
                img_names=input_img_names,
                ctr_names=output_ctr_file_names)

            imgs_np = [sitk.GetArrayFromImage(c_img) for c_img in imgs_itk[0]
                       ]  # The 0 is because we read a single fold
            ctrs_np = [sitk.GetArrayFromImage(c_img) for c_img in ctrs_itk[0]]

            # If we want to visualize the input images
            # viz_obj.plot_imgs_and_ctrs_itk(imgs_itk[0], ctrs_itk=ctrs_itk[0])

            # ------------------- Making prediction -----------
            print('\t Making prediction....')
            input_array = format_for_nn_classification(imgs_np)
            output_nn_all = model.predict(input_array, verbose=1)
            output_nn_np = output_nn_all[0, :, :, :, 0]
            # For visualizing the output of the network
            # viz_obj.plot_img_and_ctrs_np(img_np=output_nn_np)

            # ------------------- Postprocessing -----------
            print('\t Postprocessing prediction....')
            threshold = .5
            output_nn_itk = copyItkImage(imgs_itk[0][0], output_nn_np)
            print(F'\t\t Threshold NN output to {threshold} ....')
            output_nn_itk = binaryThresholdImage(output_nn_itk, threshold)
            if segmentation_type == SegmentationTypes.PROSTATE or segmentation_type == SegmentationTypes.PZ:
                print(
                    F'\t\t Restricting to largest connected component only  ....'
                )
                output_nn_itk = getLargestConnectedComponents(output_nn_itk)
                output_nn_np = sitk.GetArrayViewFromImage(output_nn_itk)

            if compute_original_resolution:
                print('\t Recovering original resolution...')
                print('\t\t Reading original resolution images....')
                img_names = [
                    config[
                        ClassificationParams.resampled_resolution_image_name],
                    config[ClassificationParams.original_resolution_image_name]
                ]
                ctr_name = config[
                    ClassificationParams.original_resolution_ctr_name]
                imgs_itk_original_temp, ctrs_itk_original_temp, _, _, _ = read_preproc_imgs_and_ctrs_itk(
                    input_folder,
                    folders_to_read=[current_folder],
                    img_names=img_names,
                    ctr_names=[ctr_name])

                gt_ctr_original_itk = ctrs_itk_original_temp[0][
                    0]  # Retrieves the gt ctr at the original resolution
                img_original_resampled_itk = imgs_itk_original_temp[0][0]
                img_original_itk = imgs_itk_original_temp[0][1]
                print('\t\t Resampling to original....')
                output_nn_original_itk = recover_original_resolution(
                    roi_np=output_nn_np,
                    resampled_itk=img_original_resampled_itk,
                    original_itk=img_original_itk,
                    start_positions=start_roi[0],
                    size_roi=size_roi[0])
                output_nn_original_itk = binaryThresholdImage(
                    output_nn_original_itk, threshold)
                if segmentation_type == SegmentationTypes.PROSTATE or segmentation_type == SegmentationTypes.PZ:
                    print(
                        F'\t\t\t Restricting to largest connected component only  ....'
                    )
                    output_nn_original_itk = getLargestConnectedComponents(
                        output_nn_original_itk)
                    output_nn_original_np = sitk.GetArrayViewFromImage(
                        output_nn_original_itk)

            if save_segmented_ctrs:
                print('\t Saving Prediction...')
                create_folder(join(output_folder, current_folder))
                # TODO at some point we will need to see if we can output more than one ctr
                sitk.WriteImage(
                    output_nn_itk,
                    join(output_folder, current_folder,
                         output_ctr_file_names[0]))
                if compute_original_resolution:
                    sitk.WriteImage(
                        output_nn_original_itk,
                        join(output_folder, current_folder,
                             F'{ORIGINAL_TXT}_{output_ctr_file_names[0]}'))

            if compute_metrics:
                # Compute metrics
                print('\t Computing metrics....')
                for c_metric in metrics_params:  # Here we can add more metrics
                    if c_metric == ClassificationMetrics.DSC_3D:
                        metric_value = numpy_dice(output_nn_np, ctrs_np[0])
                        data.loc[current_folder][c_metric.value] = metric_value
                        print(F'\t\t ----- DSC: {metric_value:.3f} -----')
                        if compute_original_resolution:
                            metric_value = numpy_dice(
                                output_nn_original_np,
                                sitk.GetArrayViewFromImage(
                                    gt_ctr_original_itk))
                            data.loc[current_folder][
                                F'{ORIGINAL_TXT}_{c_metric.value}'] = metric_value
                            print(F'\t\t ----- DSC: {metric_value:.3f} -----')

                # Saving the results every 10 steps
                if id_folder % 10 == 0:
                    save_metrics_images(data,
                                        metric_names=list(
                                            metrics_dict.values()),
                                        viz_obj=viz_obj)
                    data.to_csv(join(output_folder, output_file_name))

            if save_imgs:
                print('\t Plotting images....')
                plot_intermediate_results(current_folder,
                                          data_columns,
                                          imgs_itk=imgs_itk[0],
                                          gt_ctr_itk=ctrs_itk[0][0],
                                          nn_ctr_itk=output_nn_itk,
                                          data=data,
                                          viz_obj=viz_obj,
                                          slices=save_imgs_slices,
                                          compute_metrics=compute_metrics)
                if compute_original_resolution:
                    plot_intermediate_results(
                        current_folder,
                        data_columns,
                        imgs_itk=[img_original_itk],
                        gt_ctr_itk=gt_ctr_original_itk,
                        nn_ctr_itk=output_nn_original_itk,
                        data=data,
                        viz_obj=viz_obj,
                        slices=save_imgs_slices,
                        compute_metrics=compute_metrics,
                        prefix_name=ORIGINAL_TXT)
        except Exception as e:
            print(
                "---------------------------- Failed {} error: {} ----------------"
                .format(current_folder, e))
        print(F'\t Done! Elapsed time {time.time()-t0:0.2f} seg')

    if compute_metrics:
        save_metrics_images(data,
                            metric_names=list(metrics_dict.values()),
                            viz_obj=viz_obj)
        data.to_csv(join(output_folder, output_file_name))
import inout.io_common
from img_viz.medical import MedicalImageVisualizer
from img_viz.constants import SliceMode

from os.path import join, isdir
import numpy as np
import inout.io_rt as io_rt
import SimpleITK as sitk
from preproc.constants import PreprocParams

viz_obj = MedicalImageVisualizer()


def validateFolders(folders_to_read, dicom_path, img_names, ctr_names):

    final_folders = []

    print("Validating folders.... be patient")
    folder_names = [
        join(dicom_path, 'Patient-{num:04d}'.format(num=f))
        for f in folders_to_read
    ]

    for idx, folder in enumerate(folder_names):
        try:
            for ctr in ctr_names:
                t = sitk.ReadImage(join(dicom_path, folder, ctr))

            for img in img_names:
                t = sitk.ReadImage(join(dicom_path, folder, img))
Beispiel #9
0
    :return:
    """
    img_np = sitk.GetArrayFromImage(img_itk)
    img_np_norm = correct_adc_np(img_np, low_threshold, max_value, fix_value)
    return copyItkImage(img_itk, img_np_norm)


# ================= Only for testing =====================
if __name__ == '__main__':
    from os.path import join

    file_name = join('..', 'imagevisualizer', 'test_data', 'input',
                     'Case-0001', 'img_adc.nrrd')
    print('Reading image....')
    img_itk = sitk.ReadImage(file_name)

    img_corrected_itk = correct_adc_itk(img_itk,
                                        low_threshold=1,
                                        max_value=4500,
                                        fix_value='mean')
    print('Plotting results....')
    viz_obj = MedicalImageVisualizer(disp_images=True)
    viz_obj.plot_img_and_ctrs_itk(img_itk,
                                  itk_ctrs=[],
                                  slices=SliceMode.MIDDLE,
                                  file_name_prefix='Original')
    viz_obj.plot_img_and_ctrs_itk(img_corrected_itk,
                                  itk_ctrs=[],
                                  slices=SliceMode.MIDDLE,
                                  file_name_prefix='Corrected')
Beispiel #10
0
def main():
    config = get_segmentation_2d_config()
    cases = config[ClassificationParams.cases]
    save_segmented_ctrs = config[ClassificationParams.save_segmented_ctrs]

    input_folder = config[ClassificationParams.input_folder]
    input_img_names = config[ClassificationParams.input_img_file_names]
    output_folder = config[ClassificationParams.output_folder]
    output_imgs_folder = config[ClassificationParams.output_imgs_folder]
    output_file_name = config[ClassificationParams.output_file_name]
    model_weights_file = config[ClassificationParams.model_weights_file]

    save_imgs = config[ClassificationParams.save_imgs]

    # Builds the visualization object
    viz_obj = MedicalImageVisualizer(
        disp_images=config[ClassificationParams.show_imgs],
        output_folder=output_imgs_folder)

    output_ctr_file_names = config[ClassificationParams.output_ctr_file_names]
    # *********** Chooses the proper model ***********
    print('Reading model ....')
    model = select_2d_model(config)

    # *********** Reads the weights***********
    print('Reading weights ....')
    model.load_weights(model_weights_file)

    examples = select_cases_from_folder(input_folder, cases)
    create_folder(output_imgs_folder)

    # *********** Makes a dataframe to contain the DSC information **********
    metrics_params = config[ClassificationParams.metrics]
    metrics_dict = {met.name: met.value for met in metrics_params}

    # Check if the output files already exist, in that case read the df from it.
    if os.path.exists(join(output_imgs_folder, output_file_name)):
        data = pd.read_csv(join(output_imgs_folder, output_file_name),
                           index_col=0)
    else:
        data_columns = list(metrics_dict.values())
        data = DataFrame(index=examples, columns=data_columns)

    # *********** Iterates over each case *********
    for id_folder, current_folder in enumerate(examples):
        print(F'******* Computing folder {current_folder} ************')
        t0 = time.time()
        try:
            # -------------------- Reading data -------------
            print('\t Reading data....')
            # All these names are predefined, for any other 3d segmentation we will need to create a different configuration
            all_imgs, all_ctrs, _, _ = read_preproc_imgs_and_ctrs_png(
                input_folder,
                folders_to_read=[current_folder],
                img_names=input_img_names,
                ctr_names=output_ctr_file_names)

            imgs_np = all_imgs[0]
            ctrs_lungs_np = all_ctrs[0][0].copy(
            )  # VERIFY THE ORDER IS THE SAME IN THE CONFIG FILE
            ctrs_lesion_np = all_ctrs[0][1].copy(
            )  # VERIFY THE ORDER IS THE SAME IN THE CONFIG FILE
            # If we want to visualize the input images
            # viz_obj.plot_imgs_and_ctrs_itk(img_np[0], ctrs_itk=ctrs_itk[0])

            # ------------------- Making prediction -----------
            print('\t Making prediction....')
            input_array = format_for_nn_classification(imgs_np)
            output_nn_all = model.predict(input_array, verbose=1)
            output_nn_np = output_nn_all[0, :, :, 0]
            output_nn_np[ctrs_lungs_np ==
                         0] = 0  # Making the prediction 0 outside the lungs
            # For visualizing the output of the network
            # viz_obj.plot_img_and_ctrs_np_2d(output_nn_np, np_ctrs=[], file_name_prefix=id_folder)

            # ------------------- Postprocessing -----------
            print('\t Postprocessing prediction....')
            threshold = .5
            print(F'\t\t Threshold NN output to {threshold} ....')
            output_nn_np[
                output_nn_np <=
                threshold] = 0  # Making the prediction 0 outside the lungs
            output_nn_np[
                output_nn_np >
                threshold] = 1  # Making the prediction 0 outside the lungs

            if save_segmented_ctrs:
                print('\t Saving Prediction...')
                create_folder(join(output_folder, current_folder))
                cv2.imwrite(
                    join(output_folder, current_folder,
                         output_ctr_file_names[0]),
                    cv2.convertScaleAbs(output_nn_np, alpha=(255.0)))

            # Compute metrics
            print('\t Computing metrics....')
            for c_metric in metrics_params:  # Here we can add more metrics
                if c_metric == ClassificationMetrics.DSC_2D:
                    metric_value = numpy_dice(output_nn_np, ctrs_lesion_np)
                    data.loc[current_folder][c_metric.value] = metric_value
                    print(F'\t\t ----- DSC: {metric_value:.3f} -----')

            # Saving the results every 10 steps
            if id_folder % 10 == 0:
                save_metrics_images(data,
                                    metric_names=list(metrics_dict.values()),
                                    viz_obj=viz_obj)
                data.to_csv(join(output_folder, output_file_name))

            if save_imgs:
                print('\t Plotting images....')
                plot_intermediate_results(current_folder,
                                          data_columns,
                                          img_np=imgs_np[0],
                                          gt_ctr_np=ctrs_lesion_np,
                                          nn_ctr_np=output_nn_np,
                                          data=data,
                                          viz_obj=viz_obj)

        except Exception as e:
            print(
                "---------------------------- Failed {} error: {} ----------------"
                .format(current_folder, e))
        print(F'\t Done! Elapsed time {time.time()-t0:0.2f} seg')

    save_metrics_images(data,
                        metric_names=list(metrics_dict.values()),
                        viz_obj=viz_obj)
    data.to_csv(join(output_folder, output_file_name))