图像质量评估:SSIM算法详解与Python实现

2025-06-11 05:05:29 / 法国直播世界杯

一、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

参数详解如下所示:

参数名称类型默认值作用说明推荐范围 window_size

int

11

滑动窗口尺寸,决定局部比较范围

7-15(奇数)

gaussian_sigma

float

1.5

高斯核标准差,控制权重分布

window_size/6 ± 0.5

data_range

float

255.0

像素动态范围,8bit图像设为255,归一化图像设为1.0

根据实际数据设置

K1

float

0.01

亮度稳定性系数,值越小对亮度变化越敏感

0.01-0.05

K2

float

0.03

对比度稳定性系数,值越小对对比度变化越敏感

0.03-0.07

use_gaussian

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变化率检测突发质量劣化