WSNR(加权信噪比)是如何定义的?

信息处理 图像处理 计算机视觉 Python 信噪比 图像恢复
2022-02-24 04:16:05

我正在研究图像之间的比较以确定质量。我已经了解了 MSE、SNR 和 PSNR,现在我正在尝试了解 WSNR,我认为它类似于 SNR,但具有权重。

我有一个 Python 代码来计算两个图像之间的 WSNR,但我并不完全理解它,也不知道这个度量的数学定义是什么。我找不到任何解释它是如何定义和计算的论文或书籍。

问题:

WSNR(加权信噪比)是如何定义的?

蟒蛇代码:

import numpy as np
from scipy.ndimage.filters import gaussian_filter as __gaussian_filter
from scipy.ndimage.filters import convolve as __convolve
from scipy.ndimage.filters import correlate as __correlate
from scipy.fftpack import fftshift as __fftshift

def wsnr(reference, query):
"""Computes the Weighted Signal to Noise Ratio (WSNR) metric.

    value = wsnr(reference, query)

    inputs
    ----------
    reference: original image data.
    query    : modified image data to be compared.

    output
    ----------
    value    : wsnr value
    """
    def __genetate_meshgrid(x, y):
        f = lambda u: u / 2 + 0.5 - 1
        (H, W) = map(f, (x, y))
        return (H, W)

    def __create_complex_planes(x, y):
        (H, W) = __genetate_meshgrid(x, y)
        (xplane, yplane) = np.mgrid[-H:H + 1, -W:W + 1]
        return (xplane, yplane)

    def __get_evaluated_contrast_sensivity(plane):
        w = 0.7
        angle = np.angle(plane)
        return ((1.0 - w) / 2.0) * np.cos(4.0 * angle) + (1.0 + w) / 2.0

    def __get_radial_frequency(x, y):
        (xplane, yplane) = __create_complex_planes(x, y)
        nfreq = 60
        plane = (xplane + 1.0j * yplane) / x * 2.0 * nfreq
        s = __get_evaluated_contrast_sensivity(plane)
        radfreq = abs(plane) / s
        return radfreq

    def __generate_CSF(radfreq):
        a = -((0.114 * radfreq) ** 1.1)
        csf = 2.6 * (0.0192 + 0.114 * radfreq) * np.exp(a)
        f = radfreq < 7.8909
        csf[f] = 0.9809
        return csf

    def __weighted_fft_domain(ref, quer, csf):
        err = ref.astype('double') - quer.astype('double')
        err_wt = __fftshift(np.fft.fft2(err)) * csf
        im = np.fft.fft2(ref)
        return (err, err_wt, im)

    def __get_weighted_error_power(err_wt):
        return (err_wt * np.conj(err_wt)).sum()

    def __get_signal_power(im):
        return (im * np.conj(im)).sum()

    def __get_ratio(mss, mse):
        if mse != 0:
            ratio = 10.0 * np.log10(mss / mse)
        else:
            ratio = float("inf")
        return np.real(ratio)

    if not len(reference.shape) < 3:
        reference = __convert_to_luminance(reference)
        query = __convert_to_luminance(query)
    size = reference.shape
    (x, y) = (size[0], size[1])
    radfreq = __get_radial_frequency(x, y)
    csf = __generate_CSF(radfreq)
    (err, err_wt, im) = __weighted_fft_domain(reference, query, csf)
    mse = __get_weighted_error_power(err_wt)
    mss = __get_signal_power(im)
    ratio = __get_ratio(mss, mse)
    return ratio
1个回答

可能有几个版本,但最可能的版本如下。SNR 是一种与能量相关的度量。在时间或空间域中,它与位置无关:所有样本都具有相同的“权重”(统一权重)。作为一种能量测量,它也可以在傅立叶域中计算(或任何正交变换)。

然后,从感觉系统中,我们知道在听觉或视觉中,并非所有频率都具有相同的感知权重:人类听到 35 kHz 响亮的音调可能不会注意到它,而蝙蝠或狗会注意到。因此,声音的相对重要性应该由主体(蝙蝠、狗、人类)的感知敏感度来衡量。这会在不同的频率上产生不同的权重。与 [1-2] kHz 频段相比,人耳不应关心 35 kHz 的音调,并给予它一点权重。视力也是如此。例如,在 JPEG 压缩中使用了这种权重。

因此,在频域中不是计算,而是一些:

10logk(sk^nk^)2sk^2
k频率区间的索引,您可以为每个区间使用预定义的权重k
10logkwk(sk^nk^)2sk^2,
在哪里 wk对不太重要的频率给予较小的权重。在声音中,您可以找到A 加权曲线(以及 B-、C-、D- 和 Z-)。

在图像中,Matlab 代码函数 ratio = wsnr(orig, dith, nfreq ) 给出了对古代论文的引用: