用于线检测的 FFT

信息处理 图片 opencv fft 自由度
2022-01-13 20:11:05

我正在尝试以不同于大多数人询问的方式使用 FFT。我希望能够拍摄具有规则重复垂直线的图形的照片,并处理图像以确定线平均相距多远的像素。我尝试过精明的边缘检测和霍夫线检测,但我认为我无法优化图像以仅准确检测我感兴趣的线条。

因此,我的尝试是扫描 10 行图片并将像素值累积到与像素列对应的 bin 中。当您绘制它时,结果是一个非常漂亮的波形。当我对此执行 DFT 或 FFT 时,我可以找到一个我认为应该是行重复频率的峰值。(这可能是一个错误的假设)

我的问题是,这个数字对应什么?即我认为我对我的采样率感到困惑,因为它以像素为单位。我确实认为这是对 FFT 的有效使用,但在我认为我应该成功的时候就落到了这里。

举个例子。我创建了一张宽度为 300 像素的图片。以 30 个像素间隔绘制 1 个像素宽度的线。我发现了 2 个峰值,一个在 75 处,一个在 225 处(看起来对称)。(我不相信虚构的组件应该发挥作用??)我知道线条相隔 30 像素。75 和或 225 有什么关系?

我非常努力地得到这个,我很感激你能推荐的任何帮助。在这一点上,我正在放弃边缘检测,并想尝试这种方法。

先感谢您。

3个回答

您可能会考虑为此尝试自相关。是一个 SO 答案,描述了如何使用 FFT 与 Matlab 执行自相关。这可以扩展到两个维度。

我在 numpy 中实现了您的测试用例,如下所示:

a = np.zeros(300)
a[::30] = 1
plt.acorr(a, maxlags=50)

这给出了以下情节:

在此处输入图像描述

如您所见,峰值出现在 +/- 30 处。

如果图像中有 10 条垂直线,则完整水平扫描线(300 像素)的 FFT 应显示 bin 10 或 bin 11 周围的一些幅度内容。 300 中的 bin 75 表示每 4 个像素发生一次,或所以。

您确实需要查看 FFT 结果的大小,而不仅仅是“真实”分量(实际上是偶数分量),因为如果您的网格线偏离中心,光谱内容可能会显示为奇数(因此是“虚数”在 FFT 结果中)。

给定 FFT 的实际输入,N/2 以上的结果箱(在您的情况下超过 150)只包含相同数据的重复,但复共轭除外。所以你可以忽略它们。

我没有太多想法,但为了使在视觉上直观,您可以尝试将 FFT 居中的每个值乘以(完成此操作后,您的 DC 分量将出现在中心,整个围绕它对称。FFTFFTFFT(1)(x+y))FFT

我对此不太确定,但有些东西告诉我峰值和中心之间的距离(以像素为单位)将表明周期性。一旦有了周期性,就可以轻松得出每个对象之间的距离。