一个简单的滤波程序,用于滤掉不多的杂波

滤波程序网上有很多,例如

1、限幅滤波法(又称程序判断滤波法)

2、中位值滤波法

3、算术平均滤波法

4、递推平均滤波法(又称滑动平均滤波法)

5、中位值平均滤波法(又称防脉冲干扰平均滤波法)

6、限幅平均滤波法

7、一阶滞后滤波法

8、加权递推平均滤波法

9、消抖滤波法

10、限幅消抖滤波法

11、IIR滤波???

那么我的一个小小的滤波程序的出发点是这样的,例如100个数字,理想状况下都是5,但是实际上,还不连续分布几个6,那么怎么滤掉这几个6呢,我的想法是 这样的:

举个例子:把这个100个数字一次插入循环队列,并且每次插入都进行比较,如果循环队列中的值都相等,那么就认为此时值为真实值,

比如,buf[0] = 5;buf[1] = 5;buf[2] = 5;buf[3] = 5;那么此时就是5,如果buf[0] = 5;buf[1] = 5;buf[2] = 5;buf[3] = 6;呢,不相等了,那么就先是使用上次的值5,继续插入,buf[0] = 5;buf[1] = 5;buf[2] = 6;buf[3] = 5,再继续buf[0] = 5;buf[1] = 6;buf[2] = 5;buf[3] = 5,再继续buf[0] = 6;buf[1] = 5;buf[2] = 5;buf[3] = 5,再继续buf[0] = 5;buf[1] = 5;buf[2] = 5;buf[3] = 5,波动值6就被移出了循环队列。

这样就可以得到稳定的值5,而不受6的影响,

如果多个连续数组需要进行滤波,并且各自的稳定值不相同的话,比如上图中的组1和组2,例如组2大部分是8,偶尔有几个7,那么也是同样适用,依然是插入循环队列,

不过,这样的做法太简单,自然也会带来很大问题,就是如果杂波是连续的,等值的,那么就不好处理了,就要使用一些儿复杂的滤波方式,

这里我写了一个简单的代码,仅供参考:

//循环队列(顺序队列)的实现
#include <stdio.h>
#include <stdlib.h>

#define N 4

//定义数据类型
typedef int datatype_t;

//定义结构体
typedef struct{
    datatype_t data[N];
    int front;
    int rear;
}sequeue_t;

//创建一个空的队列
sequeue_t *sequeue_create()
{
    sequeue_t *sq = (sequeue_t *)malloc(sizeof(sequeue_t));

    sq->front = sq->rear = 0;

    return sq;
}

//判断队列是否为空
int sequeue_empty(sequeue_t *sq)
{
    return sq->front == sq->rear ? 1 : 0;
}

//判断队列是否为满
int sequeue_full(sequeue_t *sq)
{
    return (sq->rear + 1) % N == sq->front ? 1 : 0;
}

//入队
int sequeue_push(sequeue_t *sq, datatype_t value)
{
    if(sequeue_full(sq))
    {
        sequeue_pop(sq);

    }

    sq->data[sq->rear] = value;
    sq->rear = (sq->rear + 1) % N;

    return 0;
}

//出队
datatype_t sequeue_pop(sequeue_t *sq)
{
    if(sequeue_empty(sq))
    {
        printf("sequeue is empty\n");
        return (datatype_t)-1;
    }

    datatype_t value;

    value = sq->data[sq->front];

    sq->front = (sq->front + 1) % N;

    return value;
}


int buf[20] = {1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1}; 
int main(int argc, const char *argv[])
{
    sequeue_t *sq = sequeue_create();
    int i,T_vlaue = 0;
    for(i=0;i<20;i++){
        sequeue_push(sq, buf[i]);
        if(sq->data[0] == sq->data[1] && sq->data[1] == sq->data[2] && sq->data[2] == sq->data[3] ){
            T_vlaue = sq->data[0];            
        }
        printf("-------稳定值为-%d-----------\n",T_vlaue);
    }


    putchar(10);
    
    return 0;
}
 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
A:以下是一个简单的C语言程序用于语音数字滤波。该程序从麦克风或音频文件中读取语音信号,并对其进行数字滤波,以去除高频噪声和其他杂波。 ```c #include <stdio.h> #include <stdlib.h> #include <math.h> #define FILTER_LEN 256 // 滤波器长度 #define PI 3.14159265359 // 生成带通滤波器 void generate_bandpass_filter(double f0, double fs, double* filter) { for(int i=0; i<FILTER_LEN; i++) { double x = (double)i - (double)(FILTER_LEN/2); filter[i] = (2.0*f0/fs)*sinc(2.0*f0*x/fs); } } // sinc函数 double sinc(double x) { if(x == 0.0) return 1.0; else return sin(PI*x)/(PI*x); } // 滤波函数 void filter_signal(double* signal, double* filter, int len) { double* output = (double*)malloc(sizeof(double)*len); // 分配内存空间 for(int i=0; i<len; i++) { double sum = 0.0; for(int j=0; j<FILTER_LEN; j++) { int idx = i - FILTER_LEN/2 + j; if(idx >= 0 && idx < len) { sum += signal[idx] * filter[j]; } } output[i] = sum; } for(int i=0; i<len; i++) { signal[i] = output[i]; // 将滤波后的信号复制回原数组 } free(output); // 释放内存空间 } int main() { double f0 = 1000.0; // 中心频率 double fs = 16000.0; // 采样频率 double* filter = (double*)malloc(sizeof(double)*FILTER_LEN); // 分配内存空间 generate_bandpass_filter(f0, fs, filter); // 生成带通滤波器 // 从麦克风或音频文件中读取语音信号 double* signal = read_audio_signal(); int len = get_audio_signal_length(); filter_signal(signal, filter, len); // 对语音信号进行滤波 // 将滤波后的信号写入音频文件或播放出来 write_audio_signal(signal, len); free(filter); // 释放内存空间 free(signal); return 0; } ``` 请注意,此代码仅用于演示目的。实际情况下,可能需要进行更多的错误处理和优化。此外,代码中的read_audio_signal(),get_audio_signal_length(),write_audio_signal()函数需要根据具体情况进行实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值