在QT中使用Armadillo使用FFT将时域转换为频域

目录

1.前言

2.时域

2.1简介

2.2时域信号分析

3.频域

3.1简介

3.2频域信号分析


1.前言

        最近一直在做振动监测,把传感器采集到的振动信号数据转换成电压值,然后通过QT的QCharts绘制出时域图形,接着利用C++的线性库Armadillo中FFT()将时域信号转换成频域信号,绘制出响应的频谱图。QT中配Armadillo我之前写过一篇文章记录过,就不再详细说了。

QT中配置C++运算库Armadillo_唔肯木工的博客-CSDN博客

2.时域

2.1简介

        时域(Time Domain)是信号处理中的一个概念,用于描述信号在时间上的变化和演化。在时域中,信号被表示为时间的函数,可以看作是信号在时间轴上的波形图。

时域分析主要关注信号的时序特征,包括信号的振幅、频率、相位和持续时间等。通过对信号在时域上的分析,可以获得信号的时域特征,如峰值,裕度,峭度,脉冲宽度、周期性、瞬态特性等,从而对信号的时序行为进行研究和理解。

在时域分析中,常用的工具和技术包括:

  1. 时域图形表示:将信号绘制成波形图,以可视化信号在时间上的变化。常见的时域图形包括时序图、波形图、折线图等。

  2. 时域参数:通过计算信号的各种统计量和时域参数,如均值、方差、峰值、峰峰值、波形因子等,来描述信号的时域特征。

  3. 自相关函数:用于衡量信号在不同时间点上的自相关性。自相关函数可以揭示信号的周期性和重复性特征。

  4. 瞬态响应:瞬态响应描述系统对突变输入的响应,可以通过观察信号在时域上的变化来分析系统的瞬态特性。

时域分析在信号处理、通信系统、控制系统等领域具有重要的应用。通过分析信号在时间上的特性,帮助我们理解信号的动态行为、检测故障和异常、设计滤波器和控制系统等。此外,时域分析通常与频域分析相结合,以全面了解信号的特性和行为。

2.2时域信号分析

        我是通过W5500以太网芯片利用TCP或者WebSocket协议将采集到的振动信号传输给QT上位机,将上位机作为服务器端,把传输过来的信号进行转换之后绘制出来时域和频域。我对时域特征值也进行了提取,这里就先不介绍了。

void Server::StrConvert(QString str)
{
    QVector<double> dataCh4;
    QVector<double> dataCh2;
    QVector<double> dataCh3;
    QVector<double> dataCh1;
    colvec matdc4(50);
    colvec matdc2(50);
    colvec matdc3(50);
    colvec matdc1(50);
    QString hex = "7FFFFF";
    QStringList splitData = str.split("\r");
    for(int i = 0;i < splitData.length()-1;i++)
    {
        QString Qch4 = splitData.value(i).mid(18,6);
        double ch4 = 2.5*Qch4.toInt(nullptr,16)/hex.toInt(nullptr,16);

        QString Qch2 = splitData.value(i).mid(6,6);
        double ch2 = 2.5*Qch2.toInt(nullptr,16)/hex.toInt(nullptr,16);

        QString Qch3 = splitData.value(i).mid(12,6);
        double ch3 = 2.5*Qch3.toInt(nullptr,16)/hex.toInt(nullptr,16);

        QString Qch1 = splitData.value(i).mid(0,6);
        double ch1 = 2.5*Qch1.toInt(nullptr,16)/hex.toInt(nullptr,16);

        dataCh4.append(ch4);
        dataCh2.append(ch2);
        dataCh3.append(ch3);
        dataCh1.append(ch1);
    }
    for (int i = 0; i < 50; i++)
    {
        matdc1.row(i)=dataCh1.at(i); 
        matdc2.row(i)=dataCh2.at(i);
        matdc3.row(i)=dataCh3.at(i);
        matdc4.row(i)=dataCh4.at(i);
    }
    matdc1.save("matdc1.txt",raw_ascii);
    matdc2.save("matdc2.txt",raw_ascii);
    matdc3.save("matdc3.txt",raw_ascii);
    matdc4.save("matdc4.txt",raw_ascii);
    return;
}
void CompInfo1_1::Primitive()
{
    static bool flag = true;
    dc1.load("matdc1.txt");
    dc2.load("matdc2.txt");
    dc3.load("matdc3.txt");
    dc4.load("matdc4.txt");
    chart6->axisX()->setMin(QDateTime::currentDateTime().addSecs(-60));
    chart6->axisX()->setMax(QDateTime::currentDateTime().addSecs(0));
    if ((!dc1.is_empty())&&(!dc2.is_empty())&&(!dc3.is_empty())&&(!dc4.is_empty()))
    {
        for(int i = 0; i < 50; i++)
        {
            NlineSeries1->append(QDateTime::currentDateTime().toMSecsSinceEpoch(),dc1(i));
            NlineSeries2->append(QDateTime::currentDateTime().toMSecsSinceEpoch(),dc2(i));
            NlineSeries3->append(QDateTime::currentDateTime().toMSecsSinceEpoch(),dc3(i));
            NlineSeries4->append(QDateTime::currentDateTime().toMSecsSinceEpoch(),dc4(i));
        }
    }
    else
    {
        if(flag)
        {
            flag = false;
            QMessageBox::information(this,"Tip","请连接服务器!");
        }

    }
    return;
}

         上面把转换好的信号存放到矩阵中,并保存下来,绘制时域图时使用Armadillo中加载矩阵的方法读取出来。 

