在配对数据集中的低光增强评价指标中主要有SSIM、PSNR、LPIPS三种。
参考文献:低光图像增强 评价指标
图像的峰值信噪比(PSNR)的计算方法
SSIM (Structure Similarity Index Measure) 结构衡量指标+代码
LPIPS 图像相似性度量标准、感知损失(Perceptual loss)
PSNR
PSNR(Peak Signal-to-Noise Ratio) 中文名称峰值信噪比,单位为DB,他说用来衡量图像大小为的真值图像与增强图之间的差异,数值越高表明二者差异越小,说明增强后的图像失真越小,一般大于30db就表明图像质量很好。PSNR的计算方法如下:
其中,表示图像点颜色的最大数值;MSE为图像的方差,定义为: 。
SSIM
SSIM(## Structural Similarity Index Measure),中文名为结构相似性。用于衡量两幅图像相似性的指标。与PSNR相比,SSIM更关注图像结构、亮度和对比度等方面的差异,能够更好地反映人类对图像质量的主观感知。SSIM 主要考量图片的三个关键特征:亮度(Luminance), 对比度(Contrast), 结构 (Structure)。
1、亮度(Luminance):亮度的表示方法通过平均灰度来表示, ,对比函数为:
2、对比度(Contrast):对比度通过像素的标准差来衡量,,对比函数为:
3、结构 (Structure):结构对比比较的是经过归一化后 与 的比较, 即可以用相关性系数衡量:
则SSIM定义如下:
参考代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| def ssim(self, img1, img2): C1 = (0.01 * self.data_range)**2 C2 = (0.03 * self.data_range)**2 kernel = self.gaussian_kernel.to(img1.device) mu1 = F.conv2d(img1, kernel, padding=0, groups=self.channel) mu2 = F.conv2d(img2, kernel, padding=0, groups=self.channel) mu1_sq = mu1.pow(2) mu2_sq = mu2.pow(2) mu1_mu2 = mu1 * mu2 sigma1_sq = F.conv2d(img1 * img1, kernel, padding=0, groups=self.channel) - mu1_sq sigma2_sq = F.conv2d(img2 * img2, kernel, padding=0, groups=self.channel) - mu2_sq sigma12 = F.conv2d(img1 * img2, kernel, padding=0, groups=self.channel) - mu1_mu2 ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / \ ((mu1_sq + mu2_sq + C1) * (sigma1_sq + sigma2_sq + C2)) return ssim_map.mean()
|
LPIPS
LPIPS(Learned Perceptual Image Patch Structure),中文名称感知图像对比损失,是一种使用预训练的深度学习模型提取特征进行图像间比较的方法。LPIPS 认为,即使两个图像在像素级别上非常接近,人类观察者也可能将它们视为不同。因此,LPIPS 使用预训练的深度网络(如 VGG、AlexNet)来提取图像特征,然后计算这些特征之间的距离,以评估图像之间的感知相似度。
参考代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| import argparse import os import lpips parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--dir0', type=str, default='./input_images') parser.add_argument('--dir1', type=str, default='./output_images') parser.add_argument('-v','--version', type=str, default='0.1') opt = parser.parse_args()
loss_fn = lpips.LPIPS(net='alex', version=opt.version)
files = os.listdir(opt.dir0) i = 0 total_lpips_distance = 0 average_lpips_distance = 0 for file in files: try: img0 = lpips.im2tensor(lpips.load_image(os.path.join(opt.dir0,file))) img1 = lpips.im2tensor(lpips.load_image(os.path.join(opt.dir1,file))) if (os.path.exists(os.path.join(opt.dir0, file)), os.path.exists(os.path.join(opt.dir1, file))): i = i + 1 current_lpips_distance = loss_fn.forward(img0, img1) total_lpips_distance = total_lpips_distance + current_lpips_distance print('%s: %.3f'%(file, current_lpips_distance)) except Exception as e: print(e) average_lpips_distance = float(total_lpips_distance) / i print("The processed iamges is ", i , "and the average_lpips_distance is: %.3f" %average_lpips_distance)
|