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

发布于 2024-08-24 16:04:05 字数 260 浏览 12 评论 0原文

我想估计图像中的噪声。

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

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

但我没有得到持续的结果。

有更好的办法吗?

谢谢。

聚苯乙烯 除了独立噪声之外,我无法对图像进行任何假设(这对于真实图像来说并不成立,但让我们假设它)。

I want to estimate the noise in an image.

Let's assume the model of an Image + White Noise.
Now I want to estimate the Noise Variance.

My method is to calculate the Local Variance (3*3 up to 21*21 Blocks) of the image and then find areas where the Local Variance is fairly constant (By calculating the Local Variance of the Local Variance Matrix).
I assume those areas are "Flat" hence the Variance is almost "Pure" noise.

Yet I don't get constant results.

Is there a better way?

Thanks.

P.S.
I can't assume anything about the Image but the independent noise (Which isn't true for real image yet let's assume it).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

自此以后,行同陌路 2024-08-31 16:04:05

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

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 ]

You can use the following method to estimate the noise variance (this implementation works for grayscale images only):

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

Reference: J. Immerkær, “Fast Noise Variance Estimation”, Computer Vision and Image Understanding, Vol. 64, No. 2, pp. 300-302, Sep. 1996 [PDF]

雄赳赳气昂昂 2024-08-31 16:04:05

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

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

它也适用于彩色图像,您只需设置 multichannel=Trueaverage_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)

数字高意味着噪音低。

Scikit Image has an estimate sigma function that works pretty well:

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

it also works with color images, you just need to set multichannel=True and 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)

High numbers mean low noise.

千と千尋 2024-08-31 16:04:05

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

在傅立叶空间中,相关性对应于能谱。众所周知,对于自然图像,它减小为 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

我推荐这个精彩论文了解更多详细信息。

The problem of characterizing signal from noise is not easy. From your question, a first try would be to characterize second order statistics: natural images are known to have pixel to pixel correlations that are -by definition- not present in white noise.

In Fourier space the correlation corresponds to the energy spectrum. It is known that for natural images, it decreases as 1/f^2 . To quantify noise, I would therefore recommend to compute the correlation coefficient of the spectrum of your image with both hypothesis (flat and 1/f^2), so that you extract the coefficient.

Some functions to start you up:

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

I recommend this wonderful paper for more details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文