예제 #1
0
def test_n2v_creation(N2V, module, workspace):

    module.x_name.value = 'example'
    module.ml_model.value = 'Default Input Folder sub-folder|Documents/CellProfiler/data/n2v_3D'
    module.run(workspace)

    # TODO check if this is multiplatform compatible
    N2V.assert_called_with(None, 'n2v_3D',
                           '/home/nesta/Documents/CellProfiler/data')
예제 #2
0
파일: denoise.py 프로젝트: Asashou/TLI
def N2V_predict(model_name,
                model_path,
                n_tile=(2, 4, 4),
                xy_pixel=1,
                z_pixel=1,
                image=0,
                file='',
                save=True,
                save_path='',
                save_file=''):
    """apply N2V prediction on image based on provided model
    if save is True, save predicted image with provided info"""
    if file != '':
        image = tif.imread(file)
    file_name = os.path.basename(file)
    model = N2V(config=None, name=model_name, basedir=model_path)
    predict = model.predict(image, axes='ZYX', n_tiles=n_tile)
    # if predict.min() != 0:
    #     predict = datautils.img_limits(predict, limit=0)
    if save == True:
        if save_path != '' and save_path[-1] != '/':
            save_path += '/'
        if save_file == '':
            save_name = str(save_path + 'N2V_' + file_name)
        else:
            save_name = str(save_path + 'N2V_' + save_file)
        if '.tif' not in save_name:
            save_name += '.tif'
        datautils.save_image(save_name,
                             predict,
                             xy_pixel=xy_pixel,
                             z_pixel=z_pixel)
    return predict
예제 #3
0
파일: denoise.py 프로젝트: Asashou/TLI
def N2V_4D(image_4D,
           model_name,
           model_path,
           n_tile=(2, 4, 4),
           xy_pixel=1,
           z_pixel=1,
           save=True,
           save_path='',
           save_file=''):
    model = N2V(config=None, name=model_name, basedir=model_path)
    for st in tqdm(range(len(image_4D)), desc='applying N2V'):
        image_4D[st] = model.predict(image_4D[st], axes='ZYX', n_tiles=n_tile)
    if save == True:
        if save_path != '' and save_path[-1] != '/':
            save_path += '/'
        if save_file == '':
            save_name = str(save_path + 'N2V_4D.tif')
        else:
            save_name = str(save_path + 'N2V_' + save_file)
        if '.tif' not in save_name:
            save_name += '.tif'
        datautils.save_image(save_name,
                             image_4D,
                             xy_pixel=xy_pixel,
                             z_pixel=z_pixel)
    return image_4D
예제 #4
0
def predict(name, datastore):
    """
    Prediction generator using specified model.

    Args:
        name (str): model name
        datastore (Datastore): input datastore
    """
    model = N2V(config=None, name=name, basedir=model_dir())

    root = datastore.root + "_n2v"
    for key, data_in in datastore.items():
        yield model.predict(data_in, axes="ZYX")
예제 #5
0
파일: n2v.py 프로젝트: Natuy/dl4mic
 def predict(self, inputFolder, outputFolder):
     self.model = N2V(None, self.name, basedir=self.path)
     for r, d, f in os.walk(inputFolder):
         for file in f:
             base_filename = os.path.basename(file)
             input_train = imread(os.path.join(r, file))
             pred_train = self.model.predict(input_train,
                                             axes='YX',
                                             n_tiles=(2, 1))
             save_tiff_imagej_compatible(os.path.join(
                 outputFolder, base_filename),
                                         pred_train,
                                         axes='YX')
     print("Images saved into folder:", outputFolder)
예제 #6
0
파일: n2v.py 프로젝트: sommerc/careless
def predict(files, n_tiles=(1,4,4), params=params):
    from n2v.models import N2V

    files = [f.strip() for f in files.split(";")]
    datagen = BFListReader()
    datagen.from_file_list(files)

    axes = datagen.check_dims_equal()
    axes = axes.replace("T", "").replace("C","")

    assert axes == params["axes"], "The files to predict have different dimensionality: {} != {}".format(axes, params["axes"])

    print("Predicting ...")
    for c in params["train_channels"]:
        imgs = datagen.load_imgs_generator()
        print("  -- Channel {}".format(c))

        img_ch = (im[..., c:c+1] for im in imgs)
        # a name used to identify the model
        model_name = '{}_ch{}'.format(params['name'], c)
        # We are now creating our network model.
        model = N2V(config=None, name=model_name, basedir=params["in_dir"])

        for f, im in zip(files, img_ch):
            print("  -- {}".format(f))
            pixel_reso = get_space_time_resolution(str(f))
            res_img = []
            for t in range(len(im)):
                nt = n_tiles if "Z" in params["axes"] else n_tiles[1:]
                pred = model.predict(im[t,..., 0], axes=params["axes"], n_tiles=nt)

                if "Z" in params["axes"]:
                    pred = pred[:, None, ...]
                res_img.append(pred)

            pred = numpy.stack(res_img)
            if "Z" not in params["axes"]:
                    pred = pred[:, None, None, ...]

            reso      = (1 / pixel_reso.X, 1 / pixel_reso.Y )
            spacing   = pixel_reso.Z
            unit      = pixel_reso.Xunit
            finterval = pixel_reso.T

            tifffile.imsave("{}_n2v_pred_ch{}.tiff".format(str(f)[:-4], c), pred, imagej=True, resolution=reso, metadata={'axes': 'TZCYX',
                                                                                                'finterval': finterval,
                                                                                                'spacing'  : spacing,
                                                                                                'unit'     : unit})
예제 #7
0
def train(
    image,
    patch_shape=(16, 32, 32),
    ratio=0.7,
    name="untitled",
    model_dir=".",
    view_history=True,
):
    # create data generator object
    datagen = N2V_DataGenerator()

    # patch additional axes
    image = image[np.newaxis, ..., np.newaxis]

    patches = datagen.generate_patches_from_list([image], shape=patch_shape)
    logger.info(f"patch shape: {patches.shape}")
    n_patches = patches.shape[0]
    logger.info(f"{n_patches} patches generated")

    # split training set and validation set
    i = int(n_patches * ratio)
    X, X_val = patches[:i], patches[i:]

    # create training config
    config = N2VConfig(
        X,
        unet_kern_size=3,
        train_steps_per_epoch=100,
        train_epochs=100,
        train_loss="mse",
        batch_norm=True,
        train_batch_size=4,
        n2v_perc_pix=1.6,
        n2v_patch_shape=patch_shape,
        n2v_manipulator="uniform_withCP",
        n2v_neighborhood_radius=5,
    )

    model = N2V(config=config, name=name, basedir=model_dir)

    # train and save the model
    history = model.train(X, X_val)
    model.export_TF()

    plot_history(history, ["loss", "val_loss"])
    def denoise(self, pixels, ml_model,  final_tile_choice, color, axes):

        path = self.ml_model.get_absolute_path()
        (basedir, model_name) = split(path)

        try:
            model = N2V(config=None, name=model_name, basedir=basedir)
        except FileNotFoundError as e:
            raise FileNotFoundError(
                'Path ' + path + ' doesn\'t lead to valid model') from e
        if self.manual_slicing:
            tile_tuple = self.convert_string_to_tuple(final_tile_choice)
        if color or not self.manual_slicing or tile_tuple == None:
            axes = self.adjust_for_color(axes)
            pred = model.predict(pixels, axes=axes)
        else:
            pred = model.predict(pixels, axes=axes, n_tiles=tile_tuple)
        return pred
예제 #9
0
def N2V_predict(model_name, model_path, xy_pixel, z_pixel, image=0, file='', save=True, save_path='', save_file=''):
    """apply N2V prediction on image based on provided model
    if save is True, save predicted image with provided info"""
    if file != '':
        image = Image.open(file)
        image = np.array(image)
    file_name = os.path.basename(file)
    model = N2V(config=None, name=model_name, basedir=model_path)
    predict = model.predict(image, axes='ZYX', n_tiles=None)
    if save == True:
        if save_file == '':
            save_name = str(save_path+'N2V_'+file_name)
        else:
            save_name = str(save_path+'N2V_'+save_file)
        if '.tif' not in save_name:
            save_name +='.tif'
        img_save = img_limits(predict)
        save_image(save_name, img_save, xy_pixel=xy_pixel, z_pixel=z_pixel)
    return predict
