C++基于OpenCV获取离散傅里叶变换(DFT)绝对值的实现问题
解决方法
OpenCV 提供了内置的cv::magnitude函数专门用于计算复数的幅值(也就是你需要的绝对值),底层做了指令集优化,性能远高于手动遍历,完全符合Mat的设计使用逻辑,实现步骤如下:
- 拆分DFT输出的双通道复数Mat,分离实部和虚部
- 调用
cv::magnitude计算幅值 - 将结果Mat赋值到目标vector中
完整实现代码:
vector<float> areas, X_mag; cv::Mat X; // ... 你的原有逻辑 cv::dft(areas, X, cv::DFT_COMPLEX_OUTPUT); // 新增逻辑开始 cv::Mat planes[2]; cv::split(X, planes); // planes[0]为实部,planes[1]为虚部 cv::Mat mag_mat; cv::magnitude(planes[0], planes[1], mag_mat); // 将结果转存到X_mag向量 X_mag.assign(mag_mat.begin<float>(), mag_mat.end<float>());
补充说明
- 你之前使用
cv::absdiff的方式本质逻辑错误,absdiff是计算两个数组差值的绝对值,和复数模的计算逻辑完全不同,之前对vector生效只是类型转换的巧合,不具备通用性也容易出隐患。 - 如果你的场景只需要实信号DFT的非冗余半区结果,可以在计算完幅值后只取前
areas.size()/2 + 1个元素即可,能减少一半的存储空间占用。
内容的提问来源于stack exchange,提问作者polaupa
相关产品推荐
相关产品推荐

