关于图像误差分析常用指标-MSE,PSNR和SSIM

做图像处理的实验,常用到的定量比较的三个指标:均方误差(MSE), 峰值信噪比(PSNR), 结构相似性指数(SSIM).

本文将着重介绍这三个指标的定义和Python版本的代码实现。

均方误差 Mean Squared Error

功能:

衡量两张图像相似度的一个指标,均方误差越小,表示两张图像越相似。

特点:

对大误差敏感:由于是平方差,MSE对大误差特别敏感,因此如果图像中有较大的差异(比如大面积的噪声),MSE值会显著增大。

对视觉质量的感知差异不敏感:MSE主要从数学角度衡量图像差异,但它并不一定与人眼对图像质量的感知一致。例如,两个图像的MSE可能非常相近,但其中一个图像在视觉上可能明显更好。

公式:

图像处理中的均方误差公式可以如下计算:
MSE=1m×n∑i=1m∑j=1n(I(i,j)−I^(i,j))2其中:I是图像,I^是其处理版本m×n是图像的尺寸,即图像中的像素数。I(i,j)是原始图像在位置(i,j)处的像素值。I^(i,j)是处理后图像在位置(i,j)处的像素值。 MSE = \frac{1}{m \times n} \sum_{i=1}^{m} \sum_{j=1}^{n} \left( I(i,j) - \hat{I}(i,j) \right)^2 \\\\ 其中: I是图像,\hat{I}是其处理版本\\ m \times n 是图像的尺寸,即图像中的像素数。 \\ I(i,j) 是原始图像在位置 (i,j)处的像素值。\\ \hat{I}(i,j)是处理后图像在位置 (i,j)处的像素值。 MSE=m×n1i=1mj=1n(I(i,j)I^(i,j))2II^m×nI(i,j)(i,j)I^(i,j)(i,j)

代码实现(Python):

本文提供的参考代码可以实现多通道的MSE计算,计算的数值已经经过归一化处理。

import cv2
import numpy as np

def resize_to_smaller(image1, image2):
    """
    将两幅图像调整为相同的较小尺寸。
    """
    h1, w1 = image1.shape[:2]
    h2, w2 = image2.shape[:2]
    target_height = min(h1, h2)
    target_width = min(w1, w2)
    resized_image1 = cv2.resize(image1, (target_width, target_height), interpolation=cv2.INTER_AREA)
    resized_image2 = cv2.resize(image2, (target_width, target_height), interpolation=cv2.INTER_AREA)
    return resized_image1, resized_image2

def calculate_mse_per_channel(image1, image2):
    """
    计算彩色图像每个通道的均方误差 (MSE)。
    """
    assert image1.shape == image2.shape, "两幅图像的尺寸必须相同"
    mse_values = []
    for channel in range(3):  # 对B、G、R通道分别计算
        channel1 = image1[:, :, channel] / 255.0
        channel2 = image2[:, :, channel] / 255.0
        mse = np.mean((channel1 - channel2) ** 2)
        mse_values.append(mse)
    return mse_values

def main(image_path1, image_path2):
    """
    主函数,读取图像、调整尺寸并计算每个通道的 MSE。
    """
    img1 = cv2.imread(image_path1)
    img2 = cv2.imread(image_path2)

    if img1 is None or img2 is None:
        print("无法加载图像,请检查文件路径!")
        return

    img1_resized, img2_resized = resize_to_smaller(img1, img2)

    # 计算每个通道的 MSE
    mse_values = calculate_mse_per_channel(img1_resized, img2_resized)

    # print(f"MSE (B通道): {mse_values[0]:.6f}")
    # print(f"MSE (G通道): {mse_values[1]:.6f}")
    # print(f"MSE (R通道): {mse_values[2]:.6f}")

    # 平均 MSE
    avg_mse = np.mean(mse_values)
    print(f"平均 MSE: {avg_mse:.6f}")

# 程序入口
image1 = ''
image2 = ''
main(image1, image2)

峰值信噪比 Peak Signal-to-Noise Ratio

功能

PSNR 表示图像的信号与噪声之间的比率。值越高,图像质量越好。

特点

越大越好:PSNR 值越高,表示图像质量越好。通常来说,PSNR 大于 30 dB 时,人眼几乎无法分辨原始图像和压缩后的图像之间的差异。

对视觉质量有一定反映:与 MSE 相比,PSNR 直接通过对数转换来反映图像质量,且以分贝为单位,更符合人类对信号强度的感知。