예제 #10
0
파일: n2v.py 프로젝트: Natuy/dl4mic
 def __prepareData(self):
     # split patches from the training images
     data = self.dataGen.generate_patches_from_list(
         self.getTrainingImages(),
         shape=(self.patchSize, self.patchSize),
         augment=self.dataAugmentationActivated)
     # create a threshold (10 % patches for the validation)
     threshold = int(data.shape[0] * (self.percentValidation / 100))
     # split the patches into training patches and validation patches
     self.trainingData = data[threshold:]
     self.validationData = data[:threshold]
     if not self.numberOfSteps:
         self.numberOfSteps = int(
             self.trainingData.shape[0] / self.batchSize) + 1
     print(data.shape[0], "patches created.")
     print(threshold, "patch images for validation (",
           self.percentValidation, "%).")
     print(self.trainingData.shape[0] - threshold,
           "patch images for training.")
     print(self.numberOfSteps)
     # noinspection PyTypeChecker
     self.config = N2VConfig(self.trainingData,
                             unet_kern_size=self.kernelSize,
                             train_steps_per_epoch=self.numberOfSteps,
                             train_epochs=self.numberOfEpochs,
                             train_loss='mse',
                             batch_norm=True,
                             train_batch_size=self.batchSize,
                             n2v_patch_shape=(self.patchSize,
                                              self.patchSize),
                             n2v_perc_pix=self.percentPixel,
                             n2v_manipulator='uniform_withCP',
                             unet_n_depth=self.netDepth,
                             unet_n_first=self.uNetNFirst,
                             train_learning_rate=self.initialLearningRate,
                             n2v_neighborhood_radius=5)
     print(vars(self.config))
     self.model = N2V(self.config, self.name, basedir=self.path)
     print("Setup done.")
     print(self.config)
예제 #11
0
#plt.title('Validation Patch')
#plt.show()

# You can increase "train_steps_per_epoch" to get even better results at the price of longer computation
config = N2VConfig(X,
                   unet_kern_size=3,
                   unet_n_first=64,
                   unet_n_depth=3,
                   train_steps_per_epoch=5,
                   train_epochs=25,
                   train_loss='mse',
                   batch_norm=True,
                   train_batch_size=128,
                   n2v_perc_pix=5,
                   n2v_patch_shape=(64, 64),
                   n2v_manipulator='uniform_withCP',
                   n2v_neighborhood_radius=5)
vars(config)

