update
							parent
							
								
									5c22148bed
								
							
						
					
					
						commit
						274abed989
					
				@ -1,193 +0,0 @@
 | 
			
		||||
import os 
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
import numpy as np
 | 
			
		||||
import cv2 
 | 
			
		||||
from scipy import signal
 | 
			
		||||
from skimage.metrics import structural_similarity
 | 
			
		||||
from PIL import Image
 | 
			
		||||
import argparse
 | 
			
		||||
 | 
			
		||||
import time
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
import ray
 | 
			
		||||
ray.init(num_cpus=16, num_gpus=0, ignore_reinit_error=True, log_to_driver=False)
 | 
			
		||||
 | 
			
		||||
parser = argparse.ArgumentParser()
 | 
			
		||||
parser.add_argument("path_to_dataset", type=str)
 | 
			
		||||
parser.add_argument("--scale", type=int, default=4)
 | 
			
		||||
args = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
def cal_ssim(img1, img2):
 | 
			
		||||
    K = [0.01, 0.03]
 | 
			
		||||
    L = 255
 | 
			
		||||
    kernelX = cv2.getGaussianKernel(11, 1.5)
 | 
			
		||||
    window = kernelX * kernelX.T
 | 
			
		||||
 | 
			
		||||
    M, N = np.shape(img1)
 | 
			
		||||
 | 
			
		||||
    C1 = (K[0] * L) ** 2
 | 
			
		||||
    C2 = (K[1] * L) ** 2
 | 
			
		||||
    img1 = np.float64(img1)
 | 
			
		||||
    img2 = np.float64(img2)
 | 
			
		||||
 | 
			
		||||
    mu1 = signal.convolve2d(img1, window, 'valid')
 | 
			
		||||
    mu2 = signal.convolve2d(img2, window, 'valid')
 | 
			
		||||
 | 
			
		||||
    mu1_sq = mu1 * mu1
 | 
			
		||||
    mu2_sq = mu2 * mu2
 | 
			
		||||
    mu1_mu2 = mu1 * mu2
 | 
			
		||||
 | 
			
		||||
    sigma1_sq = signal.convolve2d(img1 * img1, window, 'valid') - mu1_sq
 | 
			
		||||
    sigma2_sq = signal.convolve2d(img2 * img2, window, 'valid') - mu2_sq
 | 
			
		||||
    sigma12 = signal.convolve2d(img1 * img2, window, 'valid') - mu1_mu2
 | 
			
		||||
 | 
			
		||||
    ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) * (sigma1_sq + sigma2_sq + C2))
 | 
			
		||||
    mssim = np.mean(ssim_map)
 | 
			
		||||
    return mssim
 | 
			
		||||
 | 
			
		||||
def PSNR(y_true, y_pred, shave_border=4):
 | 
			
		||||
    target_data = np.array(y_true, dtype=np.float32)
 | 
			
		||||
    ref_data = np.array(y_pred, dtype=np.float32)
 | 
			
		||||
 | 
			
		||||
    diff = ref_data - target_data
 | 
			
		||||
    if shave_border > 0:
 | 
			
		||||
        diff = diff[shave_border:-shave_border, shave_border:-shave_border]
 | 
			
		||||
    rmse = np.sqrt(np.mean(np.power(diff, 2)))
 | 
			
		||||
 | 
			
		||||
    return 20 * np.log10(255. / rmse)
 | 
			
		||||
 | 
			
		||||
def _rgb2ycbcr(img, maxVal=255):
 | 
			
		||||
    O = np.array([[16],
 | 
			
		||||
                  [128],
 | 
			
		||||
                  [128]])
 | 
			
		||||
    T = np.array([[0.256788235294118, 0.504129411764706, 0.097905882352941],
 | 
			
		||||
                  [-0.148223529411765, -0.290992156862745, 0.439215686274510],
 | 
			
		||||
                  [0.439215686274510, -0.367788235294118, -0.071427450980392]])
 | 
			
		||||
 | 
			
		||||
    if maxVal == 1:
 | 
			
		||||
        O = O / 255.0
 | 
			
		||||
 | 
			
		||||
    t = np.reshape(img, (img.shape[0] * img.shape[1], img.shape[2]))
 | 
			
		||||
    t = np.dot(t, np.transpose(T))
 | 
			
		||||
    t[:, 0] += O[0]
 | 
			
		||||
    t[:, 1] += O[1]
 | 
			
		||||
    t[:, 2] += O[2]
 | 
			
		||||
    ycbcr = np.reshape(t, [img.shape[0], img.shape[1], img.shape[2]])
 | 
			
		||||
 | 
			
		||||
    return ycbcr
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def modcrop(image, modulo):
 | 
			
		||||
    if len(image.shape) == 2:
 | 
			
		||||
        sz = image.shape
 | 
			
		||||
        sz = sz - np.mod(sz, modulo)
 | 
			
		||||
        image = image[0:sz[0], 0:sz[1]]
 | 
			
		||||
    elif image.shape[2] == 3:
 | 
			
		||||
        sz = image.shape[0:2]
 | 
			
		||||
        sz = sz - np.mod(sz, modulo)
 | 
			
		||||
        image = image[0:sz[0], 0:sz[1], :]
 | 
			
		||||
    else:
 | 
			
		||||
        raise NotImplementedError
 | 
			
		||||
    return image
 | 
			
		||||
 | 
			
		||||
