Qt C++ 数据预处理笔记(3)——梳状滤波

#include "CombFilterWorker.h"
#include "qdir.h"
#include "qfileinfo.h"

CombFilterWorker::CombFilterWorker(QString oStrDir, int iRow, QString oStrFileName, qint64 iTimestampStart, qint64 iTimestampEnd, QObject* parent)
    : QObject{parent}, oStrDir(oStrDir), iRow(iRow), oStrFileName(oStrFileName), iTimestampStart(iTimestampStart), iTimestampEnd(iTimestampEnd)
{
    oHead = PF::readHead(oStrFileName);

    this->setAutoDelete(true);
}

void CombFilterWorker::run()
{
    QElapsedTimer time;
    time.start();

    qDebugV0() << oStrFileName;

    QFile oFileRaw(oStrFileName);

    if(!oFileRaw.open(QIODevice::ReadOnly) )
    {
        emit sigMsg(oStrFileName + " 打开失败!");
        return;
    }

    //获取新的文件名,梳妆滤波后的文件
    QString oStrHead = PF::readHeadString(oStrFileName);

    QStringList aoStrHead = oStrHead.split(',', Qt::KeepEmptyParts);

    aoStrHead.replace(RAW_HEADER_DATA_CNT, QString::number(oHead.uiFS * (iTimestampEnd - iTimestampStart)));

    aoStrHead.replace(RAW_HEADER_START_TIME, QString::number(iTimestampStart));
    aoStrHead.replace(RAW_HEADER_SAMP_TIME, QString::number(iTimestampEnd - iTimestampStart));

    QString oStrHeadNew = aoStrHead.join(",");

    int iIndexStart = oStrFileName.lastIndexOf("_");
    int iIndexEnd = oStrFileName.lastIndexOf(".");

    QString oStrIndex = oStrFileName.mid(iIndexStart + 1, iIndexEnd - iIndexStart - 1);

    QString oStrBaseName = QString("%1_L(%2)_S(%3)_D(%4)_CH%5_%6_%7_%8.dat")
                           .arg(oHead.oStrTaskName)
                           .arg(oHead.oStrLine)
                           .arg(oHead.oStrSite)
                           .arg(oHead.uiDev)
                           .arg(oHead.uiCh)
                           .arg(oHead.oStrRAW_COMPONENT)
                           .arg(QDateTime::fromSecsSinceEpoch(iTimestampStart).toString("yyyyMMddHHmmss"))
                           .arg(oStrIndex);

    QString oStrFileNameNew = oStrDir + QDir::separator() + QDir::separator() + oStrBaseName;

    qDebugV0() << oStrFileNameNew;

    //写入首行信息
    QFile oFileNew(oStrFileNameNew);

    if(!oFileNew.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        emit sigMsg(oStrFileNameNew + " 打开失败!");
        return;
    }

    oFileNew.write(oStrHeadNew.toUtf8(), LENGTH_178_BYTE);

    QDataStream oStreamNew(&oFileNew);

    t_CMF cmf;

    /*初始化*/
    comb_filter_init(&cmf, -0.22059817649696845, CMF_TYPE_STOP_BANDS);

    QDataStream oStreamRaw(&oFileRaw);

    oStreamRaw.setByteOrder(QDataStream::BigEndian);
    oStreamRaw.setFloatingPointPrecision(QDataStream::SinglePrecision);
    oStreamRaw.skipRawData(LENGTH_178_BYTE);//作者是靠占位符来占据首行的。
    for(int i = 0; i < (iTimestampStart - oHead.iStartTimestamp); ++i)
    {
        oStreamRaw.skipRawData(LENGTH_4_BYTE * oHead.uiFS);
    }

    oStreamNew.setByteOrder(QDataStream::BigEndian);
    oStreamNew.setFloatingPointPrecision(QDataStream::SinglePrecision);

    quint32 uiPercentage = PROGRESS_STEP;

    oStreamRaw.startTransaction();
    oStreamNew.startTransaction();

    double in  = 0.00f;
    double out = 0.00f;

    qDebugV0() << oHead.uiFS* iTimestampStart << " ~ " << oHead.uiFS* iTimestampEnd;

    for(qint64 i = 0; i < (iTimestampEnd - iTimestampStart); ++i)
    {
        for(int j = 0; j < oHead.uiFS; ++j)
        {
            oStreamRaw >> in;

            out = this->comb_filter(&cmf, in);

            oStreamNew << out;
        }

        float fProgress = ((float)(i) / ((float)(iTimestampEnd - iTimestampStart))) * 100;

        if(fProgress >= uiPercentage)
        {
            emit sigProgress(iRow, "处理中~ ", fProgress);

            uiPercentage = uiPercentage + PROGRESS_STEP;
        }
    }

    oStreamRaw.commitTransaction();
    oFileRaw.close();

    oStreamNew.commitTransaction();
    oFileNew.flush();
    oFileNew.close();

    emit sigProgress(iRow, "梳妆滤波完毕!", 100);

    qint64 milsec = time.elapsed();

    emit sigMsg(QString("行号:%1\t加载采样点个数:%2\t耗时:%3s\t梳状滤波")
                .arg(iRow + 1)
                .arg(oHead.uiFS * (iTimestampEnd - iTimestampStart))
                .arg(QString::number(milsec / 1000.00, 'f', 3)));
}

