我想使用结构相似性指数来计算两张图像之间的平均结构相似性指数:原始的和重建的。
这是最原始的一个:
虽然这是重建的一个:
如果我运行这个脚本:
import numpy as np
from skimage.metrics import structural_similarity as ssim
# Both original and reconstructed have shape (40, 40, 1)
# dtype is 'float32'
original = np.load("original.npy")
reconstructed = np.load("reconstructed.npy")
ssim(original, reconstructed, data_range=1, channel_axis=-1) # 0.9321383
您可以注意到,该值非常大,大约为0.93
,但重建的图像与原始图像完全不同!
我错过了什么?请注意,scikit-image
版本是scikit-image~=0.21.0
。
我尝试了1:我认为data_range=1
参数有问题,因为文档说:
输入图像的数据范围(最小值和最大值之间的距离)。默认情况下,这是根据图像数据类型估计的。对于浮点图像数据,此估计值可能是错误的。因此,建议始终显式传递此值。如果未指定data_range,则会根据图像数据类型自动猜测范围。然而,对于浮点图像数据,该估计产生的结果是所需范围值的两倍,因为www.example.com中的dtype_rangeskimage.util.dtype.py定义了从-1到+1的区间。这产生了估计值2,而不是1,这是在处理图像数据时最经常需要的(因为负光强度是无意义的)。如果使用类似YCbCr的颜色数据,请注意,每个通道的范围都不同(Cb和Cr的范围是Y的两倍),因此无法通过单个调用此函数来计算通道平均SSIM,因为每个通道的范围都是相同的。
设置data_range=original.min()-original.max()
而不是data_range=1
有意义吗?你觉得怎么样?这样就得到了ssim = 0.059593666
。
如果你需要它,还有一些额外的信息:
original.min(), original.max() # (0.7764345, 0.82100683)
reconstructed.min(), reconstructed.max() # (0.6095292, 0.65623206)
我尝试了2:我以这种方式对原始图像和重建图像进行了归一化:
original = np.load("original.npy")
reconstructed = np.load("reconstructed.npy")
original = (original - np.min(original)) / (np.max(original) - np.min(original))
reconstructed = (reconstructed - np.min(reconstructed)) / (np.max(reconstructed) - np.min(reconstructed))
ssim(original, reconstructed, data_range=1, channel_axis=-1) # 0.056520723
你认为什么是正确的解决办法?
1条答案
按热度按时间slmsl1lt1#
在您的例子中,与定义的范围(
range=1
)相比,两个图像具有如此小的范围意味着它们都或多或少是平坦的,它们几乎没有偏离均匀的灰度值。所以它们在结构上非常相似。这意味着,如果您要使用强度范围1(例如,将黑色设置为0,将白色设置为1),那么您将在这两个图像中看到很少的差异:将范围归一化为1并设置
range=1
与设置range=original.min()-original.max()
具有完全相同的效果。这两种方法都使图像强度的实际范围与报告给SSIM算法的范围相匹配。虽然我可能会在规格化时以与
original
相同的方式缩放reconstructed
:正因为如此,两个图像之间的比较不会受到潜在的不同缩放的影响。不同的缩放和偏移 * 应该 * 对计算的SSIM没有影响,但如果/当您选择更改比较算法时,它可能会产生很大的影响。