如何在cv::dft中指定FFT长度,就像在Python numpy.FFT.rfft中一样



我已经使用numpy.FFT.rft()在python中成功地完成了FFT。现在,我想将此代码移植到C++。

在研究了这个主题之后,我如何将使用numpy.fft.rfft的代码从python移植到C++?,我能够使用cv::dft来做FFT。然而,问题是,对于numpy.fft.rft(),有一个额外的参数,即fft长度,我在cv.中找不到它

我的Python代码如下:

window_frame = np.array([1,2,3,4])
fft_length = 10
np.abs(np.fft.rfft(window_frame, int(fft_length)))

结果是:

[10. , 8.16620583 , 4.25325404, 2.51258479 , 2.62865556 , 2.] 

长度为(fft_length/2)+1。

在C++中,我执行以下代码:

std::vector<double> t;
cv::dft(window_frame, t)

结果是:

[10. -2., 2., -2.]

如何才能获得与Python版本相同的结果


更新:

我尝试了以下解决方案:

  1. 我将输入"window_frame"的大小调整为fft_length(用零填充)
  2. 对新输入执行cv::dft
  3. 将输出调整为(fft_length/2)+1

    std::向量t;window_frame.resize(fft_length);cv::dft(window_frame,t);t.resize((fft_length/2)+1);

结果是:

[10 2.30902 -7.83297 -4.04508 -1.31433 1.19098 2.21238 1.54508 -2.12663 -2]

这与Python版本中应用np.fft.rft()时的情况相同

[10 + 0j, 2.309 - 7.832j, -4.045 - 1.3143j, 1.19098 + 2.212j, 1.54508 -2.126j, -2 + 0j]

现在,我如何对这些数据执行np.abs?第一个元素和最后一个元素只有真正的部分吗?

在Python代码中设置FFT长度时,在应用FFT算法之前,输入信号会被截断或用0填充到请求的长度。

在C++中,你可以做,例如,

windows_frame.resize(fft_length, 0);
cv::dft(windows_frame, t);

OpenCV有自己独特的方式来表示实值频域,它与NumPy产生的不同。NumPy输出N/2+1个复数值(注意!这使用整数除法)。OpenCV输出N个实数。阅读文档,了解如何将cv::dft的输出解释为实值输入和输出。简言之,第一个阵列元素对应于零频率分量(它总是实值的),随后的阵列元素对应频谱的前半部分的实分量和虚分量。对于偶数大小的阵列,最后一个阵列元素对应于频率分量N/2(它总是实数)。对于奇数大小的阵列,频率分量N/2也很复杂,并且它的两个分量都存在(尽管文档中没有明确说明)。

  • 偶数尺寸:[r0, r1, i1, r2, i2, ... rN/2]
  • 奇数大小:[r0, r1, i1, r2, i2, ... rN/2 iN/2]

最新更新