您现在的位置是:首页 >其他 >图像质量评估:SSIM算法详解与Python实现网站首页其他
图像质量评估:SSIM算法详解与Python实现
一、SSIM算法概述
结构相似性指数(Structural Similarity Index, SSIM)是一种用于衡量两幅图像相似度的指标,通过模拟人类视觉系统(HVS)的特性,综合评估图像的亮度、对比度和结构信息。
二、适用场景
1、适用场景
场景类型 | 说明 |
---|---|
静态场景监控 | 固定摄像头监控仓库、办公室等背景变化小的场景 |
图像压缩评估 | 评估JPEG、H.264等压缩算法导致的图像质量损失 |
视频传输质量监测 | 检测网络传输中丢包或延迟引起的画面模糊、块效应等问题 |
图像增强效果对比 | 比较去噪、超分辨率等算法处理前后的质量差异 |
2、优缺点
维度 | 优点 | 缺点 |
---|---|---|
感知一致性 | 比PSNR更贴近人眼主观感受 | 对几何变换(旋转/平移)敏感 |
多维度评估 | 同时考虑亮度、对比度、结构三个维度 | 计算复杂度较高(约是PSNR的3-5倍) |
局部敏感性 | 通过滑动窗口检测局部质量变化 | 窗口大小和参数设置影响结果 |
数学可解释性 | 公式具有明确的物理意义 | 无法直接反映语义内容变化 |
三、实现原理与公式推导
SSIM通过比较两幅图像(参考图像和待评估图像)的亮度(Luminance)、对比度(Contrast)和结构(Structure)三个维度计算相似性,总公式如下:
其中:
:局部窗口内图像的均值(亮度)。
:局部窗口内图像的标准差(对比度)。
:两图像的协方差(结构相似性)。
:防止分母为零的常数,通常
,
,L为像素值的动态范围(如255)。
分三个维度详解:
1、亮度对比:
2、对比度比较:
3、 结构对比:
-
通常
四、Python实现代码
import numpy as np
from scipy.ndimage import gaussian_filter
def calculate_ssim(img1, img2,
window_size=11,
gaussian_sigma=1.5,
data_range=255.0,
K1=0.01,
K2=0.03,
use_gaussian=True):
"""
SSIM算法实现
Parameters:
img1, img2 (numpy.ndarray): 输入图像(灰度图,尺寸相同)
window_size (int): 滑动窗口尺寸
gaussian_sigma (float): 高斯核标准差
data_range (float): 像素值范围(8bit图像为255.0)
K1, K2 (float): 稳定性系数
use_gaussian (bool): 是否使用高斯加权
Returns:
ssim_score (float): 全局SSIM值
ssim_map (numpy.ndarray): 局部SSIM图
"""
# 常量计算
C1 = (K1 * data_range) ** 2
C2 = (K2 * data_range) ** 2
# 图像预处理
img1 = img1.astype(np.float64)
img2 = img2.astype(np.float64)
# 窗口生成
if use_gaussian:
x = np.linspace(-window_size//2 + 1, window_size//2, window_size)
g = np.exp(-(x**2) / (2*gaussian_sigma**2))
window = np.outer(g, g)
window /= np.sum(window)
else:
window = np.ones((window_size, window_size)) / window_size**2
# 均值计算
mu1 = gaussian_filter(img1, sigma=gaussian_sigma, mode='reflect')
mu2 = gaussian_filter(img2, sigma=gaussian_sigma, mode='reflect')
# 方差与协方差
mu1_sq = mu1**2
mu2_sq = mu2**2
mu1_mu2 = mu1 * mu2
sigma1_sq = gaussian_filter(img1**2, sigma=gaussian_sigma, mode='reflect') - mu1_sq
sigma2_sq = gaussian_filter(img2**2, sigma=gaussian_sigma, mode='reflect') - mu2_sq
sigma12 = gaussian_filter(img1*img2, sigma=gaussian_sigma, mode='reflect') - mu1_mu2
# SSIM计算
numerator = (2 * mu1_mu2 + C1) * (2 * sigma12 + C2)
denominator = (mu1_sq + mu2_sq + C1) * (sigma1_sq + sigma2_sq + C2)
ssim_map = numerator / denominator
ssim_score = np.mean(ssim_map)
return ssim_score, ssim_map
参数详解如下所示:
参数名称 | 类型 | 默认值 | 作用说明 | 推荐范围 |
---|---|---|---|---|
| int | 11 | 滑动窗口尺寸,决定局部比较范围 | 7-15(奇数) |
| float | 1.5 | 高斯核标准差,控制权重分布 | window_size/6 ± 0.5 |
| float | 255.0 | 像素动态范围,8bit图像设为255,归一化图像设为1.0 | 根据实际数据设置 |
| float | 0.01 | 亮度稳定性系数,值越小对亮度变化越敏感 | 0.01-0.05 |
| float | 0.03 | 对比度稳定性系数,值越小对对比度变化越敏感 | 0.03-0.07 |
| bool | True | 是否使用高斯加权窗口,False时使用均匀窗口(计算更快) | 根据精度要求选择 |
五、示例
import cv2
# 读取图像
ref_img = cv2.imread('ori.jpg', cv2.IMREAD_GRAYSCALE)
test_img = cv2.imread('test.jpg', cv2.IMREAD_GRAYSCALE)
# 计算SSIM
score, ssim_map = calculate_ssim(ref_img, test_img,
window_size=7,
gaussian_sigma=1.2,
data_range=255.0)
# 结果输出
print(f"全局SSIM值: {score:.4f}")
cv2.imshow('SSIM热力图', cv2.applyColorMap((ssim_map*255).astype(np.uint8), cv2.COLORMAP_JET))
cv2.waitKey(0)
六、注意事项
-
图像对齐:输入图像必须严格对齐,建议先进行特征匹配或光流对齐
-
颜色空间:算法默认处理灰度图,对RGB图像可分别计算各通道后取平均
-
性能优化:
-
对大尺寸图像可先下采样
-
关闭高斯窗口(
use_gaussian=False
)可提速约40%
-
-
异常处理:当分母接近零时可能产生NaN值,需添加微小epsilon(如1e-6)
七、扩展改进建议
-
多尺度SSIM (MS-SSIM):结合不同分辨率图像进行计算,提升对全局特征的感知
-
结合深度学习:使用CNN提取特征代替手工设计的窗口函数
-
视频SSIM:引入时间维度,计算连续帧间的SSIM变化率检测突发质量劣化