void CombFilterWorker::comb_filter_init(t_CMF* pCmf, double rho, E_CMF_TYPE type)
{
    memset(pCmf, 0, sizeof(t_CMF));
    pCmf->index = CMF_RANK - 1;
    pCmf->r = rho;
    pCmf->type = type;

    if(type == CMF_TYPE_STOP_BANDS)
    {
        pCmf->b = (1 + rho) / 2;
    }
    else
    {
        pCmf->b = (1 - rho) / 2;
    }
}

float CombFilterWorker::comb_filter(t_CMF* pCmf, double xn)
{
    double yn = 0;
    int n_N;
    int i = 0;

    n_N = pCmf->index;
    if(pCmf->type == CMF_TYPE_STOP_BANDS)
    {
        /*y[n] = bx[n]-bx[n-N]+ry[n-N]*/
        yn = pCmf->b * (xn - pCmf->x[n_N]) + pCmf->r * pCmf->y[n_N];
    }
    else
    {
        /*y[n] = bx[n]+bx[n-N]+ry[n-N]*/
        yn = pCmf->b * (xn + pCmf->x[n_N]) + pCmf->r * pCmf->y[n_N];
    }

    /*存储yn为下次迭代准备*/
    pCmf->y[n_N] = yn;
    pCmf->x[n_N] = xn;

    if(pCmf->index == 0)
    {
        pCmf->index = CMF_RANK - 1;
    }
    else
    {
        pCmf->index--;
    }

    return yn;
}
#ifndef COMBFILTERWORKER_H
#define COMBFILTERWORKER_H

#include "PF.h"
#include "qrunnable.h"
#include 

#include 
#include 
#include 

/*长度应为阶数+1*/
#define CMF_RANK  60
#define RHO -0.22059817649696845

typedef enum _E_CMF_TYPE
{
    CMF_TYPE_STOP_BANDS,
    CMF_TYPE_PASS_BANDS
} E_CMF_TYPE;
/*定义移动平均寄存器历史状态*/
typedef struct _t_CMF
{
    float x[CMF_RANK];
    float y[CMF_RANK];
    float b;
    float r;
    E_CMF_TYPE type;
    int index;
} t_CMF;

class CombFilterWorker : public QObject, public QRunnable
{
    Q_OBJECT
public:
    explicit CombFilterWorker(QString oStrDir, int iRow, QString oStrFileName, qint64 iTimestampStart, qint64 iTimestampEnd, QObject* parent = nullptr);

    void run()override;

    void comb_filter_init(t_CMF* pCmf, double rho, E_CMF_TYPE type);

    float comb_filter(t_CMF* pCmf, double xn);

signals:
    void sigMsg(QString);

    void sigProgress(int iRow, QString, float fProgress);

private:
    QString oStrDir;

    int iRow;

    QString oStrFileName;

    qint64 iTimestampStart;
    qint64 iTimestampEnd;

    HEAD oHead;
};

#endif // COMBFILTERWORKER_H

抄袭了别个的代码:https://www.cnblogs.com/embInn/p/12940708.html

你可能感兴趣的:(qt,c++,笔记)