【问题标题】:How can I port code that uses numpy.fft.rfft from python to C++?如何将使用 numpy.fft.rfft 的代码从 python 移植到 C++?
【发布时间】:2023-03-28 08:26:01
【问题描述】:

我有用 python 编写的代码。它使用 numpy 计算实际输入的 FFT 的正部分。我需要将此代码移植到 C++。

import numpy as np
interp=[131.107, 133.089, 132.199, 129.905, 132.977]
res=np.fft.rfft(interp)
print res

rfft 的结果是 [ 659.27700000+0.j, 1.27932533-1.4548977j, -3.15032533+2.1158917j]

我尝试使用 OpenCV 进行 1D DFT:

std::vector<double> fft;
std::vector<double> interpolated = {131.107, 133.089, 132.199, 129.905, 132.977};
cv::dft( interpolated, fft );
for( auto it = fft.begin(); it != fft.end(); ++it ) {
    std::cout << *it << ' ';
}
std::cout << std::endl;

cv::dft 的结果是 {1.42109e-14, -127.718, -94.705, 6.26856, 23.0231}。它与 numpy.fft.rfft 有很大不同。在计算 OpenCV 的 dft 之后,所有输入的 DC 值(零元素)接近于零,这看起来很奇怪。

使用 FFTW3 库给我的结果与 OpenCV 的结果相同:

std::vector<double> interpolated = {131.107, 133.089, 132.199, 129.905, 132.977};
fftw_complex* out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * 3 );
fftw_plan plan = fftw_plan_dft_r2c_1d( interpolated.size( ), interpolated.data( ), out, FFTW_ESTIMATE );
fftw_execute(plan);
fftw_destroy_plan(plan);
for( size_t i = 0; i < interpolated.size( ); ++i ) {
    std::cout << " (" << out[ i ][ 0 ] << ", " << out[ i ][ 1 ] << ")";
}
fftw_free(out);

这段代码给了我与 OpenCV 相同的结果。它打印:(1.42109e-14, 0) (-127.718, -94.705) (6.26856, 23.0231)。

为什么我在 C++ 和 python 中得到不同的 dft 结果?我做错了什么?

谢谢!

【问题讨论】:

  • 我在python中试过cv2import cv2;cv2.dft(interp)和numpy的结果一样。

标签: opencv numpy fft fftw


【解决方案1】:

我目前使用的是 gcc 4.6,它没有 C++11,所以我使用 OpenCV 2.4.8 尝试了你的这个版本的代码:

#include <iostream>
#include "opencv2/core/core.hpp"

int main(int argc, char *argv[])
{
    double data[] = {131.107, 133.089, 132.199, 129.905, 132.977};
    std::vector<double> interpolated (data, data + sizeof(data) / sizeof(double));
    std::vector<double> fft;

    cv::dft(interpolated, fft);

    for (std::vector<double>::const_iterator it = fft.begin(); it != fft.end(); ++it) {
        std::cout << *it << ' ';
    }
    std::cout << std::endl;
}

输出

659.277 1.27933 -1.4549 -3.15033 2.11589

同意 numpy 和 cv2 python 模块:

In [55]: np.set_printoptions(precision=3)

In [56]: x
Out[56]: array([ 131.107,  133.089,  132.199,  129.905,  132.977])

In [57]: np.fft.rfft(x)
Out[57]: array([ 659.277+0.j   ,    1.279-1.455j,   -3.150+2.116j])

In [58]: cv2.dft(x)
Out[58]: 
array([[ 659.277],
       [   1.279],
       [  -1.455],
       [  -3.15 ],
       [   2.116]])

我不知道你的代码为什么不起作用,所以我想这更像是一个长评论而不是一个答案。

【讨论】:

    【解决方案2】:

    请查看文档。 libfft rfft 方法将实数输入向量转换为复数傅立叶系数。利用实信号的傅里叶系数的共轭性,可以在与输入长度相同的数组中给出输出。

    通用 fft 和 dft 方法将复数向量转换为复系数向量。较旧的代码使用双精度数组进行输入和输出,其中复数的实部和虚部交替给出,即一个偶数长度的数组。奇数输入长度会发生什么可能是未记录的行为。

    【讨论】:

      猜你喜欢
      • 2012-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-18
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多