白话FFT频谱分析全流程(以工程使用的角度)之三:乘恢复系数、除不同系数和完整程序

白话FFT频谱分析全流程(以工程使用的角度)之三:乘恢复系数、除不同系数和完整程序

回顾

上一节我们已经讲过了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();

欢迎大家关注,点赞哦,您的支持是我加速更新和为您写出更好文章的动力!

发布了39 篇原创文章 · 获赞 113 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/whstudio123/article/details/105173262
今日推荐