MSE的关系:PSNR 和 MSE 是反相关的,MSE 越小,PSNR 越大,意味着图像质量越好。实际上,PSNR 是通过均方误差来推导的,目的是提供一个更容易理解的度量,尤其是在图像压缩中,PSNR 值越高,通常代表图像的失真较小。

单位:PSNR 的单位是分贝(dB)。PSNR 值通常在 20 dB 到 40 dB 之间,超过 40 dB 时,图像质量通常非常接近原始图像。

公式

PSNR=10⋅log⁡10(Imax2MSE)其中:Imax是图像中可能的最大像素值,对于8位图像,通常Imax=255.MSE即上文介绍的均方误差 PSNR = 10 \cdot \log_{10} ( \frac{I_{\text{max}}^2}{MSE}) \\\\ 其中: I_{max}是图像中可能的最大像素值,对于8位图像,通常I_{max}=255. \\ MSE即上文介绍的均方误差 PSNR=10log10(MSEImax2):Imax8Imax=255.MSE

代码实现(Python)

三通道,归一化处理的PSNR值

import cv2
import numpy as np

def calculate_psnr_from_mse(avg_mse, max_pixel=1.0):
    """
    根据平均 MSE 计算 PSNR。
    max_pixel: float
        图像的最大像素值(归一化图像为 1.0,原始图像为 255)。
    """
    if avg_mse == 0:
        return float('inf')  # 如果平均 MSE 为 0,PSNR 为无穷大
    return 10 * np.log10((max_pixel ** 2) / avg_mse)

def process_rgb_psnr(image1, image2):
    """
    计算 RGB 图像的平均 MSE,并根据平均 MSE 计算 PSNR。
    """
    assert image1.shape == image2.shape, "两幅图像的尺寸必须相同"
    
    # 归一化到 [0, 1]
    image1_normalized = image1 / 255.0
    image2_normalized = image2 / 255.0

    # 计算 RGB 各通道的 MSE
    mse_b = np.mean((image1_normalized[:, :, 0] - image2_normalized[:, :, 0]) ** 2)
    mse_g = np.mean((image1_normalized[:, :, 1] - image2_normalized[:, :, 1]) ** 2)
    mse_r = np.mean((image1_normalized[:, :, 2] - image2_normalized[:, :, 2]) ** 2)

    # 计算平均 MSE
    avg_mse = (mse_b + mse_g + mse_r) / 3

    # 计算 PSNR
    psnr = calculate_psnr_from_mse(avg_mse)
    
    return {"Average MSE": avg_mse, "PSNR": psnr}

def main(image_path1, image_path2):
    """
    主函数,读取图像并计算平均 MSE 和 PSNR。
    """
    # 读取图像
    img1 = cv2.imread(image_path1)
    img2 = cv2.imread(image_path2)

    if img1 is None or img2 is None:
        print("无法加载图像,请检查文件路径!")
        return

    # 调整图像大小为相同
    h1, w1 = img1.shape[:2]
    h2, w2 = img2.shape[:2]
    target_height = min(h1, h2)
    target_width = min(w1, w2)
    img1_resized = cv2.resize(img1, (target_width, target_height), interpolation=cv2.INTER_AREA)
    img2_resized = cv2.resize(img2, (target_width, target_height), interpolation=cv2.INTER_AREA)

    # 计算平均 MSE 和 PSNR
    results = process_rgb_psnr(img1_resized, img2_resized)
    print(f"PSNR: {results['PSNR']:.3f} dB")

# 程序入口
image1 = ''
image2 = ''
main(image1, image2)

结构相似性指数 Structural Similarity Index

功能

SSIM 不仅关注像素值之间的差异,还考虑了图像的结构信息(例如纹理、亮度和对比度),因此更加符合人类视觉感知。值越大,表明图像越相同。

特点

更符合人眼视觉感知:SSIM 考虑了图像的亮度、对比度和结构信息,模拟了人眼对图像的感知,因此它的评估结果更符合人类的主观感知。

不受单纯像素差异影响:不同于 MSE 和 PSNR,SSIM 更注重结构信息,因此对于相同的均方误差,SSIM 能提供更精确的质量评估。

局部结构信息:SSIM 是局部计算的,通常通过在图像中滑动一个小窗口(例如 8x8 或 11x11 的窗口),逐块计算图像的结构相似性。

综合评价:通过整幅图像的局部SSIM值来得到整体的相似性评估。

单位:SSIM值的范围通常在0到1之间,

公式

