【问题标题】:Deblurring an image去模糊图像
【发布时间】:2019-05-13 14:09:29
【问题描述】:

我正在尝试在 Python 中对图像进行去模糊处理,但遇到了一些问题。这是我尝试过的方法,但请记住,我不是该主题的专家。根据我的理解,如果你知道点扩散函数,你应该可以很简单地通过执行反卷积来对图像进行去模糊。但是,这似乎不起作用,我不知道我是否在做一些愚蠢的事情,或者我只是没有正确理解事情。在 Mark Newman 的 Computational Physics 书(使用 Python)中,他在问题 7.9 中触及了这个主题。在这个问题中,他提供了一个他故意使用高斯点扩散函数 (psf) 模糊的图像,并且该问题的目标是使用高斯对图像进行去模糊。这是通过将模糊图像的 2D FFT 除以 psf 的 2D FFT 然后进行逆变换来实现的。这工作得相当好。

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

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

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

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

请注意,我故意不发布代码,因为我认为此时这有点无关紧要。但如果有人认为这很有用,我会很乐意这样做。我不认为这是一个编程问题,因为我使用了相同的技术,并且当我具有已知的点扩散函数时它工作正常(例如当我将原始对焦图像的 FFT 除以失焦图像的 FFT 时) -聚焦图像,然后进行逆变换)。我只是不明白为什么我似乎无法使用实验测量的点扩散函数。

【问题讨论】:

    标签: python image-processing deconvolution


    【解决方案1】:

    不幸的是,您试图解决的问题比您预期的要困难。让我分四个部分来解释。第一部分假设您熟悉傅里叶变换。

    1. 为什么不能通过简单的反卷积来解决这个问题。
    2. 如何执行图像去模糊的概述。
    3. FFT 反卷积以及为什么这是一个坏主意
    4. 另一种执行反卷积的方法

    但首先,一些符号:

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

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

    你说得对,我们可以通过将 Ib 的傅里叶变换除以 的傅里叶变换来恢复模糊图像 Ib = I * K。然而,镜头模糊不是卷积模糊操作。它是一种改进的卷积模糊操作,其中模糊内核 K 取决于到您拍摄的对象的距离。因此,内核会随着像素的变化而变化。

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

    为什么 FFT 去卷积是个坏主意:

    卷积定理指出 I * K = Fi(F(I)F (K))。这个定理导致了一个合理的假设,如果我们有一个图像 Ib = I * K 被卷积核 K 模糊,那么我们可以通过以下方式恢复去模糊的图像计算I = (F(Ib)/F(K))

    在我们了解为什么这是一个坏主意之前,我想先了解一下卷积定理的含义。当我们将图像与内核进行卷积时,这与获取图像的频率分量并将其与内核的频率分量相乘是相同的。

    现在,让我解释一下为什么很难使用 FFT 对图像进行反卷积。默认情况下,模糊会删除高频信息。因此,K 的高频必须趋近于零。原因是I的高频信息在模糊时丢失了——因此,Ib的高频成分必然趋于零。为此,K 的高频分量也必须趋近于零。

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

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

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

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

    最终的边界条件通常对一维信号有意义。然而,对于图像来说,它没有多大意义。不幸的是,卷积定理指定使用周期性边界条件。

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

    另一种执行反卷积的方法

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

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

    Ib = I * K

    关于 I 就等价于解决以下优化问题:

    min L(I) = min ||I * K - Ib||²

    关于。这可以使用梯度下降来完成,因为 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)上执行优化过程。如果您对此类算法感兴趣,我建议您阅读 Amir Beck 和 Marc Teboulle 的 FISTA 论文。这篇论文的数学很重,但你不需要理解大部分内容——只需要了解如何实现 TV 去模糊算法。

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

    如何执行图像去模糊的概述。

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

    【讨论】:

    • 我还没有通读它,但这看起来是一个了不起的答案,也是 SO 迫切需要数学模式的另一个原因
    • 同意。非常感谢这个答案。在我对这个主题的研究中,我慢慢得出结论,噪音可能是导致我问题的原因,而我刚刚开始意识到除以 F(K) 实际上正在增加这一事实噪声幅度(这就是为什么我实施了一种简单的方法来尝试去除这些点)。我一直在阅读有关 Wiener 过滤器的信息,我认为我对它的理解足以实现并会尝试一下,但我注意到这不是一种迭代方法。会不会也注定失败?
    • 我必须承认我在维纳滤波器方面没有太多经验,这是一种相对古老的信号处理技术,因为我的背景是数学图像处理和逆问题。但是我肯定会测试它,因为它比迭代方法快得多。您也可以在 scikit-image 中找到 Wiener 过滤器,因此实现起来应该相对简单。
    • 在查看了更多维纳过滤器之后,我发现它们在某种程度上与我上面演示的非正则化迭代方法等效(如果您有兴趣,可以阅读有关 Landweber 迭代和 Tikhonov 正则化的信息) .
    • 因此 Wiener 滤波器与 Tikhonov 正则化反卷积相同,在设计上会导致一些模糊(类似于高斯模糊)。 TV 正则化(及其更高级的变体)不会以同样的方式导致模糊,但是,它们需要非平滑优化,这可能非常麻烦。如果需要,我可能会在稍后编辑上面的帖子,提供有关此的更多信息。
    猜你喜欢
    • 1970-01-01
    • 2013-08-29
    • 2013-03-02
    • 2017-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-24
    相关资源
    最近更新 更多