3.频域

3.1简介

频域(Frequency Domain)是信号处理中的一个概念,用于描述信号在频率上的特征和变化。在频域中,信号被表示为频率的函数,可以看作是信号在频率轴上的能量分布。

频域分析主要关注信号的频率成分和频谱特性,包括信号的频率内容、频域幅度、相位和频域分布等。通过对信号在频域上的分析,可以获得信号的频域特征,如频谱形状、频率成分的强度和分布等,从而对信号的频率特性进行研究和理解。

在频域分析中,常用的工具和技术包括:

  1. 傅里叶变换:傅里叶变换是频域分析的基础工具,将信号从时域转换到频域。傅里叶变换可以将信号表示为频率成分的叠加,提供了信号在频域上的幅度和相位信息。

  2. 频谱分析:通过对信号进行频谱分析,可以将信号在频域上的能量分布可视化为频谱图。常见的频谱分析方法包括功率谱密度(PSD)、频谱图、频谱瀑布图等。

  3. 频域滤波:频域滤波利用信号的频率特性进行滤波操作。通过在频域上调整信号的频率成分,可以实现去除噪声、滤波和频率选择等功能。

  4. 快速傅里叶变换(FFT):FFT是一种高效的算法,用于计算离散信号的傅里叶变换。FFT可以快速地将信号从时域转换到频域,常用于频谱分析和频域滤波等应用。

  5. 频域参数:通过计算信号在频域上的统计量和参数,如频域均值、频域方差、频域峰值等,来描述信号的频域特征。

频域分析可以帮助我们理解信号的频率内容、提取频率特征、设计滤波器、频率调制和解调等。

3.2频域信号分析

        在这里面我使用4096个采样点,采样频率为fs = 10000Hz,对信号进行处理,使用linspace计算得到一个频率序列。通过应用fft()函数,取复数的绝对值得到幅值。并且在频域中,频率为0对应的值表示直流分量需要减去。最后,将频率和幅值组合成一个矩阵,并返回该矩阵。

    double cacl_mean(vec src)
    {
        return mean(src);
    }

    mat calc_pri(vec src, double fs)
    {
        vec subSrc = src.subvec(0,4095);
        subSrc = subSrc-cacl_mean(subSrc);
        int n = subSrc.n_elem;
        vec freq = linspace(0, n-1,n/2)*fs/n;
        vec amps = abs(fft(subSrc,n)*2/n);
        amps = amps(span(0,n/2-1));
        mat matrix;
        matrix = mat(join_rows(freq, amps));
        return matrix;
    }
void CompInfof1_1::Draw_pr()
{
    static bool flag = true;

    fdc1.load("matdc1.txt",raw_ascii);
    fdc2.load("matdc2.txt",raw_ascii);
    fdc3.load("matdc3.txt",raw_ascii);
    fdc4.load("matdc4.txt",raw_ascii);
    fx1 = FDomain->calc_pri(fdc1,10000);
    fx2 = FDomain->calc_pri(fdc2,10000);
    fx3 = FDomain->calc_pri(fdc3,10000);
    fx4 = FDomain->calc_pri(fdc4,10000);
    if ((!fdc1.is_empty())&&(!fdc2.is_empty())&&(!fdc3.is_empty())&&(!fdc4.is_empty()))
    {
        for(int i=0;i<fx1.n_rows;i++)
        {
            PRlineSeries1->append(fx1(i,0),fx1(i,1));
            PRlineSeries2->append(fx2(i,0),fx2(i,1));
            PRlineSeries3->append(fx3(i,0),fx3(i,1));
            PRlineSeries4->append(fx4(i,0),fx4(i,1));
        }

    }
    else
    {
        if(flag)
        {
            flag = false;
            QMessageBox::information(this,"Tip","请连接服务器!");
        }

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值