def __init__(self, valsetdir=None, gtvalsetdir=None, gray_mode=False, num_input_frames=NUMFRXSEQ_VAL): self.gray_mode = gray_mode # Look for subdirs with individual sequences seqs_dirs = sorted(glob.glob(os.path.join(valsetdir, VALSEQPATT))) # open individual sequences and append them to the sequence list sequences = [] for seq_dir in seqs_dirs: seq, _, _ = open_sequence(seq_dir, gray_mode, expand_if_needed=False, \ max_num_fr=num_input_frames) # seq is [num_frames, C, H, W] sequences.append(seq) self.sequences = sequences gts_dirs = sorted(glob.glob(os.path.join(gtvalsetdir, VALSEQPATT))) gts = [] for gt_dir in gts_dirs: gt, _, _ = open_sequence(gt_dir, gray_mode, expand_if_needed=False, \ max_num_fr=num_input_frames) # gt is [num_frames, C, H, W] gts.append(gt) self.gts = gts
def test_fastdvdnet(**args): """Denoises all sequences present in a given folder. Sequences must be stored as numbered image sequences. The different sequences must be stored in subfolders under the "test_path" folder. Inputs: args (dict) fields: "model_file": path to model "test_path": path to sequence to denoise "suffix": suffix to add to output name "max_num_fr_per_seq": max number of frames to load per sequence "noise_sigma": noise level used on test set "dont_save_results: if True, don't save output images "no_gpu": if True, run model on CPU "save_path": where to save outputs as png "gray": if True, perform denoising of grayscale images instead of RGB """ # Start time start_time = time.time() # If save_path does not exist, create it logger = init_logger_test(os.path.dirname(args['save_path'])) # Sets data type according to CPU or GPU modes if args['cuda']: device = torch.device('cuda') else: device = torch.device('cpu') # Create models print('Loading models ...') model_temp = FastDVDnet(num_input_frames=NUM_IN_FR_EXT) # Load saved weights state_temp_dict = torch.load(args['model_file']) if args['cuda']: device_ids = [0] model_temp = nn.DataParallel(model_temp, device_ids=device_ids).cuda() else: # CPU mode: remove the DataParallel wrapper state_temp_dict = remove_dataparallel_wrapper(state_temp_dict) model_temp.load_state_dict(state_temp_dict) # Sets the model in evaluation mode (e.g. it removes BN) model_temp.eval() with torch.no_grad(): # process data seq = open_sequence(args['test_path'], args['first'], args['last'], args['already_norm']) seq = torch.from_numpy(seq).to(device) seq_time = time.time() # Add noise if not args['already_noisy']: noise = torch.empty_like(seq).normal_( mean=0, std=args['noise_sigma']).to(device) seqn = seq + noise else: seqn = seq noisestd = torch.FloatTensor([args['noise_sigma']]).to(device) denframes = denoise_seq_fastdvdnet(seq=seqn, noise_std=noisestd, temp_psz=NUM_IN_FR_EXT, model_temporal=model_temp) # Compute PSNR and log it stop_time = time.time() psnr = compute_psnr(denframes.cpu().numpy(), seq.cpu().numpy(), 1.) psnr_noisy = compute_psnr(seqn.cpu().numpy().squeeze(), seq.cpu().numpy(), 1.) loadtime = (seq_time - start_time) runtime = (stop_time - seq_time) seq_length = seq.size()[0] logger.info("Finished denoising {}".format(args['test_path'])) logger.info( "\tDenoised {} frames in {:.3f}s, loaded seq in {:.3f}s".format( seq_length, runtime, loadtime)) logger.info("\tPSNR noisy {:.4f}dB, PSNR result {:.4f}dB".format( psnr_noisy, psnr)) # Save outputs if not args['dont_save_results']: # Save sequence save_out_seq(denframes.cpu(), args['save_path'], args['first']) # close logger close_logger(logger)
def test_dvdnet(**args): """Denoises all sequences present in a given folder. Sequences must be stored as numbered image sequences. The different sequences must be stored in subfolders under the "test_path" folder. Inputs: args (dict) fields: "model_spatial_file": path to model of the pretrained spatial denoiser "model_temp_file": path to model of the pretrained temporal denoiser "test_path": path to sequence to denoise "suffix": suffix to add to output name "max_num_fr_per_seq": max number of frames to load per sequence "noise_sigma": noise level used on test set "dont_save_results: if True, don't save output images "no_gpu": if True, run model on CPU "save_path": where to save outputs as png """ start_time = time.time() # If save_path does not exist, create it if not os.path.exists(args['save_path']): os.makedirs(args['save_path']) logger = init_logger_test(args['save_path']) # Sets data type according to CPU or GPU modes if args['cuda']: device = torch.device('cuda') else: device = torch.device('cpu') # Create models model_spa = DVDnet_spatial() model_temp = DVDnet_temporal(num_input_frames=NUM_IN_FRAMES) # Load saved weights state_spatial_dict = torch.load(args['model_spatial_file']) state_temp_dict = torch.load(args['model_temp_file']) if args['cuda']: device_ids = [0] model_spa = nn.DataParallel(model_spa, device_ids=device_ids).cuda() model_temp = nn.DataParallel(model_temp, device_ids=device_ids).cuda() else: # CPU mode: remove the DataParallel wrapper state_spatial_dict = remove_dataparallel_wrapper(state_spatial_dict) state_temp_dict = remove_dataparallel_wrapper(state_temp_dict) model_spa.load_state_dict(state_spatial_dict) model_temp.load_state_dict(state_temp_dict) # Sets the model in evaluation mode (e.g. it removes BN) model_spa.eval() model_temp.eval() with torch.no_grad(): # process data seq, _, _ = open_sequence(args['test_path'],\ False,\ expand_if_needed=False,\ max_num_fr=args['max_num_fr_per_seq']) seq = torch.from_numpy(seq[:, np.newaxis, :, :, :]).to(device) seqload_time = time.time() # Add noise noise = torch.empty_like(seq).normal_(mean=0, std=args['noise_sigma']).to(device) seqn = seq + noise noisestd = torch.FloatTensor([args['noise_sigma']]).to(device) denframes = denoise_seq_dvdnet(seq=seqn,\ noise_std=noisestd,\ temp_psz=NUM_IN_FRAMES,\ model_temporal=model_temp,\ model_spatial=model_spa,\ mc_algo=MC_ALGO) den_time = time.time() # Compute PSNR and log it psnr = batch_psnr(denframes, seq.squeeze(), 1.) psnr_noisy = batch_psnr(seqn.squeeze(), seq.squeeze(), 1.) print("\tPSNR on {} : {}\n".format(os.path.split(args['test_path'])[-1], psnr)) print("\tDenoising time: {:.2f}s".format(den_time - seqload_time)) print("\tSequence loaded in : {:.2f}s".format(seqload_time - start_time)) print("\tTotal time: {:.2f}s\n".format(den_time - start_time)) logger.info("%s, %s, PSNR noisy %fdB, PSNR %f dB" % \ (args['test_path'], args['suffix'], psnr_noisy, psnr)) # Save outputs if not args['dont_save_results']: # Save sequence save_out_seq(seqn, denframes, args['save_path'], int(args['noise_sigma']*255), \ args['suffix'], args['save_noisy']) # close logger close_logger(logger)
def test_fastdvdnet(**args): """Denoises all sequences present in a given folder. Sequences must be stored as numbered image sequences. The different sequences must be stored in subfolders under the "test_path" folder. Inputs: args (dict) fields: "model_file": path to model "test_path": path to sequence to denoise "suffix": suffix to add to output name "max_num_fr_per_seq": max number of frames to load per sequence "dont_save_results: if True, don't save output images "no_gpu": if True, run model on CPU "save_path": where to save outputs as png "gray": if True, perform denoising of grayscale images instead of RGB """ # Start time start_time = time.time() # If save_path does not exist, create it if not os.path.exists(args['save_path']): os.makedirs(args['save_path']) logger = init_logger_test(args['save_path']) # Sets data type according to CPU or GPU modes if args['cuda']: device = args['device_id'][0] else: device = torch.device('cpu') # Create models print('Loading models ...') model_temp = FastDVDnet(num_input_frames=NUM_IN_FR_EXT) # Load saved weights state_temp_dict = torch.load(args['model_file']) if args['cuda']: device_ids = args['device_id'] model_temp = nn.DataParallel(model_temp, device_ids=device_ids).cuda(device) else: # CPU mode: remove the DataParallel wrapper state_temp_dict = remove_dataparallel_wrapper(state_temp_dict) model_temp.load_state_dict(state_temp_dict) # Sets the model in evaluation mode (e.g. it removes BN) model_temp.eval() gt = None with torch.no_grad(): # process data seq, _, _ = open_sequence(args['test_path'], args['gray'], expand_if_needed=False, max_num_fr=args['max_num_fr_per_seq']) seq = torch.from_numpy(seq).to(device) seq_time = time.time() denframes = denoise_seq_fastdvdnet(seq=seq, temp_psz=NUM_IN_FR_EXT, model_temporal=model_temp) if args['gt_path'] is not None: gt, _, _ = open_sequence(args['gt_path'], args['gray'], expand_if_needed=False, max_num_fr=args['max_num_fr_per_seq']) gt = torch.from_numpy(gt).to(device) # Compute PSNR and log it stop_time = time.time() if gt is None: psnr = 0 psnr_noisy = 0 else: psnr = batch_psnr(denframes, gt, 1.) psnr_noisy = batch_psnr(seq.squeeze(), gt, 1.) loadtime = (seq_time - start_time) runtime = (stop_time - seq_time) seq_length = seq.size()[0] logger.info("Finished denoising {}".format(args['test_path'])) logger.info( "\tDenoised {} frames in {:.3f}s, loaded seq in {:.3f}s".format( seq_length, runtime, loadtime)) logger.info("\tPSNR noisy {:.4f}dB, PSNR result {:.4f}dB".format( psnr_noisy, psnr)) # Save outputs if not args['dont_save_results']: # Save sequence save_out_seq(seq, denframes, args['save_path'], 0, args['suffix'], args['save_noisy']) # close logger close_logger(logger)
def test_fastdvdnet(**args): """Denoises all sequences present in a given folder. Sequences must be stored as numbered image sequences. The different sequences must be stored in subfolders under the "test_path" folder. Inputs: args (dict) fields: "model_file": path to model "test_path": path to sequence to denoise "suffix": suffix to add to output name "max_num_fr_per_seq": max number of frames to load per sequence "noise_sigma": noise level used on test set "dont_save_results: if True, don't save output images "no_gpu": if True, run model on CPU "save_path": where to save outputs as png "gray": if True, perform denoising of grayscale images instead of RGB """ # If save_path does not exist, create it if not os.path.exists(args['save_path']): os.makedirs(args['save_path']) logger = init_logger_test(args['save_path']) # Sets data type according to CPU or GPU modes if args['cuda']: device = torch.device('cuda') else: device = torch.device('cpu') # Create models print('Loading models ...') model_temp = FastDVDnet(num_input_frames=NUM_IN_FR_EXT) # Load saved weights state_temp_dict = torch.load(args['model_file']) if args['cuda']: device_ids = [0] model_temp = nn.DataParallel(model_temp, device_ids=device_ids).cuda() else: # CPU mode: remove the DataParallel wrapper state_temp_dict = remove_dataparallel_wrapper(state_temp_dict) model_temp.load_state_dict(state_temp_dict) # Sets the model in evaluation mode (e.g. it removes BN) model_temp.eval() processed_count = 0 # To avoid out of memory issues, we only process one folder at a time. for tmp_folder in get_next_folder(args['test_path'], args['max_num_fr_per_seq']): folder = tmp_folder.name # Start time print("Processing {}".format(os.listdir(tmp_folder.name))) logger.info("Processing {}".format(os.listdir(folder))) start_time = time.time() with torch.no_grad(): # process data seq, _, _ = open_sequence(folder, args['gray'], expand_if_needed=False, max_num_fr=args['max_num_fr_per_seq']) seq = torch.from_numpy(seq).to(device) seq_time = time.time() # Add noise noise = torch.empty_like(seq).normal_( mean=0, std=args['noise_sigma']).to(device) seqn = seq + noise noisestd = torch.FloatTensor([args['noise_sigma']]).to(device) denframes = denoise_seq_fastdvdnet(seq=seqn, noise_std=noisestd, temp_psz=NUM_IN_FR_EXT, model_temporal=model_temp) # Compute PSNR and log it stop_time = time.time() psnr = batch_psnr(denframes, seq, 1.) psnr_noisy = batch_psnr(seqn.squeeze(), seq, 1.) loadtime = (seq_time - start_time) runtime = (stop_time - seq_time) seq_length = seq.size()[0] logger.info("Finished denoising {}".format(args['test_path'])) logger.info("\tDenoised {} frames in {:.3f}s, loaded seq in {:.3f}s". format(seq_length, runtime, loadtime)) logger.info( "\tPSNR noisy {:.4f}dB, PSNR result {:.4f}dB".format(psnr_noisy, psnr)) # Save outputs if not args['dont_save_results']: # Save sequence save_out_seq(seqn, denframes, args['save_path'], int(args['noise_sigma']*255), args['suffix'], args['save_noisy'], processed_count) # subtract half stride because of the half-steps get_next_folder takes. processed_count+=seqn.size()[0] # close logger close_logger(logger)