消除图像模糊

2024-04-25 14:36:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用Python去模糊图像,但是遇到了一些问题。以下是我尝试过的,但请记住,我不是这方面的专家。根据我的理解,如果你知道点扩散函数,你应该可以很简单地通过反褶积来消除图像的模糊。然而,这似乎不起作用,我不知道我是在做蠢事,还是只是没有正确理解事情。在marknewman的计算物理书(使用Python)中,他在问题7.9中谈到了这个问题。在这个问题中,他提供了一个图像,他故意模糊使用高斯点扩散函数(psf),问题的目标是用高斯函数去模糊图像。这是通过将模糊图像的2D-FFT除以psf的2D-FFT,然后进行逆变换来实现的。这相当好用。在

为了扩展这个问题,我想去模糊一个用相机拍摄的故意失焦的真实图像。所以我安装了一个照相机,拍了两组照片。第一组照片对焦了。第一个是一个非常小的LED灯在一个完全黑暗的房间,第二个是一张纸,上面有文字(使用闪光灯)。然后,在没有改变任何距离或任何东西的情况下,我改变了相机上的焦距设置,这样文本就非常不对焦了。然后我用闪光灯拍了一张文字照片,然后拍了第二张LED照片(不带闪光灯)。这是模糊的图像。在

Blurred Text

Blurred Point Light Source

现在,根据我的理解,模糊点光源的图像应该是点扩散函数,因此我应该可以用它来消除图像的模糊。问题是,当我这样做的时候,我得到的图像看起来就像噪音。在做了一点研究之后,似乎在使用反褶积技术时,噪声可能是一个大问题。然而,鉴于我已经测量了我认为是精确的点扩散函数,我很惊讶噪声在这里会成为一个问题。在

我做过的一件事是用1或epsilon替换psf变换中的小值(小于epsilon),我尝试用epsilon的大范围值来代替它。这产生的图像不仅是噪声,而且也不是图像的去模糊版本;它看起来像原始(非模糊)图像的怪异、模糊版本。这是我的程序中的一个图像(你可以忽略sigma的值,它在这个程序中没有使用)。在

enter image description here

我相信我正在处理噪音问题,但我不知道为什么,也不知道该怎么做。任何建议都将不胜感激(记住,我不是这方面的专家)。在

请注意,我故意没有发布代码,因为我认为这在这一点上有些不相干。但如果有人认为这是有用的,我很乐意这样做。我不认为这是一个编程问题,因为我使用了相同的技术,当我有已知的点扩展函数时,它工作得很好(例如,当我将原始聚焦图像的FFT除以离焦图像的FFT,然后进行逆变换)。我只是不明白为什么我不能使用我的实验测量点扩散函数。在


Tags: 函数图像fft版本led噪声照片技术
1条回答
网友
1楼 · 发布于 2024-04-25 14:36:39

不幸的是,你想解决的问题比你想象的要困难。让我分四个部分来解释。第一部分假设您熟悉傅立叶变换。在

  1. 为什么你不能用一个简单的反褶积来解决这个问题。在
  2. 如何进行图像去模糊的概述。在
  3. FFT反褶积及其不好的原因
  4. 反褶积的另一种方法

但是首先,一些符号:

我用I来表示图像,K来表示卷积核。I*K是图像I与核K的卷积。F(I)是图像I的(n维)Fourier变换,F(K)是卷积核的傅立叶变换(这也称为点扩展函数,或PSF)。类似地,Fi是傅里叶逆变换。在

为什么你不能用简单的反褶积来解决这个问题:

你说的对,我们可以用Fourier变换除以Fourier变换来恢复模糊图像。然而,镜头模糊不是卷积模糊操作。这是一种改进的卷积模糊操作,其中模糊内核K取决于与拍摄对象的距离。因此,内核从一个像素变为一个像素。在

您可能认为这不是您的映像的问题,因为您已经在映像的位置测量了正确的内核。然而,情况可能并非如此,因为图像中距离较远的部分可能会影响图像中靠近的部分。解决此问题的一种方法是裁剪图像,使其只显示纸张。在

为什么FFT反褶积是个坏主意:

