qt+傅里叶变换+fft+并画图(时域转换为频域)
时间: 2025-06-28 07:14:02 浏览: 4
### 使用Qt实现快速傅里叶变换(FFT)并绘制从时域到频域的图形
#### 准备工作
为了在Qt中实现快速傅里叶变换(FFT)并将时域信号转换为频域进行绘图,需要先安装必要的库。可以利用第三方库如FFTW来简化FFT计算过程[^1]。
对于GUI部分,Qt自带的`QCustomPlot`是一个非常方便的选择,它能够很好地支持二维数据可视化需求[^3]。
#### 实现步骤概述
创建一个新的Qt Widgets Application项目,在其中加入对所需外部库的支持;编写读取或生成测试时域信号函数;调用FFT算法完成变换操作;最后借助于`QCustomPlot`组件展示结果图表。
以下是具体代码片段:
```cpp
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "qcustomplot/qcustomplot.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked(); // 假设有一个按钮触发FFT运算及绘图
private:
Ui::MainWindow *ui;
QVector<double> timeData, freqData;
void generateTimeDomainSignal();
void performFFT(const QVector<std::complex<double>>& input,
QVector<std::complex<double>> &output);
};
#endif // MAINWINDOW_H
// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <fftw3.h>
void MainWindow::generateTimeDomainSignal() {
int N = 512; // 数据长度
double T = 1.0 / 800.0; // 时间间隔
for (int i=0;i<N;++i){
double t=i*T;
timeData.append(sin(50*2*M_PI*t)+sin(120*2*M_PI*t));
}
}
void MainWindow::performFFT(const QVector<std::complex<double>>& input,
QVector<std::complex<double>>& output) {
fftw_complex in[N], out[N];
fftw_plan p;
for(int i=0;i<input.size();++i){
in[i][0]=input.at(i).real();
in[i][1]=input.at(i).imag();
}
/* Create the plan */
p = fftw_plan_dft_1d(N, reinterpret_cast<fftw_complex*>(in),
reinterpret_cast<fftw_complex*>(out), FFTW_FORWARD, FFTW_ESTIMATE);
/* Execute the plan */
fftw_execute(p);
for(int i=0;i<output.size();++i){
std::complex<double> c(out[i][0],out[i][1]);
output.replace(i,c);
}
/* Clean up */
fftw_destroy_plan(p);
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow) {
ui->setupUi(this);
connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));
}
MainWindow::~MainWindow(){
delete ui;
}
void MainWindow::on_pushButton_clicked(){
this->generateTimeDomainSignal();
QVector<std::complex<double>> complexInput(timeData.count());
for(int i=0 ; i<timeData.count() ; ++i )
complexInput[i]=(std::complex<double>(timeData[i]));
QVector<std::complex<double>> complexOutput(complexInput.count());
this->performFFT(complexInput,complexOutput);
// 绘制时间序列图像
ui->customPlot->addGraph();
ui->customPlot->graph()->setData(QVector<double>::fromStdVector(
vector<int>(0,timeData.count())),timeData);
ui->customPlot->replot();
// 计算幅度谱并绘制频率响应曲线
QVector<double> magnitudeSpectrum(complexOutput.count()/2+1);
for(size_t k=0;k<=magnitudeSpectrum.count()-1;++k){
magnitudeSpectrum[k]=sqrt(pow(complexOutput[k].real(),2)+
pow(complexOutput[k].imag(),2))/N;
}
ui->customPlot->addGraph();
ui->customPlot->graph()->setData(QVector<double>::fromStdVector(
vector<int>(0,magnitudeSpectrum.count())),
magnitudeSpectrum);
ui->customPlot->rescaleAxes();
ui->customPlot->replot();
}
```
上述代码展示了如何在一个简单的Qt应用程序框架内集成FFT功能,并通过`QCustomPlot`控件呈现时域与频域的数据变化情况[^4]。
阅读全文
相关推荐

















