不幸的是,您试图解决的问题比您预期的要困难。让我分四个部分来解释。第一部分假设您熟悉傅里叶变换。
- 为什么不能通过简单的反卷积来解决这个问题。
- 如何执行图像去模糊的概述。
- FFT 反卷积以及为什么这是一个坏主意
- 另一种执行反卷积的方法
但首先,一些符号:
我用I来表示图像,用K来表示卷积核。 I * K 是图像I 与核K 的卷积。 F(I)是图像的(n维)傅里叶变换I和F (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 的卷积算法如何处理边界条件。通常,当我们对图像进行卷积时,分辨率会有所降低。这是不需要的行为,因此我们引入了边界条件来指定图像外部像素的像素值。这种边界条件的例子是
- 图像外的像素与图像内最近的像素具有相同的值
- 图像外的像素具有恒定值(例如 0)
- 图像是周期信号的一部分,因此最上面一行的像素行等于最下面一行的像素。
最终的边界条件通常对一维信号有意义。然而,对于图像来说,它没有多大意义。不幸的是,卷积定理指定使用周期性边界条件。
除此之外,基于 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 的加速梯度方案的自适应重启。
如何执行图像去模糊的概述。
- 裁剪图像,使所有物体与相机的距离相同
- 以与您现在相同的方式找到卷积核(首先在合成模糊图像上测试您的反卷积算法)
- 实现一种迭代方法来计算去卷积
- 对图像进行反卷积。