我已经使用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版本相同的结果
更新:
我尝试了以下解决方案:
- 我将输入"window_frame"的大小调整为fft_length(用零填充)
- 对新输入执行cv::dft
将输出调整为(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]