我想估计图像中的噪声。
让我们假设一个图像+白噪声的模型。现在我想估计噪声方差。
我的方法是计算图像的局部方差(3*3 到 21*21 块),然后找到局部方差相当恒定的区域(通过计算局部方差矩阵的局部方差)。我假设这些区域是“平坦的”,因此方差几乎是“纯”噪声。
然而,我并没有得到持续的结果。
有没有更好的办法?
谢谢。
PS我不能假设任何关于图像的信息,但独立噪声(这对于真实图像来说不是真的,但让我们假设它)。
我想估计图像中的噪声。
让我们假设一个图像+白噪声的模型。现在我想估计噪声方差。
我的方法是计算图像的局部方差(3*3 到 21*21 块),然后找到局部方差相当恒定的区域(通过计算局部方差矩阵的局部方差)。我假设这些区域是“平坦的”,因此方差几乎是“纯”噪声。
然而,我并没有得到持续的结果。
有没有更好的办法?
谢谢。
PS我不能假设任何关于图像的信息,但独立噪声(这对于真实图像来说不是真的,但让我们假设它)。
您可以使用以下方法来估计噪声方差(此实现仅适用于灰度图像):
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,“快速噪声方差估计”,计算机视觉和图像理解,卷。64,第 2 期,第 300-302 页,1996 年 9 月 [ PDF ]
从噪声中表征信号的问题并不容易。根据您的问题,第一次尝试是描述二阶统计数据:已知自然图像具有像素到像素的相关性,根据定义,白噪声中不存在这些相关性。
在傅立叶空间中,相关性对应于能谱。众所周知,对于自然图像,它会减少 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
我推荐这篇精彩的论文以获取更多详细信息。
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)
高数字意味着低噪音。