代码之家  ›  专栏  ›  技术社区  ›  Royi

图像中的噪声估计/噪声测量

  •  13
  • Royi  · 技术社区  · 16 年前

    我想估计图像中的噪声。

    假设图像+白噪声的模型。 现在我要估计噪声方差。

    我的方法是计算图像的局部方差(3*3到21*21块),然后找到局部方差相当恒定的区域(通过计算局部方差矩阵的局部方差)。

    但我没有得到固定的结果。

    有更好的办法吗?

    附笔。 除了独立的噪声,我不能对图像做任何假设(这对于真实的图像是不正确的,让我们假设它)。

    3 回复  |  直到 16 年前
        1
  •  18
  •   user2398029    12 年前

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

    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。Immerkr,快速噪声方差估计,计算机视觉和图像理解,第64卷,第2期,第300-302页,1996年9月[ PDF

        2
  •  5
  •   meduz    8 年前

    从噪声中表征信号的问题并不容易。从你的问题来看,第一个尝试是描述二阶统计量:自然图像已知具有像素到像素的相关性,而根据定义,这种相关性不存在于白噪声中。

    一些启动功能:

    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
    

    this wonderful paper 更多细节。

        3
  •  3
  •   lotif    8 年前

    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)
    

    推荐文章