scale = args.scale
 | 
			
		||||
 | 
			
		||||
dataset_path = Path(args.path_to_dataset)
 | 
			
		||||
hr_path = dataset_path / "HR/"
 | 
			
		||||
lr_path = dataset_path / f"LR_bicubic/X{scale}/"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
print(hr_path, lr_path)
 | 
			
		||||
 | 
			
		||||
hr_files = os.listdir(hr_path)
 | 
			
		||||
lr_files = os.listdir(lr_path)
 | 
			
		||||
 | 
			
		||||
@ray.remote(num_cpus=1)
 | 
			
		||||
def benchmark_image_pair(hr_image_path, lr_image_path, interpolation_function):
 | 
			
		||||
    hr_image = cv2.imread(hr_image_path)
 | 
			
		||||
    lr_image = cv2.imread(lr_image_path)
 | 
			
		||||
    
 | 
			
		||||
    hr_image = hr_image[:,:,::-1] # BGR -> RGB
 | 
			
		||||
    lr_image = lr_image[:,:,::-1] # BGR -> RGB
 | 
			
		||||
    
 | 
			
		||||
    start_time = datetime.now()
 | 
			
		||||
    upscaled_lr_image = interpolation_function(lr_image, scale)
 | 
			
		||||
    processing_time = datetime.now() - start_time
 | 
			
		||||
 | 
			
		||||
    hr_image = modcrop(hr_image, scale)
 | 
			
		||||
    upscaled_lr_image = upscaled_lr_image
 | 
			
		||||
 | 
			
		||||
    psnr = PSNR(_rgb2ycbcr(hr_image)[:,:,0], _rgb2ycbcr(upscaled_lr_image)[:,:,0])
 | 
			
		||||
    cpsnr = PSNR(hr_image, upscaled_lr_image)
 | 
			
		||||
 | 
			
		||||
    cv2_psnr = cv2.PSNR(cv2.cvtColor(hr_image, cv2.COLOR_RGB2YCrCb)[:,:,0], cv2.cvtColor(upscaled_lr_image, cv2.COLOR_RGB2YCrCb)[:,:,0])
 | 
			
		||||
    cv2_cpsnr = cv2.PSNR(hr_image, upscaled_lr_image)
 | 
			
		||||
 | 
			
		||||
    ssim = cal_ssim(_rgb2ycbcr(hr_image)[:,:,0], _rgb2ycbcr(upscaled_lr_image)[:,:,0])
 | 
			
		||||
    cv2_ssim = cal_ssim(cv2.cvtColor(hr_image, cv2.COLOR_RGB2YCrCb)[:,:,0], cv2.cvtColor(upscaled_lr_image, cv2.COLOR_RGB2YCrCb)[:,:,0])
 | 
			
		||||
    ssim_scikit, diff = structural_similarity(_rgb2ycbcr(hr_image)[:,:,0], _rgb2ycbcr(upscaled_lr_image)[:,:,0], full=True, data_range=255.0)
 | 
			
		||||
    cv2_scikit_ssim, diff = structural_similarity(cv2.cvtColor(hr_image, cv2.COLOR_RGB2YCrCb)[:,:,0], cv2.cvtColor(upscaled_lr_image, cv2.COLOR_RGB2YCrCb)[:,:,0], full=True, data_range=255.0)
 | 
			
		||||
 | 
			
		||||
    return ssim, cv2_ssim, ssim_scikit, cv2_scikit_ssim, psnr, cpsnr, cv2_psnr, cv2_cpsnr, processing_time.total_seconds()
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
def benchmark_interpolation(interpolation_function):
 | 
			
		||||
    psnrs, cpsnrs, ssims = [], [], []
 | 
			
		||||
    cv2_psnrs, cv2_cpsnrs, scikit_ssims = [], [], []
 | 
			
		||||
    cv2_scikit_ssims = []
 | 
			
		||||
    cv2_ssims = []
 | 
			
		||||
    tasks = []
 | 
			
		||||
    for hr_name, lr_name in zip(hr_files, lr_files):
 | 
			
		||||
        hr_image_path = str(hr_path / hr_name)
 | 
			
		||||
        lr_image_path = str(lr_path / lr_name)
 | 
			
		||||
        tasks.append(benchmark_image_pair.remote(hr_image_path, lr_image_path, interpolation_function))
 | 
			
		||||
 | 
			
		||||
    ready_refs, remaining_refs = ray.wait(tasks, num_returns=1, timeout=None)
 | 
			
		||||
    while len(remaining_refs) > 0:
 | 
			
		||||
        print(f"\rReady {len(ready_refs)}/{len(hr_files)}",  end="     ")
 | 
			
		||||
        ready_refs, remaining_refs = ray.wait(tasks, num_returns=len(ready_refs)+1, timeout=None)
 | 
			
		||||
 | 
			
		||||
    for task in tasks:
 | 
			
		||||
        ssim, cv2_ssim, ssim_scikit, cv2_scikit_ssim, psnr, cpsnr, cv2_psnr, cv2_cpsnr, processing_time = ray.get(task)
 | 
			
		||||
        ssims.append(ssim)
 | 
			
		||||
        cv2_ssims.append(cv2_ssim)
 | 
			
		||||
        scikit_ssims.append(ssim_scikit)
 | 
			
		||||
        cv2_scikit_ssims.append(cv2_scikit_ssim)        
 | 
			
		||||
        psnrs.append(psnr) 
 | 
			
		||||
        cpsnrs.append(cpsnr)
 | 
			
		||||
        cv2_psnrs.append(cv2_psnr)
 | 
			
		||||
        cv2_cpsnrs.append(cv2_cpsnr)
 | 
			
		||||
        processing_times.append(processing_time)
 | 
			
		||||
 | 
			
		||||
    print()
 | 
			
		||||
    print(f"AVG PSNR: {np.mean(psnrs):.2f} PSNR + _rgb2ycbcr") 
 | 
			
		||||
    print(f"AVG PSNR: {np.mean(cv2_psnrs):.2f} cv2.PSNR + cv2.cvtColor")
 | 
			
		||||
    print(f"AVG cPSNR: {np.mean(cpsnrs):.2f} PSNR")    
 | 
			
		||||
    print(f"AVG cPSNR: {np.mean(cv2_cpsnrs):.2f} cv2.PSNR ")
 | 
			
		||||
    print(f"AVG SSIM: {np.mean(ssims):.4f} cal_ssim + _rgb2ycbcr")
 | 
			
		||||
    print(f"AVG SSIM: {np.mean(cv2_ssims):.4f} cal_ssim + cv2.cvtColor")
 | 
			
		||||
    print(f"AVG SSIM: {np.mean(scikit_ssims):.4f} structural_similarity + _rgb2ycbcr")
 | 
			
		||||
    print(f"AVG SSIM: {np.mean(cv2_scikit_ssims):.4f} structural_similarity + cv2.cvtColor")
 | 
			
		||||
    print(f"AVG Time s: {np.percentile(processing_times, q=0.9)}")
 | 
			
		||||
    print(f"{np.mean(psnrs):.2f},{np.mean(cv2_psnrs):.2f},{np.mean(cpsnrs):.2f},{np.mean(cv2_cpsnrs):.2f},{np.mean(ssims):.4f},{np.mean(cv2_ssims):.4f},{np.mean(scikit_ssims):.4f},{np.mean(cv2_scikit_ssims):.4f},{np.percentile(processing_times, q=0.9)}")  
 | 
			
		||||
 | 
			
		||||
def cv2_interpolation(image, scale):
 | 
			
		||||
    scaled_image = cv2.resize(
 | 
			
		||||
        image, 
 | 
			
		||||
        None, None, 
 | 
			
		||||
        fx=scale, fy=scale, 
 | 
			
		||||
        interpolation=cv2.INTER_CUBIC
 | 
			
		||||
    )
 | 
			
		||||
    return scaled_image
 | 
			
		||||
 | 
			
		||||
def pillow_interpolation(image, scale):
 | 
			
		||||
    image = Image.fromarray(image[:,:,::-1])
 | 
			
		||||
    width, height = int(image.width * scale), int(image.height * scale)
 | 
			
		||||
    scaled_image = image.resize((width, height), resample=Image.Resampling.BICUBIC)
 | 
			
		||||
    return np.array(scaled_image)[:,:,::-1]
 | 
			
		||||
 | 
			
		||||
print("cv2 bicubic interpolation")
 | 
			
		||||
benchmark_interpolation(cv2_interpolation)
 | 
			
		||||
print()
 | 
			
		||||
print("pillow bicubic interpolation")
 | 
			
		||||
benchmark_interpolation(pillow_interpolation)
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue