基于QCustomPlot 和 FFTW 应用分享

本文介绍如何使用QCustomPlot进行信号的时间域和频域分析,包括自定义轴刻度、曲线颜色调整等功能,并利用FFTW库进行高效的傅立叶变换计算。

试验采集数据,需要查看时间域曲线、频谱计算(含复数结果输出)、查看分段详情、导出计算结果、批量处理大文件。对比Qwt QtCharts,还是选用QCustomPlot。没失望,效率还是可以,UI也还蛮好。FFTW库,一个字~香!

涉及到的细节:QCustomPlot双对数轴,x轴刻度自定义,x轴逆序,全选/全不选按钮联动,单根曲线颜色,xy轴标尺跟随,tracer更新,缩放轴切换,子线程跑FFTW,线程池管理多个子线程,同时读多个文件,曲线抽稀,FFTW策略重复执行,moveToThread跑子线程,SQLite中检索信息、QXlsx库写Excel文件。 

 Mark哈。各位看官老爷,有空可以指导哈。滤波,小波变换,去噪等还不晓得咋玩,《数字信号处理》 这门课我都不记得上过没。

  /* 点击按钮,修改曲线颜色 */
    QPushButton *poBtnColor = new QPushButton("颜色");
    poBtnColor->setMaximumWidth(50);
    connect(poBtnColor, &QPushButton::clicked, this, [=]{
        if(!poGraph->visible()){
            QMessageBox::warning(NULL, "警告", "请先勾选该曲线!",
                                 QMessageBox::Cancel,
                                 QMessageBox::Cancel);
            return ;
        }

        QColorDialog *colorDlg = new QColorDialog(this);

        QColor color = colorDlg->getColor(QColor(255,0,0));  //显示对话框并获取当前选中的颜色(显示对话框时线程阻塞,是模态显示的)

        poBtnColor->setStyleSheet(QString("color: rgb(255, 255, 255); background-color: rgb(%1, %2, %3);")
                                  .arg(color.red())
                                  .arg(color.green())
                                  .arg(color.blue()));

        poGraph->setPen(QColor(color.red(), color.green(), color.blue()));

        foreach(QCPItemTracer *poTracer,  mapGraphTracer.value(poGraph)){
            poTracer->setBrush(QColor(color.red(), color.green(), color.blue()));
        }
        ui->plotSpectrum->replot();

        //临时变量释放资源
        delete colorDlg;
        colorDlg = nullptr;
    });
/* QVector x y 中,找到最大值&&索引和最小值&&索引 */
void SpectrumAnalysisThread::extremum(QVector<float> x, QVector<float> y)
{
    //qDebugV0()<<"input :"<<x.length()<<y;

    if(x.count() <= 2){
        /* 要这个顺序 */
        for(int i = 0; i < x.count(); i++){
            adX.append(x.at(i));
            adY.append(y.at(i));
        }
    }
    else{
        auto max = std::max_element(std::begin(y), std::end(y));
        auto min = std::min_element(std::begin(y), std::end(y));

        float biggest  = *max;
        float smallest = *min;

        auto positionmax = std::distance(std::begin(y),max);
        auto positionmin = std::distance(std::begin(y),min);

        int posmax = positionmax;
        int posmin = positionmin;

        if(posmin < posmax){
            adX.append(x.at(posmin));
            adY.append(y.at(posmin));

            adX.append(x.at(posmax));
            adY.append(y.at(posmax));
        }else{
            adX.append(x.at(posmax));
            adY.append(y.at(posmax));

            adX.append(x.at(posmin));
            adY.append(y.at(posmin));
        }
    }
}
/* 分段计算频谱,抽稀频谱曲线,循环执行FFTW plan, */
void SpectrumAnalysisThread::slotSpectrum(int iRow, QString oStrFileName, quint64 uiStart, quint64 uiEnd, quint64 uiSecs, QList<double> adTargetF)
{
    /* 1、获取完整的时间与数据 */
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值