估计图像的信噪比

Estimating signal to noise ratio of an image

我正在尝试对图像进行降噪。我想通过查看信噪比值来了解它是否已降噪。现在,我如何估计 Python 中图像的信噪比?

SNR is defined in different ways,但我想对于您的应用程序,它的确切定义并不重要。一般来说,它是信号强度与噪声强度的比值。 "Strength"这里故意不明确,经常用到信号的功率和噪声,但幅值也是可行的。

然后我们假设 SNR 是图像信号的功率除以噪声信号的功率。噪声的强度就是它的方差。您正在比较去噪前后的图像,因此大概信号的功率不会改变。我们可以忽略它并将其设置为1。现在我们的SNR简单地定义为1/var(noise).

所以,你需要做的是估计噪声方差,并比较去噪前后的差异。您希望看到此方差下降(随着 SNR 的增加)。

一般来说,如果不知道没有噪声的图像是什么样子,估计图像的噪声方差是不容易的。您可以将噪声图像视为

image = noiseless_image + noise.

所以,图像的方差是有噪声的方差+无噪声图像的方差。不知道后者,就得不到前者。

不过也是有技巧的。最简单的方法,如果你愿意为你比较的每张图像做一些手工工作,就是勾勒出一个平坦的背景区域(通常一小块天空区域就可以)。非常重要的是,该区域的强度没有自然变化。现在简单地计算这个区域内像素的方差。

为此已发布了多种全自动方法。我知道 J. Immerkær 的一篇文章:"Fast Noise Variance Estimation",计算机视觉和图像理解 64(2):300-302, 1996。DIPlib 库(我是作者)有 an implementation。您可以从 Python 使用它,如下所示:

var = dip.EstimateNoiseVariance(img)

img 来自库的图像对象,或 Numpy 数组,或任何其他公开缓冲区的对象)。但是,由于尚未正式发布具有 Python 绑定的库版本,如果要使用此实现,则必须自己获取和编译库。不过考虑到是比较简单的方法,你可以考虑自己实现一下。

这是该方法的伪代码:

mask = gradient magnitude of img
Apply Gaussian smoothing (sigma = 3) to mask
If the image has more than one channel:
   mask = max over the channels
Compute the Otsu threshold value for mask
mask = pixels where mask < threshold

error = discrete Laplace of in: apply convolution with [1,-2,1;-2,4,-2;1,-2,1]
MSE = the mean square value of the pixels in error that fall within mask, on a per-channel basis
If the image has more than one channel:
   MSE = mean over MSE values for each channel
variance = MSE / 36