用FFT实现二维卷积

Implement 2D convolution using FFT(用FFT实现二维卷积)
本文介绍了用FFT实现二维卷积的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TensorFlow.conv2d()对于卷积大图像和大核(滤镜)来说,速度非常慢。将1024x1024图像与相同大小的内核进行卷积需要几分钟时间。为了进行比较,cv2.filter2D()立即返回结果。

我找到tf.fft2()tf.rfft()

但是,我不清楚如何使用这些函数执行简单的图像过滤。

如何使用FFT使用TensorFlow实现快速2D图像过滤?

推荐答案

x * y形式的线性离散卷积可以使用卷积定理和离散时间傅里叶变换计算。如果x * y是圆形离散卷积,则可以使用离散傅里叶变换(DFT)进行计算。

卷积定理状态x * y可以使用傅里叶变换计算为

其中表示傅里叶变换和傅立叶逆变换。当xy是离散的并且它们的卷积是线性卷积时,这是使用DTFT计算的

如果xy是离散的,并且它们的卷积是循环卷积,则用DFT代替上面的DTFT。注意:线性卷积问题可以嵌入到循环卷积问题中。


我对MatLab比较熟悉,但通过阅读tf.signal.fft2dtf.signal.ifft2d的TensorFlow文档,下面的解决方案应该可以通过替换MatLab函数fft2ifft2轻松转换为TensorFlow。

(和TensorFlow)fft2(和tf.signal.fft2d)使用快速傅立叶变换算法计算DFT。如果xy的卷积是循环的,则可以通过

计算
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通过填零来计算xy2*N-1点2D傅立叶变换,然后计算2*N-1点2D逆傅立叶变换。此方法不能在TensorFlow中使用(根据我对文档的理解),因此下一步是唯一的选择。在MatLab和TensorFlow中,可以通过首先将xy扩展到大小2*N-1x2*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中,hh_extended完全相等。xy的卷积可以在不进行傅里叶变换的情况下计算
hC = conv2(x, y);

在MatLab中。


在我笔记本电脑上的MatLab中conv2(x, y)需要55秒,而傅里叶变换方法只需不到0.4秒。

这篇关于用FFT实现二维卷积的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Leetcode 234: Palindrome LinkedList(Leetcode 234:回文链接列表)
How do I read an Excel file directly from Dropbox#39;s API using pandas.read_excel()?(如何使用PANDAS.READ_EXCEL()直接从Dropbox的API读取Excel文件?)
subprocess.Popen tries to write to nonexistent pipe(子进程。打开尝试写入不存在的管道)
I want to realize Popen-code from Windows to Linux:(我想实现从Windows到Linux的POpen-code:)
Reading stdout from a subprocess in real time(实时读取子进程中的标准输出)
How to call type safely on a random file in Python?(如何在Python中安全地调用随机文件上的类型?)