用于 3D 图像体积的 SSIM

SSIM for 3D image volume

我正在使用 TensorFlow 处理图像超分辨率问题(2D 和 3D),并且我使用 SSIM 作为 eval_metrics 之一。

我正在使用来自 TF 的 image.ssim 和来自 skimagemeasure.comapre_ssim。它们都给出了相同的 2D 结果,但 3D 体积的结果总是不同。

我查看了这两个 TF-implementation and 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 体积的深度。

有人可以阐明这些并帮助我决定进一步使用哪一个吗?为什么?

粗略地看一下代码,似乎 TensorFlow 总是为批处理中的每个图像和每个通道计算 2D SSIM。它平均跨通道的 SSIM 值,returns 批次中每个图像的值。对于 TF,4D 数组是具有多个通道的 2D 图像的集合。

相比之下,如果设置了 multichannel,SciKit-Image 会在所有维度上计算 SSIM,最后一个维度除外。因此,在 4D 阵列的情况下,它会为每个通道计算 3D SSIM 并计算通道间的平均值。

这与您发现的 3 维阵列的结果相似,但 4 维阵列的结果不同。


skimage however, seems to be using 1D Gaussian filters.

我不确定你从哪里得到的,SciKit-Image 在 n 的情况下使用 nD 高斯分布D 图像。然而,高斯是一个可分离的滤波器,这意味着它可以通过 n 个一维滤波器的应用程序有效地实现。