# name used to identify the model
model_name = 'n2v_2D_RGB'
# the base directory in which our model will live
basedir = 'models'
# We are now creating our network model
model = N2V(config, model_name, basedir=basedir)
history = model.train(X, X_val)
print(sorted(list(history.history.keys())))
#plt.figure(figsize=(16,5))
#plot_history(history,['loss','val_loss'])
#plt.show()
예제 #12
0
파일: n2v.py 프로젝트: sommerc/careless
def train_predict(n_tiles=(1,4,4), params=params, files=None, headless=False, **unet_config):
    """
    These advanced options can be set by keyword arguments:

    n_tiles : tuple(int)
        Number of tiles to tile the image into, if it is too large for memory.
    unet_residual : bool
        Parameter `residual` of :func:`n2v_old.nets.common_unet`. Default: ``n_channel_in == n_channel_out``
    unet_n_depth : int
        Parameter `n_depth` of :func:`n2v_old.nets.common_unet`. Default: ``2``
    unet_kern_size : int
        Parameter `kern_size` of :func:`n2v_old.nets.common_unet`. Default: ``5 if n_dim==2 else 3``
    unet_n_first : int
        Parameter `n_first` of :func:`n2v_old.nets.common_unet`. Default: ``32``
    batch_norm : bool
        Activate batch norm
    unet_last_activation : str
        Parameter `last_activation` of :func:`n2v_old.nets.common_unet`. Default: ``linear``
    train_learning_rate : float
        Learning rate for training. Default: ``0.0004``
    n2v_patch_shape : tuple
        Random patches of this shape are extracted from the given training data. Default: ``(64, 64) if n_dim==2 else (64, 64, 64)``
    n2v_manipulator : str
        Noise2Void pixel value manipulator. Default: ``uniform_withCP``
    train_reduce_lr : dict
        Parameter :class:`dict` of ReduceLROnPlateau_ callback; set to ``None`` to disable. Default: ``{'factor': 0.5, 'patience': 10}``
    n2v_manipulator : str
        Noise2Void pixel value manipulator. Default: ``uniform_withCP``
    """
    from n2v.models import N2VConfig, N2V

    from n2v.utils.n2v_utils import manipulate_val_data
    from n2v.internals.N2V_DataGenerator import N2V_DataGenerator

    if not headless:
        from csbdeep.utils import plot_history
        from matplotlib import pyplot as plt

    np = numpy

    # Init reader
    datagen = BFListReader()
    print("Loading images ...")
    if files is None:
        datagen.from_glob(params["in_dir"], params["glob"])
        files = datagen.get_file_names()
    else:
        datagen.from_file_list(files)


    print("Training ...")
    for c in params["train_channels"]:
        print("  -- Channel {}".format(c))

        imgs_for_patches = datagen.load_imgs_generator()
        imgs_for_predict = datagen.load_imgs_generator()

        img_ch = (im[..., c:c+1] for im in imgs_for_patches)
        img_ch_predict = (im[..., c:c+1] for im in imgs_for_predict)

        npatches = params["n_patches_per_image"] if params["n_patches_per_image"] > 1 else None

        patches = N2V_DataGenerator().generate_patches_from_list(img_ch, num_patches_per_img=npatches, shape=params['patch_size'], augment=params['augment'])

        numpy.random.shuffle(patches)

        sep = int(len(patches)*0.9)
        X     = patches[:sep]
        X_val = patches[ sep:]

        config = N2VConfig(X,
                        train_steps_per_epoch=params["train_steps_per_epoch"],
                        train_epochs=params["train_epochs"],
                        train_loss='mse',
                        train_batch_size=params["train_batch_size"],
                        n2v_perc_pix=params["n2v_perc_pix"],
                        n2v_patch_shape=params['patch_size'],
                        n2v_manipulator='uniform_withCP',
                        n2v_neighborhood_radius=params["n2v_neighborhood_radius"], **unet_config)


        # a name used to identify the model
        model_name = '{}_ch{}'.format(params['name'], c)
        # the base directory in which our model will live
        basedir = 'models'
        # We are now creating our network model.
        model = N2V(config=config, name=model_name, basedir=params["in_dir"])

        history = model.train(X, X_val)


        val_patch = X_val[0,..., 0]
        val_patch_pred = model.predict(val_patch, axes=params["axes"])


        if "Z" in params["axes"]:
            val_patch      = val_patch.max(0)
            val_patch_pred = val_patch_pred.max(0)

        if not headless:
            f, ax = plt.subplots(1,2, figsize=(14,7))
            ax[0].imshow(val_patch,cmap='gray')
            ax[0].set_title('Validation Patch')
            ax[1].imshow(val_patch_pred,cmap='gray')
            ax[1].set_title('Validation Patch N2V')


            plt.figure(figsize=(16,5))
            plot_history(history,['loss','val_loss'])

        print("  -- Predicting channel {}".format(c))
        for f, im in zip(files, img_ch_predict):
            print("  -- {}".format(f))
            pixel_reso = get_space_time_resolution(str(f))
            res_img = []
            for t in range(len(im)):
                nt = n_tiles if "Z" in params["axes"] else n_tiles[1:]
                pred = model.predict(im[t,..., 0], axes=params["axes"], n_tiles=nt)

                if "Z" in params["axes"]:
                    pred = pred[:, None, ...]
                res_img.append(pred)

            pred = numpy.stack(res_img)
            if "Z" not in params["axes"]:
                    pred = pred[:, None,     None, ...]

            reso      = (1 / pixel_reso.X, 1 / pixel_reso.Y )
            spacing   = pixel_reso.Z
            unit      = pixel_reso.Xunit
            finterval = pixel_reso.T

            tifffile.imsave("{}_n2v_pred_ch{}.tiff".format(str(f)[:-4], c), pred, imagej=True, resolution=reso, metadata={'axes': 'TZCYX',
                                                                                                'finterval': finterval,
                                                                                                'spacing'  : spacing,
                                                                                                'unit'     : unit})
예제 #13
0
# IMPORTANT!! I add clip
X = np.round(np.clip(X, 0, 255.))
X_val = np.round(np.clip(X_val, 0, 255.))


