ECG工频滤波器50hz,流处理,(纯干货)(算法步骤+C源码)(工频干扰)

算法步骤

1. 声明变量

        * notchQueue:滤波器队列

        * notchData:滤波器数据

        * pbuffer:滤波器延时缓存

        * index:滤波器队列指针

        * ctx_flag:滤波器稳定性计数器

        * ctx_c_threshold:滤波器稳定性阈值

        * l:滤波器队列长度

        在函数开始,声明所有需要使用的变量。

2. 循环左移,插入datum

        将notchQueue队列的第一个元素移出,并将datum插入到队列尾部。

3. 判断滤波器稳定性

        如果相邻元素的差值的绝对值小于阈值,则认为滤波器稳定。

4. 更新滤波器数据

        如果滤波器稳定,则更新滤波器数据。

  • 计算滤波器数据:

    • 将notchQueue队列中的所有元素求和
    • 将notchQueue队列的第一个元素减去最后一个元素
    • 将求和结果除以队列长度
  • 更新pbuffer数据:

    • 将notchQueue队列的中间元素减去滤波器数据

5. 返回滤波后的数据


#define notchFilter50hzLength 10


typedef struct
{
    int flag;
    int c_threshold;
    float notchQueue[notchFilter50hzLength + 2];
    float notchData[notchFilter50hzLength];
    float pbuffer[notchFilter50hzLength];
    int index;
    int l = notchFilter50hzLength;
} NotchFilter_50hz_CTX;


void move_left(float *data, int n)
{
    // 向左移动数据,data[0] = data[1],...
    int i = 0;
    for (i = 0; i < (n - 1); i++) 
        data[i] = data[i + 1]; 
}

void move_left(float *data, int n, float new_data)
{
    // 向左移动数据,data[0] = data[1],...
    move_left(data, n);
    data[n - 1] = new_data; // 更新最后一个元素
}

// 初始化函数NotchFilter_50hz_init,用于初始化ctx变量
void NotchFilter_50hz_init(NotchFilter_50hz_CTX *ctx)
{ 
    int *ctx_flag = &(ctx->flag);
    int *ctx_c_threshold = &(ctx->c_threshold);

    // 初始化ctx_c_threshold为18,ctx_flag为1
    ctx->c_threshold = 18;
    ctx->flag = 1;
    
    // 初始化notchData,pbuffer,notchQueue
    int i = 0;
    for (i = 0; i < ctx->l; i++)
    {
        ctx->notchData[i] = 0;
        ctx->pbuffer[i] = 0;
        ctx->notchQueue[i] = 0;
    }

    ctx->notchQueue[ctx->l] = 0;
    ctx->notchQueue[ctx->l + 1] = 0;
    // 初始化index为0
    ctx->index = 0;
}
 

float NotchFilter_50hz(NotchFilter_50hz_CTX *ctx, float datum)
{/**
    函数NotchFilter_50hz用于处理50赫兹滤波器,参数ctx为上下文指针,datum为数据,channelNumber为通道号
    @param ctx 上下文指针
    @param datum 数据
    @return 滤波后的数据
**/
    // 声明变量notchQueue,notchData,pbuffer,index,ctx_flag,ctx_c_threshold
    float(*notchQueue) = ctx->notchQueue;
    float(*notchData) = ctx->notchData;
    float(*pbuffer) = ctx->pbuffer;
    int *index = &(ctx->index);

    int *ctx_flag = &(ctx->flag);
    int *ctx_c_threshold = &(ctx->c_threshold);
    int l = ctx->l;

    // 循环左移,插入datum
    move_left(notchQueue, l + 1, datum);

    if (*index == l - 1) 
        *index = 0; 
    // 计算两个相邻元素的差值
    float DifferA = notchQueue[l - 1] - notchQueue[0];
    float DifferB = notchQueue[l] - notchQueue[1];

    // 如果差值的绝对值小于阈值,则认为滤波器稳定
    if (fabsf(DifferA - DifferB) < (float)(*ctx_c_threshold))
    {
        // 滤波器稳定,重置计数器
        (*ctx_flag) = (*ctx_flag) - 1;
        // 如果计数器为0,则更新滤波器数据
        if ((*ctx_flag) == 0)
        {
            // 计算滤波器数据
            (*ctx_flag) = 1;
            float sum = 0;
            for (int i = 0; i < l; i++) 
                sum = sum + notchQueue[i]; 
            float differ = notchQueue[l - 1] - notchQueue[0];
            notchData[l / 2 - 1] = (sum - differ) / l;
            // 更新pbuffer数据
            pbuffer[*index] = notchQueue[l / 2 - 1] - notchData[l / 2 - 1];
        }
        else 
            // 滤波器数据不变
            notchData[l / 2 - 1] = notchQueue[l / 2 - 1] - pbuffer[*index]; 
    }
    else // 滤波器不稳定,重置计数器
        (*ctx_flag) = l - 1; 

    // 更新滤波器数据
    notchData[l / 2 - 1] = notchQueue[l / 2 - 1] - pbuffer[*index];

    // 返回滤波后的数据
    float result = notchQueue[l / 2 - 1] - pbuffer[*index];
    *index = *index + 1;

    return result;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值