问题 图像噪声估计/噪声测量


我想估计图像中的噪点。

让我们假设一个图像+白噪声的模型。 现在我想估计噪声方差。

我的方法是计算图像的局部方差(3 * 3到21 * 21块),然后找到局部方差相当恒定的区域(通过计算局部方差矩阵的局部方差)。 我假设这些区域是“平坦的”,因此方差几乎是“纯”噪声。

然而,我没有得到持续的结果。

有没有更好的办法?

谢谢。

附: 我不能假设任何关于图像但是独立的噪声(对于真实图像不是这样,但我们假设它)。


1939
2018-03-13 23:32


起源



答案:


您可以使用以下方法估计噪声方差(此实现仅适用于灰度图像):

def estimate_noise(I):

  H, W = I.shape

  M = [[1, -2, 1],
       [-2, 4, -2],
       [1, -2, 1]]

  sigma = np.sum(np.sum(np.absolute(convolve2d(I, M))))
  sigma = sigma * math.sqrt(0.5 * math.pi) / (6 * (W-2) * (H-2))

  return sigma

参考文献:J.Immerkær,“Fast Noise Variance Estimation”,Computer Vision and Image Understanding,Vol。 64,第2期,第300-302页,1996年9月[PDF]


7
2017-08-21 21:18



谢谢。我会试一试。 - Royi
这实际上有效!如果你得到sigma> 10.0,那么你有一个嘈杂的图像,否则 - 不是。此外,为了使其适用于彩色图像,只需将它们转换为灰度,如下所示: import cv2  img = cv2.imread(img_path)  img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  noise = estimate_noise(img_gray) - tsveti_iko
别忘了 import math, import numpy as np 和 from scipy.signal import convolve2d ;) - tsveti_iko
提供的PDF链接也不起作用 - 请改用: sciencedirect.com/science/article/pii/S1077314296900600 - tsveti_iko


答案:


您可以使用以下方法估计噪声方差(此实现仅适用于灰度图像):

def estimate_noise(I):

  H, W = I.shape

  M = [[1, -2, 1],
       [-2, 4, -2],
       [1, -2, 1]]

  sigma = np.sum(np.sum(np.absolute(convolve2d(I, M))))
  sigma = sigma * math.sqrt(0.5 * math.pi) / (6 * (W-2) * (H-2))

  return sigma

参考文献:J.Immerkær,“Fast Noise Variance Estimation”,Computer Vision and Image Understanding,Vol。 64,第2期,第300-302页,1996年9月[PDF]


7
2017-08-21 21:18



谢谢。我会试一试。 - Royi
这实际上有效!如果你得到sigma> 10.0,那么你有一个嘈杂的图像,否则 - 不是。此外,为了使其适用于彩色图像,只需将它们转换为灰度,如下所示: import cv2  img = cv2.imread(img_path)  img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  noise = estimate_noise(img_gray) - tsveti_iko
别忘了 import math, import numpy as np 和 from scipy.signal import convolve2d ;) - tsveti_iko
提供的PDF链接也不起作用 - 请改用: sciencedirect.com/science/article/pii/S1077314296900600 - tsveti_iko


从噪声中表征信号的问题并不容易。根据您的问题,第一次尝试将表征二阶统计量:已知自然图像具有像素到像素的相关性,这些相关性按照定义 - 不存在于白噪声中。

在傅里叶空间中,相关性对应于能谱。众所周知,对于自然图像,它减少为1 / f ^ 2。为了量化噪声,我建议用两个假设(平面和1 / f ^ 2)计算图像光谱的相关系数,以便提取系数。

一些启动你的功能:

import numpy
def get_grids(N_X, N_Y):
    from numpy import mgrid
    return mgrid[-1:1:1j*N_X, -1:1:1j*N_Y]

def frequency_radius(fx, fy):
    R2 = fx**2 + fy**2
    (N_X, N_Y) = fx.shape
    R2[N_X/2, N_Y/2]= numpy.inf

    return numpy.sqrt(R2)

def enveloppe_color(fx, fy, alpha=1.0):
    # 0.0, 0.5, 1.0, 2.0 are resp. white, pink, red, brown noise
    # (see http://en.wikipedia.org/wiki/1/f_noise )
    # enveloppe
    return 1. / frequency_radius(fx, fy)**alpha #

import scipy
image = scipy.lena()
N_X, N_Y = image.shape
fx, fy = get_grids(N_X, N_Y)
pink_spectrum = enveloppe_color(fx, fy)

from scipy.fftpack import fft2
power_spectrum = numpy.abs(fft2(image))**2

我建议 这篇精彩的论文 更多细节。


4
2018-03-14 13:09



为了让事情更清楚,我们假设我有一个Image Matrix - I.在Matlab语法中我会写:NoisyImage = I + 5 * randn(size(I));现在,我想估计噪音的方差 - 25(假设I没有噪音)。现在,该方法应该是可靠的,具有更小的噪声因子(方差),然后在某种程度上估计实际图像的噪声水平(使用独立噪声模型)谢谢。附:你能指出我在哪篇文章中找到它吗?你认识其他人吗? - Royi
您是否愿意全面参考该论文?你提供的链接现在已经死了。谢谢。 - P-Gn
@ user1735003也许是这篇论文: redwood.berkeley.edu/w/images/6/69/08-atick-nc-1992.pdf  (只是从死链接url的假设) - Olia_Pavliuk
感谢注意到死链接,我解决了! - meduz


Scikit Image有一个估计sigma函数,效果很好:

http://scikit-image.org/docs/dev/api/skimage.restoration.html#skimage.restoration.estimate_sigma

它也适用于彩色图像,你只需要设置 multichannel=True 和 average_sigmas=True

import cv2
from skimage.restoration import estimate_sigma

def estimate_noise(image_path):
    img = cv2.imread(image_path)
    return estimate_sigma(img, multichannel=True, average_sigmas=True)

高数字意味着低噪音。


1
2018-06-26 22:13



嗨,确实有Donoho的方法基于小波(HH的力量中位数)。我可以在MATLAB中添加它的实现。谢谢。 - Royi