config = N2VConfig(X, unet_kern_size=3,
                   train_steps_per_epoch=400, train_epochs=200, train_loss='mse', batch_norm=True,
                   train_batch_size=args.batch_size, n2v_perc_pix=args.perc_pix,
                   n2v_patch_shape=(args.patch_size, args.patch_size),
                   unet_n_first=96,
                   unet_residual=True,
                   n2v_manipulator='uniform_withCP', n2v_neighborhood_radius=2)
vars(config)

model = N2V(config, args.exp_name)
model.prepare_for_training(metrics=())


groundtruth_data = np.load('data/BSD68_reproducibility_data/test/bsd68_groundtruth.npy', allow_pickle=True)

# In[12]:


test_data = np.load('data/BSD68_reproducibility_data/test/bsd68_gaussian25.npy', allow_pickle=True)
# In[13]:
# In[13]:

from skimage.measure import compare_psnr, compare_ssim
import cv2
예제 #14
0
# Let's look at two patches
#plt.figure(figsize=(14,7))
#plt.subplot(1,2,1)
#plt.imshow(X[0,16,...,0],cmap='magma')
#plt.title('Training Patch')
#plt.subplot(1,2,2)
#plt.imshow(X_val[0,16,...,0],cmap='magma')
#plt.title('Validation Patch')
#plt.show()

# You can increase "train_steps_per_epoch" to get even better results at the price of longer computation.
config = N2VConfig(X, unet_kern_size=3,
    train_steps_per_epoch=100, train_epochs=10, train_loss='mse', batch_norm=True,
    train_batch_size=4, n2v_perc_pix=1.6, n2v_patch_shape=(32, 64, 64),
    n2v_manipulator='uniform_withCP', n2v_neighborhood_radius=5)
# Let's look at the parameters stored in the config-object.
vars(config)

# a name used to identify the model
model_name = 'n2v_3D'
# the base directory in which our model will live
basedir = 'models'
# We are now creating our network model
model = N2V(config=config, name=model_name, basedir=basedir)

history = model.train(X, X_val)
print(sorted(list(history.history.keys())))
#plt.figure(figsize=(16,5))
#plot_history(history,['loss','val_loss'])
#plt.show()
예제 #15
0
# default = 32,64,64
patches = datagen.generate_patches_from_list(imgs[:1], shape=(32, 64, 64))

# default = :600
X = patches[:600]
X_val = patches[600:]
numberEpochs = 20
config = N2VConfig(X,
                   unet_kern_size=3,
                   train_steps_per_epoch=int(X.shape[0] / 128),
                   train_epochs=numberEpochs,
                   train_loss='mse',
                   batch_norm=True,
                   train_batch_size=4,
                   n2v_perc_pix=0.198,
                   n2v_patch_shape=(32, 64, 64),
                   n2v_manipulator='uniform_withCP',
                   n2v_neighborhood_radius=5)
vars(config)
model_name = '20epoch'
model = N2V(config=config, name=model_name, basedir=image_path)
history = model.train(X, X_val)
print(sorted(list(history.history.keys())))
model.export_TF()

# Load the image, and predict the denoised image.
img = imread(os.path.join(image_path, image_name))
pred = model.predict(img, axes='ZYX', n_tiles=(2, 4, 4))
save_tiff_imagej_compatible(os.path.join(image_path, 'denoised.tif'), pred,
                            'ZYX')
예제 #16
0
#!/usr/bin/env python
# Noise2Void - 2D Example for SEM data
from n2v.models import N2V
import numpy as np
from matplotlib import pyplot as plt
from tifffile import imread
from csbdeep.io import save_tiff_imagej_compatible

# A previously trained model is loaded by creating a new N2V-object without providing a 'config'.
model_name = 'n2v_2D_SEM'
basedir = 'models'
model = N2V(config=None, name=model_name, basedir=basedir)

input_train = imread('data/train.tif')
input_val = imread('data/validation.tif')
pred_train = model.predict(input_train, axes='YX', n_tiles=(2, 1))
pred_val = model.predict(input_val, axes='YX')

#plt.figure(figsize=(16,8))
#plt.subplot(1,2,1)
#plt.imshow(input_train[:1500:,:1500],cmap="magma")
#plt.title('Input');
#plt.subplot(1,2,2)
#plt.imshow(pred_train[:1500,:1500],cmap="magma")
#plt.title('Prediction')
#plt.show()

