用FFT实现二维卷积
本教程将介绍用FFT实现二维卷积的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。
问题描述
TensorFlow.conv2d()
对于卷积大图像和大核(滤镜)来说,速度非常慢。将1024x1024图像与相同大小的内核进行卷积需要几分钟时间。为了进行比较,cv2.filter2D()
立即返回结果。
但是,我不清楚怎么使用这些函数执行简单的图像过滤。
怎么使用FFT使用TensorFlow实现快速2D图像过滤?
推荐答案
x * y
形式的线性离散卷积可以使用卷积定理和离散时间傅里叶变换计算。如果x * y
是圆形离散卷积,则可以使用离散傅里叶变换(DFT)进行计算。
卷积定理状态x * y
可以使用傅里叶变换计算为
其中表示傅里叶变换和傅立叶逆变换。当x
和y
是离散的并且它们的卷积是线性卷积时,这是使用DTFT计算的
如果x
和y
是离散的,并且它们的卷积是循环卷积,则用DFT代替上面的DTFT。注意:线性卷积问题可以嵌入到循环卷积问题中。
我对MatLab比较熟悉,但通过阅读tf.signal.fft2d
和tf.signal.ifft2d
的TensorFlow文档,下面的解决方案应该可以通过替换MatLab函数fft2
和ifft2
轻松转换为TensorFlow。
(和TensorFlow)fft2
(和tf.signal.fft2d
)使用快速傅立叶变换算法计算DFT。如果x
和y
的卷积是循环的,则可以通过
计算
ifft2(fft2(x).*fft2(y))
其中.*
表示在MatLab中逐个元素相乘。然而,如果它是线性的,那么我们将数据零填充到长度2N-1
,其中N
是一维的长度(在问题中是1024)。在MatLab中,这可以用两种方法之一来计算。首先,由
h = ifft2(fft2(x, 2*N-1, 2*N-1).*fft2(y, 2*N-1, 2*N-1));
其中,MatLab通过填零来计算x
和y
的2*N-1
点2D傅立叶变换,然后计算2*N-1
点2D逆傅立叶变换。此方法不能在TensorFlow中使用(根据我对文档的理解),因此下一步是唯一的选择。在MatLab和TensorFlow中,可以通过首先将x
和y
扩展到大小2*N-1
x2*N-1
,然后计算2*N-1
点2D傅立叶变换和逆傅立叶变换
来计算卷积
x_extended = x;
x_extended(2*N-1, 2*N-1) = 0;
y_extended = y;
y_extended(2*N-1, 2*N-1) = 0;
h_extended = ifft2(fft2(x_extended).*fft2(y_extended));
在MatLab中,h
和h_extended
完全相等。x
和y
的卷积可以在不进行傅里叶变换的情况下计算
hC = conv2(x, y);
在MatLab中。
在我笔记本电脑上的MatLab中conv2(x, y)
需要55秒,而傅里叶变换方法只需不到0.4秒。
好了关于用FFT实现二维卷积的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。