用于3D图像体积的SSIM

时间:2018-12-26 14:43:40

标签: python-2.7 tensorflow image-processing scikit-image ssim

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

我正在使用TF中的image.ssimmeasure.comapre_ssim中的skimage。两者对于2D都给出相同的结果,但是3D体积的结果始终存在差异。

我已经研究了TF-implementationskimage-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体积的深度。

有人可以对此有所启发,并帮助我决定进一步使用哪个,为什么?

1 个答案:

答案 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 应用有效地实现。