SSIM(x,y)=(2μxμy+C1)(2σxy+C2)(μx2+μy2+C1)(σx2+σy2+C2)其中:x和y是两张图像(原始图像和重建图像)的局部图像块(一般是滑动窗口的区域)。μx和μy是图像x和y块的平均值(亮度信息)。σx2和σy2是图像块x和y的方差(对比度信息)。σxy是图像x和y块之间的协方差(结构信息)。C1和C2是常数,用于避免分母为零的情况,通常选择C1=(K1L)2和C2=(K2L)2,其中L是像素值的动态范围,K1和K2是常数。 SSIM(x, y) = \frac{(2 \mu_x \mu_y + C_1)(2 \sigma_{xy} + C_2)}{(\mu_x^2 + \mu_y^2 + C_1)(\sigma_x^2 + \sigma_y^2 + C_2)} \\ 其中: x 和 y 是两张图像(原始图像和重建图像)的局部图像块(一般是滑动窗口的区域)。\\ \mu_x 和 \mu_y 是图像 x和 y 块的平均值(亮度信息)。\\ \sigma_x^2 和\sigma_y^2 是图像块 x 和 y 的方差(对比度信息)。\\ \sigma_{xy} 是图像 x 和 y 块之间的协方差(结构信息)。\\ C_1 和 C_2 是常数,用于避免分母为零的情况,通常选择 C_1 = (K_1 L)^2 和 C_2 = (K_2 L)^2 ,\\ 其中 L 是像素值的动态范围, K_1 和 K_2 是常数。 SSIM(x,y)=(μx2+μy2+C1)(σx2+σy2+C2)(2μxμy+C1)(2σxy+C2)xyμxμyxyσx2σy2xyσxyxyC1C2C1=(K1L)2C2=(K2L)2LK1K2

代码实现(Python)

借助scikit-image库实现,逐通道计算,求平均

from skimage.metrics import structural_similarity as ssim
import cv2

def calculate_ssim(image1, image2):
    """
    计算两幅图像的 SSIM(结构相似性指数),逐通道计算 RGB 的 SSIM。
    综合 SSIM 值(平均 SSIM)。
    """
    # 确保输入的图像尺寸相同
    assert image1.shape == image2.shape, "两幅图像的尺寸必须相同"
    
    # 分离 RGB 通道
    r1, g1, b1 = cv2.split(image1)
    r2, g2, b2 = cv2.split(image2)
    
    # 计算每个通道的 SSIM
    ssim_r = ssim(r1, r2)
    ssim_g = ssim(g1, g2)
    ssim_b = ssim(b1, b2)
    
    # 计算总体 SSIM(三个通道的平均值)
    overall_ssim = (ssim_r + ssim_g + ssim_b) / 3
    return overall_ssim

def main(image_path1, image_path2):
    """
    主函数,读取图像并计算 SSIM。
    """
    # 读取图像(RGB 图像)
    img1 = cv2.imread(image_path1, cv2.IMREAD_COLOR)
    img2 = cv2.imread(image_path2, cv2.IMREAD_COLOR)

    if img1 is None or img2 is None:
        print("无法加载图像,请检查文件路径!")
        return

    # 调整图像大小为相同
    h1, w1 = img1.shape[:2]
    h2, w2 = img2.shape[:2]
    target_height = min(h1, h2)
    target_width = min(w1, w2)
    img1_resized = cv2.resize(img1, (target_width, target_height), interpolation=cv2.INTER_AREA)
    img2_resized = cv2.resize(img2, (target_width, target_height), interpolation=cv2.INTER_AREA)

    # 计算 SSIM
    ssim_value = calculate_ssim(img1_resized, img2_resized)
    print(f"SSIM: {ssim_value:.6f}")

# 程序入口
image1 = ''
image2 = ''
main(image1, image2)