# Let's look at the results
#plt.figure(figsize=(16,8))
#plt.subplot(1,2,1)
#plt.imshow(input_val,cmap="magma")
예제 #17
0
def infer(images, name="untitled", model_dir="."):
    model = N2V(config=None, name=name, basedir=model_dir)

    for image in images:
        yield model.predict(image, axes="ZYX")
예제 #18
0
config = N2VConfig(X,
                   unet_kern_size=3,
                   train_steps_per_epoch=400,
                   train_epochs=200,
                   train_loss='mse',
                   batch_norm=True,
                   train_batch_size=args.batch_size,
                   n2v_perc_pix=args.perc_pix,
                   n2v_patch_shape=(args.patch_size, args.patch_size),
                   unet_n_first=96,
                   unet_residual=True,
                   n2v_manipulator='uniform_withCP',
                   n2v_neighborhood_radius=2)
vars(config)

model = N2V(config, args.exp_name, basedir=args.ckpt_dir)
model.prepare_for_training(metrics=())

# We are ready to start training now.
history = model.train(X, X_val)
#
#
# # ### After training, lets plot training and validation loss.
#
# # In[10]:
#
#
# print(sorted(list(history.history.keys())))
# plt.figure(figsize=(16,5))
# plot_history(history,['loss','val_loss']);
예제 #19
0
파일: evaluate.py 프로젝트: Natuy/dl4mic
def main(argv):
    parser = ParserCreator.createArgumentParser("./evaluate.yml")
    if len(argv) == 1:
        parser.print_help(sys.stderr)
        sys.exit(1)
    args = parser.parse_args(argv[1:])
    print(args)

    Source_QC_folder = args.testInputPath
    Target_QC_folder = args.testGroundTruthPath
    QC_model_path = args.baseDir
    QC_model_name = args.name

    # Create a quality control/Prediction Folder
    if os.path.exists(QC_model_path + "/" + QC_model_name +
                      "/Quality Control/Prediction"):
        shutil.rmtree(QC_model_path + "/" + QC_model_name +
                      "/Quality Control/Prediction")

    os.makedirs(QC_model_path + "/" + QC_model_name +
                "/Quality Control/Prediction")

    # Activate the pretrained model.
    model_training = N2V(config=None,
                         name=QC_model_name,
                         basedir=QC_model_path)

    # List Tif images in Source_QC_folder
    Source_QC_folder_tif = Source_QC_folder + "/*.tif"
    Z = sorted(glob(Source_QC_folder_tif))
    Z = list(map(imread, Z))

    print('Number of test dataset found in the folder: ' + str(len(Z)))

    # Perform prediction on all datasets in the Source_QC folder
    for filename in os.listdir(Source_QC_folder):
        img = imread(os.path.join(Source_QC_folder, filename))
        predicted = model_training.predict(img, axes='YX', n_tiles=(2, 1))
        #        os.chdir(QC_model_path+"/"+QC_model_name+"/Quality Control/Prediction")
        imsave(
            os.path.join(
                QC_model_path + "/" + QC_model_name +
                "/Quality Control/Prediction", filename), predicted)

    # Open and create the csv file that will contain all the QC metrics
    with open(QC_model_path+"/"+QC_model_name+"/Quality Control/QC_metrics_"+QC_model_name+".csv", "w", newline='') \
            as file:
        writer = csv.writer(file)

        # Write the header in the csv file
        writer.writerow([
            "image #", "Prediction v. GT mSSIM", "Input v. GT mSSIM",
            "Prediction v. GT NRMSE", "Input v. GT NRMSE"
        ])

        # Let's loop through the provided dataset in the QC folders
        for i in os.listdir(Source_QC_folder):
            if not os.path.isdir(os.path.join(Source_QC_folder, i)):
                print('Running QC on: ' + i)
                # -------------------------------- Target test data (Ground truth) --------------------------------
                test_GT = io.imread(os.path.join(Target_QC_folder, i))
                test_GT_norm = normalizeImageWithPercentile(
                    test_GT)  # For normalisation between 0 and 1.

                # -------------------------------- Source test data --------------------------------
                test_source = io.imread(os.path.join(Source_QC_folder, i))
                test_source_norm = normalizeImageWithPercentile(
                    test_source)  # For normalisation between 0 and 1.
                # Normalize the image further via linear regression wrt the normalised GT image
                test_source_norm = normalizeByLinearRegression(
                    test_source_norm, test_GT_norm)

                # -------------------------------- Prediction --------------------------------
                test_prediction = io.imread(
                    os.path.join(
                        QC_model_path + "/" + QC_model_name +
                        "/Quality Control/Prediction", i))
                test_prediction_norm = normalizeImageWithPercentile(
                    test_prediction)
                # For normalisation between 0 and 1.
                # Normalize the image further via linear regression wrt the normalised GT image
                test_prediction_norm = normalizeByLinearRegression(
                    test_prediction_norm, test_GT_norm)

                # -------------------------------- Calculate the metric maps and save them ----------------------------

                # Calculate the SSIM images based on the default window parameters defined in the function
                GTforSSIM = img_as_uint(clipImageMinAndMax(test_GT_norm, 0, 1),
                                        force_copy=True)
                PredictionForSSIM = img_as_uint(clipImageMinAndMax(
                    test_prediction_norm, 0, 1),
                                                force_copy=True)
                SourceForSSIM = img_as_uint(clipImageMinAndMax(
                    test_source_norm, 0, 1),
                                            force_copy=True)

                # Calculate the SSIM maps
                img_SSIM_GTvsPrediction = ssim(GTforSSIM, PredictionForSSIM)
                img_SSIM_GTvsSource = ssim(GTforSSIM, SourceForSSIM)

                # Save ssim_maps
                img_SSIM_GTvsPrediction_32bit = np.float32(
                    img_SSIM_GTvsPrediction)
                io.imsave(
                    QC_model_path + '/' + QC_model_name +
                    '/Quality Control/SSIM_GTvsPrediction_' + i,
                    img_SSIM_GTvsPrediction_32bit)
                img_SSIM_GTvsSource_32bit = np.float32(img_SSIM_GTvsSource)
                io.imsave(
                    QC_model_path + '/' + QC_model_name +
                    '/Quality Control/SSIM_GTvsSource_' + i,
                    img_SSIM_GTvsSource_32bit)

                # Calculate the Root Squared Error (RSE) maps
                img_RSE_GTvsPrediction = np.sqrt(
                    np.square(test_GT_norm - test_prediction_norm))
                img_RSE_GTvsSource = np.sqrt(
                    np.square(test_GT_norm - test_source_norm))

                # Save SE maps
                img_RSE_GTvsPrediction_32bit = np.float32(
                    img_RSE_GTvsPrediction)
                img_RSE_GTvsSource_32bit = np.float32(img_RSE_GTvsSource)
                io.imsave(
                    QC_model_path + '/' + QC_model_name +
                    '/Quality Control/RSE_GTvsPrediction_' + i,
                    img_RSE_GTvsPrediction_32bit)
                io.imsave(
                    QC_model_path + '/' + QC_model_name +
                    '/Quality Control/RSE_GTvsSource_' + i,
                    img_RSE_GTvsSource_32bit)

                # SAVE THE METRIC MAPS HERE #########
                # -------------------------------- Calculate the metrics and save them --------------------------------

                # Calculate the mean SSIM metric
                # SSIM_GTvsPrediction_metrics = np.mean(img_SSIM_GTvsPrediction) # THIS IS WRONG, please compute the
                # SSIM over the whole image and not in patches.
                # SSIM_GTvsSource_metrics = np.mean(img_SSIM_GTvsSource) # THIS IS WRONG, please compute the SSIM over
                # the whole image and not in patches.
                index_SSIM_GTvsPrediction = ssim_index(GTforSSIM,
                                                       PredictionForSSIM)
                index_SSIM_GTvsSource = ssim_index(GTforSSIM, SourceForSSIM)

                # Normalised Root Mean Squared Error (here it's valid to take the mean of the image)
                NRMSE_GTvsPrediction = np.sqrt(np.mean(img_RSE_GTvsPrediction))
                NRMSE_GTvsSource = np.sqrt(np.mean(img_RSE_GTvsSource))

                writer.writerow([
                    i,
                    str(index_SSIM_GTvsPrediction),
                    str(index_SSIM_GTvsSource),
                    str(NRMSE_GTvsPrediction),
                    str(NRMSE_GTvsSource)
                ])

    # All data is now processed saved
    Test_FileList = os.listdir(Source_QC_folder)  # this assumes, as it should,
    #                                               that both source and target are named the same
    print("---evaluation done---")