卷积定理说明I*K=FiF(I)F(K))。这个定理给出了一个合理的假设:如果我们有一个被卷积核模糊的图像,Ib=I*K,那么我们可以通过计算I=(F(Ib)/F(K))来恢复模糊图像。在

在我们看为什么这是一个坏主意之前,我想得到一些关于卷积定理的直觉。当我们用一个核来卷积一个图像时,这与取图像的频率分量并将其与核的频率分量相乘是一样的。在

现在,让我解释一下为什么用FFT去卷积图像是困难的。默认情况下,模糊会删除高频信息。因此,K的高频必须趋于零。其原因是当模糊时,I的高频信息丢失,因此Ib的高频分量必须归零。要做到这一点,K的高频分量也必须归零。在

由于K的高频分量几乎为零,我们发现当我们用FFT去卷积时,Ib的高频分量被显著放大(我们几乎被零除)。在无噪音的情况下,这不是问题。在

然而,在嘈杂的情况下,这是一个问题。其原因是,根据定义,噪声是高频信息。因此,当我们试图去卷积Ib时,噪声几乎被无限放大。这就是FFT反褶积不是一个好主意的原因。在

此外,您需要考虑基于FFT的卷积算法如何处理边界条件。通常,当我们卷积图像时,分辨率会有所降低。这是不需要的行为,所以我们引入边界条件指定图像外部像素的像素值。此类边界条件的示例如下

  1. 图像外部的像素值与图像内部最近的像素值相同
  2. 图像外部的像素有一个常量值(例如0)
  3. 图像是周期信号的一部分,因此最上面一行的像素行等于最下面的一行像素。在

最后的边界条件通常对一维信号有意义。然而,对于图像来说,这没什么意义。不幸的是,卷积定理规定使用周期性边界条件。在

除此之外,基于FFT的反演方法似乎比迭代方法(如梯度下降和FISTA)对错误核更敏感。在

反褶积的另一种方法

现在似乎所有的希望都破灭了,因为所有的图像都是嘈杂的,而解卷积将增加噪声。然而,情况并非如此,因为我们有迭代方法来执行反褶积。首先让我向您展示最简单的迭代方法。在

| | I |²是所有I像素的平方和。解方程

Ib=I*K

对于,I等于解决了以下优化问题:

最小L(I)=最小| | I*K-Ib | |²

关于I。这可以通过梯度下降来实现,因为L的梯度由

DL=Q*(I*K-Ib)

其中Q是通过转置K得到的核(这在信号处理中也称为匹配滤波器)。在

因此,您可以得到以下迭代算法,将去模糊的图像。在

from scipy.ndimage import convolve

blurred_image = # Load image
kernel = # Load kernel/psf
learning_rate = # You need to find this yourself, do a logarithmic line search. Small rate will always converge, but slowly. Start with 0.4 and divide by 2 every time it fails.
maxit = 100

def loss(image):
    return np.sum(convolve(image, kernel) - blurred_image)

def gradient(image):
    return convolve(convolve(image, kernel) - blurred_image)

deblurred = blurred_image.copy()
for _ in range(maxit):
    deblurred -= learning_rate*gradient(image)

上述方法可能是迭代反褶积算法中最简单的一种。这些方法在实际中的使用是通过所谓的正则化反褶积算法。这些算法首先指定一个测量图像中噪声量的函数,例如TV(I)(即I的总变化)。然后对L(I)+wTV(I)执行优化程序。如果你对这类算法感兴趣,我建议你阅读阿米尔·贝克和马克·泰布尔的FISTA论文。这篇论文数学性很强,但你不需要了解其中大部分内容,只需了解如何实现电视去模糊算法。在

除了使用正则化器,我们还使用加速方法来最小化损失L(I)。一个这样的例子是Nesterov加速梯度下降。关于这些方法的信息,请参阅Brendan O'Donoghue,Emmanuel Candes的加速梯度方案的自适应重启。在

如何进行图像去模糊的概述

  1. 裁剪你的图像,使所有东西与相机的距离相同
  2. 像现在一样找到卷积核(首先在合成模糊图像上测试你的反褶积算法)
  3. 实现一种迭代方法来计算反褶积
  4. 对图像进行反褶积。在

相关问题 更多 >