### MSEPSNRSSIM 的定义、计算方法及应用场景 #### 1. 均方误差 (Mean Square Error, MSE) MSE 是衡量两幅图像之间差异的最基本指标之一。它通过计算当前图像 \(X\) 参考图像 \(Y\) 在每个像素位置上的误差平方平均值来表示两者之间的差异。其公式为: \[ MSE = \frac{1}{H \cdot W} \sum_{i=1}^{H} \sum_{j=1}^{W} (X(i,j) - Y(i,j))^2 \] 其中,\(H\) \(W\) 分别表示图像的高度宽度[^3]。 - **定义**: MSE 表示图像间的均方误差,数值越小,说明两幅图像越接近。 - **计算方法**: 对于灰度图像或彩色图像的每个通道,逐像素计算误差平方并取平均值。 - **应用场景**: MSE常用于评估图像重建或压缩后的失真程度。然而,由于其对人眼感知的敏感性较差,单独使用时可能无法准确反映图像质量。 --- #### 2. 峰值信噪比 (Peak Signal-to-Noise Ratio, PSNR) PSNR 是基于 MSE 的一种图像质量评价指标常用于衡量图像压缩或重建后的质量。其公式为: \[ PSNR = 10 \cdot \log_{10} \left( \frac{L^2}{MSE} \right) \] 其中,\(L\) 是图像的最大像素值(对于8位图像,\(L = 255\))[^3]。 - **定义**: PSNR 表示信号峰值与噪声的比例,单位为分贝(dB)。数值越大,图像质量越好。 - **计算方法**: 首先计算 MSE,然后根据上述公式转换为 PSNR- **应用场景**: PSNR 广泛应用于图像压缩、视频编码等领域,用于量化图像失真程度。但需要注意的是,PSNR 主要关注像素级误差,可能无法完全反映人眼感知的质量。 以下是一个 MATLAB 实现 PSNR 的代码示例: ```matlab function [PSNR, MSE] = psnr(X, Y) if size(X,3) ~= 1 org = rgb2ycbcr(X); test = rgb2ycbcr(Y); Y1 = double(org(:,:,1)); Y2 = double(test(:,:,1)); else Y1 = double(X); Y2 = double(Y); end if any(size(Y1) ~= size(Y2)) error('The input size is not equal, please check'); end D = Y1 - Y2; MSE = sum(D(:).^2) / numel(Y1); PSNR = 10 * log10(255^2 / MSE); end ``` --- #### 3. 结构相似性 (Structural Similarity Index, SSIM) SSIM 是一种更贴近人眼感知的图像质量评价指标,综合考虑了亮度、对比度结构信息。其公式为: \[ SSIM(x, y) = \frac{(2\mu_x\mu_y + C_1)(2\sigma_{xy} + C_2)}{(\mu_x^2 + \mu_y^2 + C_1)(\sigma_x^2 + \sigma_y^2 + C_2)} \] 其中: - \(\mu_x\) \(\mu_y\) 分别是图像 \(x\) \(y\) 的均值; - \(\sigma_x^2\) \(\sigma_y^2\) 分别是图像 \(x\) \(y\) 的方差; - \(\sigma_{xy}\) 是图像 \(x\) \(y\) 的协方差; - \(C_1\) \(C_2\) 是为了防止分母为零而引入的小常数[^2]。 - **定义**: SSIM 衡量两幅图像在结构上的相似性,取值范围为 \([-1, 1]\),数值越接近 1,图像越相似。 - **计算方法**: 使用窗口滑动的方式局部计算 SSIM,并取全局平均值。 - **应用场景**: SSIM 更适合用于需要考虑人眼感知的应用场景,例如图像增强、去噪、超分辨率重建等。 以下是一个 MATLAB 实现 SSIM 的代码示例: ```matlab function ssim_val = ssim(X, Y) % 参数设置 K1 = 0.01; K2 = 0.03; L = 255; % 图像最大灰阶值 C1 = (K1*L)^2; C2 = (K2*L)^2; % 转换为双精度类型 X = double(X); Y = double(Y); % 计算均值、方差协方差 mu_X = imfilter(X, fspecial('gaussian', [11 11], 1.5), 'same'); mu_Y = imfilter(Y, fspecial('gaussian', [11 11], 1.5), 'same'); sigma_X = imfilter(X.^2, fspecial('gaussian', [11 11], 1.5), 'same') - mu_X.^2; sigma_Y = imfilter(Y.^2, fspecial('gaussian', [11 11], 1.5), 'same') - mu_Y.^2; sigma_XY = imfilter(X.*Y, fspecial('gaussian', [11 11], 1.5), 'same') - mu_X.*mu_Y; % 计算 SSIM ssim_map = ((2*mu_X.*mu_Y + C1).*(2*sigma_XY + C2)) ./ ... ((mu_X.^2 + mu_Y.^2 + C1).*(sigma_X + sigma_Y + C2)); ssim_val = mean(ssim_map(:)); end ``` --- ### 总结 - **MSE** 是最基础的误差指标,数值越小越好,但对人眼感知不敏感。 - **PSNR** 是基于 MSE 的改进指标,以 dB 为单位,数值越大越好,适用于量化像素级误差- **SSIM** 综合考虑了亮度、对比度结构信息,数值越接近 1 越好,更适合用于人眼感知相关的应用。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ayu阿予

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值