回顾
上一节我们已经讲过了FFT和数据取半,求模,现在信号已经很象样了,但我们还要对信号进行一些处理,才能反映出正确的数值关系。
开始
1.乘恢复系数:
各类窗函数的恢复系数
我们注意:
1.里面有幅值恢复系数和功率恢复系数,按需要恢复;
2.在频域,需要对每条谱线进行修正,修正通过乘以相应的修正因子实现;
3.不能同时应用能量修正与幅值修正,只能按一种方式进行修正;
2.除不同系数:
假设原始信号的峰值为A,那么FFT的结果的每个点(除了第一个点直流分量之外)的模值就是A
的N/2倍。而第一个点就是直流分量,它的模值就是直流分量的N倍.
这是因为傅里叶级数对应时域幅值,其中已经包含了1/N项,而FFT变换中没有该系数,因此,进行FFT变换后,需除以N/2才能与时域对上。
全球绝大部分的FFT算法,计算出来后都需要进行幅度转换.
那么具体怎么做呢?
很简单:对第0个数据(也就是直流分量)除以N,对其它点除以N再乘以2就可以啦。
最后程序
到这里我们就走完了频谱分析的全流程,最后我们总结一下,来看看完整的一个程序:(使用qt编写)
QVector<double> x_,y_;
for(auto i = 0; i<1024;i++)
{
x_<<i;
y_<< mFFTWinFunc.Flattop_Win(i,1024)*pcmdata[i];
}
//用上面的原始数据的初始化这个结构体类
QVector<Complex> in_(x_.size());
QVector<Complex> out_(x_.size());
for(auto i = 0; i< x_.size();i++)
{
in_[i].rl = y_[i];
}
//调用接口 生成频域的 out_ 数据
m_fft2->fft1(in_,in_.size(),out_);
QVector<double> x1,y1;
for(auto i = 0;i<out_.size()/2;i++)
{
x1<<i;
y1<<2*sqrt(out_[i].rl * out_[i].rl+out_[i].im * out_[i].im)/1024.0;
}
y1[0]= y1[0]/2.0;
this->curve->setSamples(x1,y1);
this->curve->attach(ui->qwtplot_boxing);
QString s = QString::number(y_max_xnum*0.04315, 10,2);
mX->setLabel(s+"khz");
mX->setLabelAlignment(Qt::AlignBottom);
mX->setLabelOrientation(Qt::Horizontal);
mX->setLineStyle(QwtPlotMarker::VLine);
mX->setLinePen(QPen(Qt::white, 1, Qt::DashDotDotLine));
mX->setXValue(y_max_xnum);
mX->attach(ui->qwtplot_boxing);
ui->qwtplot_boxing->replot();
欢迎大家关注,点赞哦,您的支持是我加速更新和为您写出更好文章的动力!