衡量高分辨率图片生成效果的指标PSNR/SSIM
做对抗生成的时候遇到的问题,记录一下备忘。
背景是对抗生成的图片,用做分类器训练的时候并不能达到理想的提高分类器精度的效果,反而会拉低val_acc出现过拟合。
思考可能的原因一个是生成的图片太模糊,另一个是发生了model collapse。
肉眼难以分辨图片的细微区别,希望找一些指标来定量衡量生成的图片的效果。
常见的两个指标PSNR 和 SSIM
- PSNR
峰值信噪比,由公式可以看出与MSE成反比,是从像素级别上衡量的。
结果在0-100之间,越大越好。
缺点是:“PSNR的分数无法和人眼看到的视觉品质完全一致,有可能PSNR较高者看起来反而比PSNR较低者差。这是因为人眼的视觉对于误差的敏感度并不是绝对的,其感知结果会受到许多因素的影响而产生变化(例如:人眼对空间频率较低的对比差异敏感度较高,人眼对亮度对比差异的敏感度较色度高,人眼对一个区域的感知结果会受到其周围邻近区域的影响)”
实测效果确实不好,感觉这个指标更关注像素层面,因此亮度的差别会对结果造成很大的影响。
- SSIM
结构相似性,将失真建模为亮度、对比度和结构三个因素的组合。
结果在0-1之间,越大越好。
实测效果好,但是该指标只能反映两张图片“结构相似”,不能直接说明生成质量“是否提升”。
(数学上看,ssim(x,y)=ssim(y,x)轮换对称,PSNR指标同理。)
目前原始图像1和生成图像2的ssim为0.542,ssim越高,则二者越接近,即生成效果越好,借此逐步将生成图像趋同于原始图像。
import cv2
import numpy as np
import math
import tensorflow as tf
# def psnr1(img1, img2):
# mse = np.mean((img1 - img2) ** 2)
# if mse < 1.0e-10:
# return 100
# return 10 * math.log10(255.0 ** 2 / mse)
def psnr2(img1, img2):
mse = np.mean((img1 / 255. - img2 / 255.) ** 2)
if mse < 1.0e-10:
return 100
PIXEL_MAX = 1
return 20 * math.log10(PIXEL_MAX / math.sqrt(mse))
def ssim(img1, img2, max_val):
_, _, checks = _verify_compatible_image_shapes(img1, img2)
with ops.control_dependencies(checks):
img1 = array_ops.identity(img1)
# Need to convert the images to float32. Scale max_val accordingly so that
# SSIM is computed correctly.
max_val = math_ops.cast(max_val, img1.dtype)
max_val = convert_image_dtype(max_val, dtypes.float32)
img1 = convert_image_dtype(img1, dtypes.float32)
img2 = convert_image_dtype(img2, dtypes.float32)
ssim_per_channel, _ = _ssim_per_channel(img1, img2, max_val)
# Compute average over color channels.
return math_ops.reduce_mean(ssim_per_channel, [-1])
if __name__ == '__main__':
file1 = "output16_right.jpeg"
file2 = "valid_gen.jpeg"
# file1 = "valid_gen.png"
# file2 = "123.png"
img1 = cv2.imread(file1)
img1 = cv2.resize(img1, (256,256))
img2 = cv2.imread(file2)
img2 = cv2.resize(img2, (256,256))
img3 = img1 - img2
hmerge = np.hstack((img1, img2, img3))
im1 = tf.image.convert_image_dtype(img1, tf.float32)
im2 = tf.image.convert_image_dtype(img2, tf.float32)
# cv2.imshow("test",hmerge)
# cv2.waitKey(0)
# print(psnr2(img1, img2))
ssim1 = tf.image.ssim(im1, im2, 1.0)
with tf.Session() as sess:
print(file1)
print(file2)
print('tf.image.ssim: ', sess.run(ssim1))
----------------------备忘-------------------------------------------------------------------------------
原始高清/SRGAN生成优化
生成/SRGAN优化
左眼/右眼
目标是,提高原始高清/生成的SSIM。
------------------------------------------------------------
代码参考的是:
https://blog.csdn.net/u010886794/article/details/84784453