我正在使用TensorFlow处理图像超分辨率问题(2D和3D),并且正在使用SSIM作为eval_metrics
之一。
我正在使用TF中的image.ssim
和measure.comapre_ssim
中的skimage
。两者对于2D都给出相同的结果,但是3D体积的结果始终存在差异。
我已经研究了TF-implementation和skimage-implemenation的源代码。在两种实现方式中,如何考虑和处理输入图像似乎存在一些根本差异。
用于复制问题的代码:
import numpy as np
import tensorflow as tf
from skimage import measure
# For 2-D case
np.random.seed(12345)
a = np.random.random([32, 32, 64])
b = np.random.random([32, 32, 64])
a_ = tf.convert_to_tensor(a)
b_ = tf.convert_to_tensor(b)
ssim_2d_tf = tf.image.ssim(a_, b_, 1.0)
ssim_2d_sk = measure.compare_ssim(a, b, multichannel=True, gaussian_weights=True, data_range=1.0, use_sample_covariance=False)
print (tf.Session().run(ssim_2d_tf), ssim_2d_sk)
# For 3-D case
np.random.seed(12345)
a = np.random.random([32, 32, 32, 64])
b = np.random.random([32, 32, 32, 64])
a_ = tf.convert_to_tensor(a)
b_ = tf.convert_to_tensor(b)
ssim_3d_tf = tf.image.ssim(a_, b_, 1.0)
ssim_3d_sk = measure.compare_ssim(a, b, multichannel=True, gaussian_weights=True, data_range=1.0, use_sample_covariance=False)
s_3d_tf = tf.Session().run(ssim_3d_tf)
print (np.mean(s_3d_tf), ssim_3d_sk)
在3D情况下,我必须取输出的平均值,因为Tensorflow在最后三个维度上计算SSIM,因此得出 32个SSIM 值。这表明TF考虑了NHWC格式的SSIM图像。这对于3D体积上的SSIM是否有用?
skimage
不过似乎正在使用一维高斯滤波器。因此很明显,即使这还没有考虑3D体积的深度。
有人可以对此有所启发,并帮助我决定进一步使用哪个,为什么?
答案 0 :(得分:4)
从粗略地看代码来看,似乎TensorFlow始终为批处理中的每个图像和每个通道计算2D SSIM。它将平均各个通道的SSIM值,并为批次中的每个图像返回一个值。对于TF,4D数组是具有多个通道的2D图像的集合。
相比之下,如果设置了multichannel
,则SciKit-Image会在所有维度上计算SSIM,最后一个除外。因此,在使用4D阵列的情况下,它会为每个通道计算3D SSIM并在通道之间求平均值。
这与您发现的3D阵列结果相似,但4D阵列结果不同的结果一致。
但是,skimage似乎正在使用一维高斯滤波器。
我不确定您从何处获得此信息,对于 n D图像,SciKit-Image使用 n D高斯分布。但是,高斯是可分离的滤波器,这意味着它可以通过一维滤波器的 n 应用有效地实现。