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')
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
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
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")
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)
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})
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
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
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)
#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()
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})
# 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
# 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()
# 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')
#!/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")
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")
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']);
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---")