在配对数据集中的低光增强评价指标中主要有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()

## Initializing the model
loss_fn = lpips.LPIPS(net='alex', version=opt.version)

# the total list of images
files = os.listdir(opt.dir0)
i = 0
total_lpips_distance = 0
average_lpips_distance = 0
for file in files:

try:
# Load images
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

# Compute distance
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)