简单数字滤波实现算法(C语言源程序)
10种简单的数字滤波算法(C语言源程序)
10种简单的数字滤波算法(C语言源程序)假定从8位AD中读取数据(如果是更高位的AD可定义数据类型为int),子程序为get_ad();1、限副滤波/* A值可根据实际情况调整value为有效值,new_value为当前采样值滤波程序返回有效的实际值*/#define A 10char value;char filter(){char new_value;new_value = get_ad();if ( ( new_value - value > A ) || ( value - new_value > A )return value;return new_value;}2、中位值滤波法/* N值可根据实际情况调整排序采用冒泡法*/#define N 11char filter(){char value_buf[N];char count,i,j,temp;for ( count=0;count<n;count++)< p="">{value_buf[count] = get_ad();delay();for (j=0;j<n-1;j++)< p="">{for (i=0;i<n-j;i++)< p="">{if ( value_buf[i]>value_buf[i+1] ){temp = value_buf[i];value_buf[i] = value_buf[i+1];value_buf[i+1] = temp;}}}return value_buf[(N-1)/2];}3、算术平均滤波法*/#define N 12char filter(){int sum = 0;for ( count=0;count<n;count++)< p=""> {sum + = get_ad();delay();}return (char)(sum/N);}4、递推平均滤波法(又称滑动平均滤波法)/*#define N 12char value_buf[N];char i=0;char filter(){char count;int sum=0;value_buf[i++] = get_ad();if ( i == N ) i = 0;for ( count=0;count<n,count++)< p="">sum = value_buf[count];return (char)(sum/N);}5、中位值平均滤波法(又称防脉冲干扰平均滤波法)/* */#define N 12char filter(){char count,i,j;char value_buf[N];int sum=0;for (count=0;count<n;count++)< p="">{value_buf[count] = get_ad();delay();}for (j=0;j<n-1;j++)< p="">for (i=0;i<n-j;i++)< p="">{if ( value_buf[i]>value_buf[i+1] ){temp = value_buf[i];value_buf[i] = value_buf[i+1];value_buf[i+1] = temp;}}}for(count=1;count<n-1;count++)< p="">sum += value[count];return (char)(sum/(N-2));}6、限幅平均滤波法/**/略参考子程序1、37、一阶滞后滤波法/* 为加快程序处理速度假定基数为100,a=0~100 */ #define a 50char value;char filter(){char new_value;new_value = get_ad();return (100-a)*value + a*new_value;}8、加权递推平均滤波法/* coe数组为加权系数表,存在程序存储区。
c语言滤波程序
c语言滤波程序C语言滤波程序滤波是信号处理中常用的技术,它可以通过去除噪声或者平滑信号来提取出我们所关心的信息。
在C语言中,我们可以通过编写滤波程序来实现这一目的。
一、滤波的基本原理滤波的基本原理是通过对输入信号进行加权平均或者卷积运算,从而得到滤波后的输出信号。
常见的滤波方法有移动平均滤波、中值滤波和低通滤波等。
1. 移动平均滤波移动平均滤波是一种简单有效的滤波方法,它通过计算一定窗口大小内的信号均值来平滑信号。
具体步骤如下:(1)定义一个窗口大小N;(2)从输入信号的第一个样本开始,计算窗口内信号的均值;(3)将计算得到的均值作为输出信号,并将窗口向后移动一个样本;(4)重复上述步骤,直到处理完所有样本。
2. 中值滤波中值滤波是一种非线性滤波方法,它通过计算窗口内信号的中值来平滑信号。
具体步骤如下:(1)定义一个窗口大小N;(2)从输入信号的第一个样本开始,将窗口内的信号排序,取中间值作为输出信号;(3)将窗口向后移动一个样本;(4)重复上述步骤,直到处理完所有样本。
3. 低通滤波低通滤波是一种常用的滤波方法,它可以去除高频噪声,保留低频信号。
具体步骤如下:(1)定义一个截止频率fc;(2)将输入信号进行傅里叶变换,得到频域表示;(3)将高于截止频率的部分置零,得到滤波后的频域表示;(4)将滤波后的频域表示进行傅里叶反变换,得到滤波后的时域信号。
二、C语言实现滤波程序在C语言中,我们可以使用数组来表示信号,并通过循环和条件判断语句来实现滤波算法。
下面以移动平均滤波为例,给出一个简单的滤波程序:```c#include <stdio.h>#define WINDOW_SIZE 5float movingAverageFilter(float signal[], int size){float filteredSignal[size];int i, j;float sum;for (i = 0; i < size; i++){sum = 0;for (j = i - WINDOW_SIZE / 2; j <= i + WINDOW_SIZE / 2; j++){if (j >= 0 && j < size){sum += signal[j];}}filteredSignal[i] = sum / WINDOW_SIZE;}return filteredSignal;}int main(){float signal[] = {1.2, 2.5, 3.1, 4.6, 5.2, 6.3, 7.4, 8.9, 9.7, 10.3}; int size = sizeof(signal) / sizeof(float);float filteredSignal[size];filteredSignal = movingAverageFilter(signal, size);for (int i = 0; i < size; i++){printf("%.2f ", filteredSignal[i]);}printf("\n");return 0;}```在这个程序中,我们首先定义了一个窗口大小WINDOW_SIZE,然后定义了一个移动平均滤波函数movingAverageFilter。
C语言滤波算法实现
C语言滤波算法实现滤波算法是信号处理领域中一种常见的技术,用于去除信号中的噪声或不需要的部分,以提取出我们感兴趣的特征。
在C语言中,实现滤波算法可以有效地处理信号,提高信号质量和可靠性。
本文将介绍C语言中一些常见的滤波算法及其实现方法。
一、均值滤波算法均值滤波算法是一种简单而常用的滤波算法,它通过计算信号中一定窗口内像素值的平均值,替代该窗口内的每个像素值,从而达到去除噪声的目的。
下面是C语言中实现均值滤波算法的示例代码:```c#include <stdio.h>#define SIZE 5void meanFilter(int data[], int length) {int result[length];int sum = 0;for (int i = 0; i < length; i++) {sum = 0;for (int j = i - SIZE / 2; j <= i + SIZE / 2; j++) {if (j >= 0 && j < length) {sum += data[j];}}result[i] = sum / SIZE;}for (int i = 0; i < length; i++) {printf("%d ", result[i]);}}int main() {int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int length = sizeof(data) / sizeof(data[0]);meanFilter(data, length);return 0;}```在上述代码中,我们定义了一个`meanFilter`函数来实现均值滤波。
该函数接受一个整型数组`data`和数组长度`length`作为参数。
在函数内部,我们使用一个大小为5的滑动窗口,对每个像素进行均值计算,并将结果存储在一个新的数组`result`中。
一阶低通滤波c代码
一阶低通滤波c代码以下是一个简单的一阶低通滤波器的C代码实现。
一阶低通滤波器通常用于平滑数据,减少噪声。
它的工作原理是基于前一个输出样本和当前输入样本来计算新的输出样本。
请注意,以下代码假定你已经定义了一个合适的数据类型(如float),并且你的编译器支持基本的数学运算。
c#include <stdio.h>// 定义数据类型typedef float DataType;// 一阶低通滤波器结构体typedef struct {DataType alpha; // 滤波系数,取值范围0到1DataType prevOutput; // 上一次的输出值} FirstOrderLowPassFilter;// 初始化滤波器void initFilter(FirstOrderLowPassFilter *filter, DataType alpha) {filter->alpha = alpha;filter->prevOutput = 0.0;}// 应用滤波器DataType applyFilter(FirstOrderLowPassFilter *filter, DataType input) { DataType output = filter->alpha * input + (1.0 - filter->alpha) * filter->prevOutput;filter->prevOutput = output;return output;}int main() {FirstOrderLowPassFilter filter;DataType input, output;// 初始化滤波器,设置滤波系数为0.1initFilter(&filter, 0.1);// 假设我们有一个输入信号,这里用简单的for循环模拟for (int i = 0; i < 10; i++) {input = (i % 2 == 0) ? 10.0 : 0.0; // 模拟一个方波信号output = applyFilter(&filter, input);printf("Input: %f, Output: %f\n", input, output);}return 0;}以上代码首先定义了一个FirstOrderLowPassFilter结构体,它包含滤波系数alpha 和上一个输出值prevOutput。
数学滤波c语言
数学滤波c语言
数学滤波是一种信号处理技术,通过数学函数对信号进行平滑处理,去除噪声和干扰。
在C语言中实现数学滤波可以采用不同的算法,比如移动平均滤波、中值滤波、傅里叶变换等。
下面是一个简单的移动平均滤波器的C语言实现示例:
```c
include <>
define N 5 // 滤波器长度
void moving_average_filter(int input, int output, int length) {
int i, j;
int sum = 0;
for (i = 0; i < length; i++) {
sum += input[i];
output[i] = sum / (i + 1);
}
}
int main() {
int input[N] = {1, 2, 3, 4, 5}; // 输入信号
int output[N]; // 输出信号
moving_average_filter(input, output, N); // 滤波处理
for (int i = 0; i < N; i++) {
printf("%d ", output[i]); // 输出处理后的信号
}
return 0;
}
```
在这个示例中,我们定义了一个长度为N的移动平均滤波器。
在
`moving_average_filter`函数中,我们遍历输入信号,对每个数据点进行累加,并计算移动平均值。
最后,在`main`函数中,我们调用
`moving_average_filter`函数对输入信号进行处理,并输出处理后的信号。
十一种滤波方法及C语言程序
一.十一种通用滤波算法(转)1、限幅滤波法(又称程序判断滤波法)A、方法:根据经验判断,确定两次采样允许的最大偏差值(设为A)每次检测到新值时判断:如果本次值与上次值之差<=A,则本次值有效如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值B、优点:能有效克服因偶然因素引起的脉冲干扰C、缺点无法抑制那种周期性的干扰平滑度差2、中位值滤波法A、方法:连续采样N次(N取奇数)把N次采样值按大小排列取中间值为本次有效值B、优点:能有效克服因偶然因素引起的波动干扰对温度、液位的变化缓慢的被测参数有良好的滤波效果C、缺点:对流量、速度等快速变化的参数不宜3、算术平均滤波法A、方法:连续取N个采样值进行算术平均运算N值较大时:信号平滑度较高,但灵敏度较低N值较小时:信号平滑度较低,但灵敏度较高N值的选取:一般流量,N=12;压力:N=4B、优点:适用于对一般具有随机干扰的信号进行滤波这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动C、缺点:对于测量速度较慢或要求数据计算速度较快的实时控制不适用比较浪费RAM4、递推平均滤波法(又称滑动平均滤波法)A、方法:把连续取N个采样值看成一个队列队列的长度固定为N每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则) 把队列中的N个数据进行算术平均运算,就可获得新的滤波结果N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4B、优点:对周期性干扰有良好的抑制作用,平滑度高适用于高频振荡的系统C、缺点:灵敏度低对偶然出现的脉冲性干扰的抑制作用较差不易消除由于脉冲干扰所引起的采样值偏差不适用于脉冲干扰比较严重的场合比较浪费RAM5、中位值平均滤波法(又称防脉冲干扰平均滤波法)A、方法:相当于“中位值滤波法”+“算术平均滤波法”连续采样N个数据,去掉一个最大值和一个最小值然后计算N-2个数据的算术平均值N值的选取:3~14B、优点:融合了两种滤波法的优点对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差C、缺点:测量速度较慢,和算术平均滤波法一样比较浪费RAM6、限幅平均滤波法A、方法:相当于“限幅滤波法”+“递推平均滤波法”每次采样到的新数据先进行限幅处理,再送入队列进行递推平均滤波处理B、优点:融合了两种滤波法的优点对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差C、缺点:比较浪费RAM7、一阶滞后滤波法A、方法:取a=0~1本次滤波结果=(1-a)*本次采样值+a*上次滤波结果B、优点:对周期性干扰具有良好的抑制作用适用于波动频率较高的场合C、缺点:相位滞后,灵敏度低滞后程度取决于a值大小不能消除滤波频率高于采样频率的1/2的干扰信号8、加权递推平均滤波法A、方法:是对递推平均滤波法的改进,即不同时刻的数据加以不同的权通常是,越接近现时刻的数据,权取得越大。
用C语言实现数字滤波
标题:用C语言实现数字滤波2008-05-09 16:17:33在工业过程控制系统中,由于被控对象的环境比较恶劣,干扰源比较多,仪器、仪表采集的信息常会受到干扰,所以在模拟系统中,为了消除干扰,常采用RC滤波电路,而在由工业控制计算机组成的自动检测系统中,为了提高采样的可靠性,减少虚假信息的影响,常常采用数字滤波的方法。
数字滤波的方法有很多种,可以根据不同的测量参数进行选择。
下面给出几种常用的数字滤波方法的C语言函数,这些函数有一定的通用性,用Turbo C 2.0编制而成,在研华IPC-610/386机上均编译通过,适用于PC机及其兼容机。
1. 程序判数滤波采样的信号,如因常受到随机干扰传感器不稳定而引起严重失真时,可以采用此方法。
方法是:根据生产经验确定两交采样允许的最大偏差△×,若先后两次采样的信号相减数值大于△×,表明输入的是干扰信号,应该去掉;用上次采样值作为本次采样值,若小于、等于△×表明没有受到干扰,本次采样值效。
该方法适用于慢变化的物理参数的采样,如温度、物理位置等测量系统。
程序判断滤波的C程序函数如下:float program_detect_filter(float old_new_value[], float X){float sample_value;if (fabs(old_new_value[1]_old_new_value[0])>X)sample_value=old_new_value[0];elsesample_value=old_new_value[1];retrun(sample_value);}函数调用需一个一维的两个元素的数组(old_new_value[2],用于存放上次采样值(old_new_v alue[0],)和本次采样值(old_new_value[1],),函数中sample_value表示有效采样值,X表示根据根据经验确定的两次采样允许的最大偏差△×。
FIR数字滤波器设计(窗函数法)C语言实现
FIR数字滤波器设计(窗函数法)C语⾔实现背景介绍:理想滤波器在物理上是不可实现的,其单位脉冲响应是⽆限长、⾮因果的。
窗函数法,就是从时域出发,⽤有限长、因果的单位脉冲响应h(n)去逼近理想滤波器的⽆限长、⾮因果的单位脉冲响应的⽅法。
窗函数法⼜叫傅⾥叶级数法。
更多背景资料,请看数字信号处理(李永全),P175。
⽅法简介:设N-1阶FIR数字滤波器的单位冲击响应为h(n),则传递函数H(z)为:窗函数法的设计步骤如下:1.根据给定的理想频率响应Hd(e^jw),利⽤傅⾥叶反变换,求出单位冲击响应hd(n):2.将hd(n)乘以窗函数w(n),得到所要求的FIR滤波器系数h(n):3.求卷积:使⽤说明⼦函数语句:void firwin(int n, int band, int wn, int fs, double h[], double kaiser=0.0, double fln=0.0, double fhn=0.0);形参说明n:滤波器的阶数band:滤波器的类型,取值1-4,分别为低通、带通、带阻、⾼通滤波器wn:窗函数的类型,取值1-7,分别对应矩形窗、图基窗、三⾓窗、汉宁窗、海明窗、布拉克曼窗和凯塞窗fs:采样频率h:存放滤波器的系数kaiser:beta值fln:带通下边界频率fhn:带通上边界频率源代码void firwin(int n, int band, int wn, int fs, double h[], double kaiser, double fln, double fhn){int i;int n2;int mid;double s;double pi;double wc1;double wc2;double beta;double delay;beta = kaiser;pi = 4.0 * atan(1.0); //pi=PI;if ((n % 2) == 0)/*如果阶数n是偶数*/{n2 = (n / 2) - 1;/**/mid = 1;//}else{n2 = n / 2;//n是奇数,则窗⼝长度为偶数mid = 0;}delay = n / 2.0;wc1 = 2 * pi * fln;wc2 = 2 * pi * fhn;switch (band){case 1:{for (i=0; i<=n2; ++i){s = i - delay;h[i] = (sin(wc1 * s / fs) / (pi * s)) * window(wn, n+1, i, beta);//低通,窗⼝长度=阶数+1,故为n+1h[n - i] = h[i];}if (mid == 1){h[n / 2] = wc1 / pi;//n为偶数时,修正中间值系数}break;}case 2:{for (i=0; i<=n2; i++){s = i - delay;h[i] = (sin(wc2 * s / fs) - sin(wc1 * s / fs)) / (pi * s);//带通h[i] = h[i] * window(wn, n+1, i, beta);h[n-i] = h[i];}if (mid == 1){h[n / 2] = (wc2 - wc1) / pi;}break;}case 3:{for (i=0; i<=n2; ++i){s = i - delay;h[i] = (sin(wc1 * s / fs) + sin(pi * s) - sin(wc2 * s / fs)) / (pi * s);//带阻 h[i] = h[i] * window(wn, n+1, i, beta);h[n - i] = h[i];}if (mid == 1){h[n / 2] = (wc1 + pi - wc2) / pi;}break;}case 4:{for (i=0; i<=n2; i++){s = i - delay;h[i] = (sin(pi * s) - sin(wc1 * s / fs)) / (pi * s);//⾼通h[i] = h[i] * window(wn, n+1, i, beta);h[n-i] = h[i];}if (mid == 1){h[n / 2] = 1.0 - wc1 / pi;}break;}}}//n:窗⼝长度 type:选择窗函数的类型 beta:⽣成凯塞窗的系数static double window(int type, int n, int i, double beta){int k;double pi;double w;pi = 4.0 * atan(1.0); //pi=PI;w = 1.0;switch (type){case 1:{w = 1.0; //矩形窗break;}case 2:{k = (n - 2) / 10;if (i <= k){w = 0.5 * (1.0 - cos(i * pi / (k + 1))); //图基窗}if (i > n-k-2){w = 0.5 * (1.0 - cos((n - i - 1) * pi / (k + 1)));}break;}case 3:{w = 1.0 - fabs(1.0 - 2 * i / (n - 1.0));//三⾓窗break;}case 4:{w = 0.5 * (1.0 - cos( 2 * i * pi / (n - 1)));//汉宁窗break;}case 5:{w = 0.54 - 0.46 * cos(2 * i * pi / (n - 1));//海明窗break;}case 6:{w = 0.42 - 0.5 * cos(2 * i * pi / (n - 1)) + 0.08 * cos(4 * i * pi / (n - 1));//布莱克曼窗 break;}case 7:{w = kaiser(i, n, beta);//凯塞窗break;}}return(w);}static double kaiser(int i, int n, double beta){double a;double w;double a2;double b1;double b2;double beta1;b1 = bessel0(beta);a = 2.0 * i / (double)(n - 1) - 1.0;a2 = a * a;beta1 = beta * sqrt(1.0 - a2);b2 = bessel0(beta1);w = b2 / b1;return(w);}static double bessel0(double x){int i;double d;double y;double d2;double sum;y = x / 2.0;d = 1.0;sum = 1.0;for (i=1; i<=25; i++){d = d * y / i;d2 = d * d;sum = sum + d2;if (d2 < sum*(1.0e-8)){break;}}return(sum);}得到系数之后,与输⼊信号求卷积即可!。
【论文设计】平均值法数字滤波器的C语言算法及其实现
防脉冲干扰移动平均值法数字滤波器的C语言算法及其实现在许多的数据采集系统中,现场的强电设备较多,不可避免地会产生尖脉冲干扰,这种干扰一般持续时间短,峰值大,对这样的数据进行数字滤波处理时,仅仅采用算术平均或移动平均滤波时,尽管对脉冲干扰进行了1/n的处理,但,其剩余值仍然较大。
这种场合最好的策略是:将被认为是受干扰的信号数据去掉,这就是防脉冲干扰平均值滤波法的原理。
防脉冲干扰平均值滤波法的算法是:对连续的n个数据进行排序,去掉其中最大和最小的2个数据,将剩余数据示平均值。
在一般8051单片机的应用中为了加快数据处理速度,n可以取值6。
而对于具有较快速度的处理器,则n值可以适当取大一些。
但最好是n=2^k+2, k为整数,因为这样在求平均值average=SUM/(n-2)=SUM/2^k 时,可以写成average=SUM>>k,用移位的方法,可以加快处理速度。
上述算法显然还存在一个不足之处,就是每采集一个数据就要进行一次排序,这样会大量占用系统宝贵的时间。
这可以通过存储当前数据中的最大值和最小值来改进。
具体做法是:系统中用两个变量来存储当前n个数据的最大值和最小值在这个数组中的偏移量(也就是数组下标,存储数组下标而直接不存储数据本身是因为:在一般的系统中,n不会超无符号短整形的表示范围,因此用一个char形变量就可以存储了而如果直接存储数据本身,则许多情况下要用int形变量,甚至更长的类型)。
这样只要在当前输入的数据将要覆盖的数据正好是当前的最大值或最小值时才在下个数组中查找最大值或最小值,而其他情况下则只要将输入的数据与最大值和最小值比较就可以修改下最大值和最小值了,而且不用进行数据排序。
这个算法很简单,下面是对应的C语言代码实现,可以很方便的应用的具体的51单片机,或其他处理器上,只须做少量的修改。
#i nclude"stdio.h"#define dtype unsigned int // 采集数据的数据类型#define uint8 char#define LEN 6 //移动算术平均的个数+2=SHIFT<<2+2#define SHIFT 2 //2^SHIFTuint8 pdata; //移动指针uint8 pmax,pmin; //记录数据表中最大值和最小值的位置,//在一般的数据采集系统中,数据的长度>=8,//因此用指针记录而不是直接记录最大值和最小值dtype datas[LEN];dtype szlb(dtype _data){/****************************//* 在调用此子程序前必须对 *//* pdata,datas[]数组, *//* pmax,pmin进行初始化 *//****************************/uint8 i;dtype average=0; //清零,用来计算平均值pdata=(pdata+1)%LEN; //指针下标在0到LEN-1上滑动datas[pdata]=_data; //采样所得数据存入数据表中for(i=0;i<LEN;i++)average+=datas[i]; //求所有数据总和/*******去除被认为是脉冲的数据******/if(_data>datas[pmax])pmax=pdata; //得到最大值的指针else if(_data<datas[pmin])pmin=pdata; //得到最小值的指针if(pdata==pmax) //如果当前输入值将存入当前最大值的位置时 { //由以上方法将不可行,必须从其他位置中查找极值for(i=0;i<LEN;i++)if(datas[i]>datas[pmax])pmax=i;}else if(pdata==pmin)//如果当前输入值将存入当前最大值的位置时 { //由以上方法将不可行,必须从其他位置中查找极值for(i=0;i<LEN;i++)if(datas[i]<datas[pmin])pmin=i;}average=average-datas[pmax]-datas[pmin];//减去脉冲return (average>>SHIFT); //求算术平均值}/******以下是在VC++6.0环境下运行的测试程序**//***通过手动输入来模拟数据采集过程****/void main(){uint8 i;dtype _data;pdata=0;pmax=0;pmin=0;for(i=0;i<LEN;i++)datas[i]=0;printf("数据: 最大 最小\n");while(1){scanf("%u",&_data);szlb(_data);for(i=0;i<LEN;i++)printf("%-3u ",datas[i]);printf(" %-3u %-3u",datas[pmax],datas[pmin]); printf("\n");}}本文来自互联网,原文地址:/user1/349/archives/2006/7707.html。
10种简单的数字滤波算法(C++源程序)
10种简单的数字滤波算法(C++源程序)以下是10种简单的数字滤波算法C++实现示例:1. 均值滤波均值滤波是数字滤波算法的一种常见形式,它可以通过计算一定范围内像素值的平均值来平滑图像。
其C++实现如下:#include <iostream>#include <opencv2/opencv.hpp>using namespace std;using namespace cv;// Function to implement mean filtervoid meanBlur(Mat& img, Mat& result, int k_size){int img_rows = img.rows;int img_cols = img.cols;// Create a same sized blank imageresult.create(img_rows, img_cols, img.type());for(int r=0; r<img_rows; r++){for(int c=0; c<img_cols; c++){// Define the window of radius k_sizeint r_min = max(0, r-k_size/2);int r_max = min(img_rows-1, r+k_size/2);int c_min = max(0, c-k_size/2);int c_max = min(img_cols-1, c+k_size/2);// Calculate the mean valueint sum = 0;int count = 0;for (int i=r_min; i<=r_max; i++){for (int j=c_min; j<=c_max; j++){sum += img.at<uchar>(i,j);count++;}}result.at<uchar>(r,c) = (uchar) (sum/count);}}}int main(int argc, char** argv){// Load the imageMat img = imread("image.jpg", 0);// Check if image is loaded properlyif(!img.data){cout << "Failed to load image" << endl;return -1;}// Define the kernel sizeint k_size = 3;// Apply mean filterMat result;meanBlur(img, result, k_size);// Display the resultnamedWindow("Original Image", WINDOW_NORMAL);namedWindow("Mean Filtered Image", WINDOW_NORMAL);imshow("Original Image", img);imshow("Mean Filtered Image", result);waitKey(0);return 0;}在上述代码中,`meanBlur()` 函数接收一个输入图像`img` 和一个输出图像`result`,以及一个整数参数`k_size`,该参数指定滤波器的大小,即窗口的半径。
c语言正弦信号滤波
c语言正弦信号滤波
在C语言中进行正弦信号滤波的实现,可以采用简单的数字滤波算法。
以下是一种常用的滤波器设计方法:
1. 定义一个数组作为输入和输出缓存,用来存储待滤波信号和滤波后的信号。
2. 初始化输入缓存和输出缓存,将它们的值设为0。
3. 定义滤波器的阶数和截止频率。
4. 创建一个函数,用来实现滤波器计算。
函数的输入参数为输入缓存和输出缓存。
5. 在滤波函数中,利用差分方程或者传递函数的方法,根据输入缓存的值计算输出缓存的值。
6. 将输出缓存的值返回给主函数,作为滤波后的信号。
7. 在主函数中,通过正弦函数产生一个输入信号。
8. 将输入信号传递给滤波函数进行滤波处理。
9. 将滤波后的信号打印输出或者进行其他处理。
这是一个简单的C语言滤波器实现的步骤,可以根据具体的滤波需求进行调整和优化。
需要注意的是,在实际应用中,滤波器的设计还需要考虑一些其他的因素,比如采样频率、滤波器的稳定性等。
十一种滤波方法及C语言程序
一. 十一种通用滤波算法(转)1、限幅滤波法(又称程序判断滤波法)A、方法:根据经验判断,确定两次采样允许的最大偏差值(设为A)每次检测到新值时判断:如果本次值与上次值之差<=A, 则本次值有效如果本次值与上次值之差>A, 则本次值无效, 放弃本次值, 用上次值代替本次值B、优点:能有效克服因偶然因素引起的脉冲干扰C缺点无法抑制那种周期性的干扰平滑度差2、中位值滤波法A、方法:连续采样N次(N取奇数)把N 次采样值按大小排列取中间值为本次有效值B、优点:能有效克服因偶然因素引起的波动干扰对温度、液位的变化缓慢的被测参数有良好的滤波效果C缺点:对流量、速度等快速变化的参数不宜3、算术平均滤波法A、方法:连续取N 个采样值进行算术平均运算N 值较大时:信号平滑度较高,但灵敏度较低N 值较小时:信号平滑度较低,但灵敏度较高N值的选取:一般流量,N=12;压力:N=4B、优点:适用于对一般具有随机干扰的信号进行滤波这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动C缺点:对于测量速度较慢或要求数据计算速度较快的实时控制不适用比较浪费RAM4、递推平均滤波法(又称滑动平均滤波法)A、方法:把连续取N个采样值看成一个队列队列的长度固定为N 每次采样到一个新数据放入队尾, 并扔掉原来队首的一次数据.(先进先出原则)把队列中的N个数据进行算术平均运算,就可获得新的滤波结果N值的选取:流量,N=12;压力:N=4;液面,N=4〜12;温度,N=1〜4 B、优点:对周期性干扰有良好的抑制作用,平滑度高适用于高频振荡的系统C缺点:灵敏度低对偶然出现的脉冲性干扰的抑制作用较差不易消除由于脉冲干扰所引起的采样值偏差不适用于脉冲干扰比较严重的场合比较浪费RAM5、中位值平均滤波法(又称防脉冲干扰平均滤波法)A、方法:相当于“中位值滤波法” +“算术平均滤波法”连续采样N个数据,去掉一个最大值和一个最小值然后计算N-2 个数据的算术平均值N 值的选取:3〜14B、优点:融合了两种滤波法的优点对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差C缺点:测量速度较慢,和算术平均滤波法一样比较浪费RAM6、限幅平均滤波法A、方法:相当于“限幅滤波法” +“递推平均滤波法” 每次采样到的新数据先进行限幅处理,再送入队列进行递推平均滤波处理B、优点:融合了两种滤波法的优点对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差C缺点:比较浪费RAM7、一阶滞后滤波法A、方法:取a=0〜1本次滤波结果=(1-a)*本次采样值+a*上次滤波结果B、优点:对周期性干扰具有良好的抑制作用适用于波动频率较高的场合C缺点:相位滞后,灵敏度低滞后程度取决于 a 值大小不能消除滤波频率高于采样频率的1/2 的干扰信号8、加权递推平均滤波法A、方法:是对递推平均滤波法的改进,即不同时刻的数据加以不同的权通常是,越接近现时刻的数据,权取得越大。
10种简单的数字滤波C语言源程序算法
10种简单的数字滤波C语言源程序算法(2009-11-09 10:25:08)假定从8位AD中读取数据(如果是更高位的AD可定义数据类型为int),子程序为get_ad();1、限幅滤波法(又称程序判断滤波法)A、方法:根据经验判断,确定两次采样允许的最大偏差值(设为A)每次检测到新值时判断:如果本次值与上次值之差<=A,则本次值有效如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值B、优点:能有效克服因偶然因素引起的脉冲干扰C、缺点无法抑制那种周期性的干扰平滑度差2、中位值滤波法A、方法:连续采样N次(N取奇数)把N次采样值按大小排列取中间值为本次有效值B、优点:能有效克服因偶然因素引起的波动干扰对温度、液位的变化缓慢的被测参数有良好的滤波效果C、缺点:对流量、速度等快速变化的参数不宜3、算术平均滤波法A、方法:连续取N个采样值进行算术平均运算N值较大时:信号平滑度较高,但灵敏度较低N值较小时:信号平滑度较低,但灵敏度较高N值的选取:一般流量,N=12;压力:N=4B、优点:适用于对一般具有随机干扰的信号进行滤波这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动C、缺点:对于测量速度较慢或要求数据计算速度较快的实时控制不适用比较浪费RAM4、递推平均滤波法(又称滑动平均滤波法)A、方法:把连续取N个采样值看成一个队列队列的长度固定为N每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则) 把队列中的N个数据进行算术平均运算,就可获得新的滤波结果N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4 B、优点:对周期性干扰有良好的抑制作用,平滑度高适用于高频振荡的系统C、缺点:灵敏度低对偶然出现的脉冲性干扰的抑制作用较差不易消除由于脉冲干扰所引起的采样值偏差不适用于脉冲干扰比较严重的场合比较浪费RAM5、中位值平均滤波法(又称防脉冲干扰平均滤波法)A、方法:相当于“中位值滤波法”+“算术平均滤波法”连续采样N个数据,去掉一个最大值和一个最小值然后计算N-2个数据的算术平均值N值的选取:3~14B、优点:融合了两种滤波法的优点对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差C、缺点:测量速度较慢,和算术平均滤波法一样比较浪费RAM6、限幅平均滤波法A、方法:相当于“限幅滤波法”+“递推平均滤波法”每次采样到的新数据先进行限幅处理,再送入队列进行递推平均滤波处理B、优点:融合了两种滤波法的优点对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差C、缺点:比较浪费RAM7、一阶滞后滤波法A、方法:取a=0~1本次滤波结果=(1-a)*本次采样值+a*上次滤波结果B、优点:对周期性干扰具有良好的抑制作用适用于波动频率较高的场合C、缺点:相位滞后,灵敏度低滞后程度取决于a值大小不能消除滤波频率高于采样频率的1/2的干扰信号8、加权递推平均滤波法A、方法:是对递推平均滤波法的改进,即不同时刻的数据加以不同的权通常是,越接近现时刻的数据,权取得越大。
(完整word版)经典滤波算法及C语言程序
经典的滤波算法(转)1、限幅滤波法(又称程序判断滤波法)A、方法:根据经验判断,确定两次采样允许的最大偏差值(设为A)每次检测到新值时判断:如果本次值与上次值之差<=A,则本次值有效如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值B、优点:能有效克服因偶然因素引起的脉冲干扰C、缺点无法抑制那种周期性的干扰平滑度差2、中位值滤波法A、方法:连续采样N次(N取奇数)把N次采样值按大小排列取中间值为本次有效值B、优点:能有效克服因偶然因素引起的波动干扰对温度、液位的变化缓慢的被测参数有良好的滤波效果C、缺点:对流量、速度等快速变化的参数不宜3、算术平均滤波法A、方法:连续取N个采样值进行算术平均运算N值较大时:信号平滑度较高,但灵敏度较低N值较小时:信号平滑度较低,但灵敏度较高N值的选取:一般流量,N=12;压力:N=4B、优点:适用于对一般具有随机干扰的信号进行滤波这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动C、缺点:对于测量速度较慢或要求数据计算速度较快的实时控制不适用比较浪费RAM递推平均滤波法对偶然出现的脉冲性干扰的抑制作用较差4、递推平均滤波法(又称滑动平均滤波法)A、方法:把连续取N个采样值看成一个队列队列的长度固定为N每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则)把队列中的N个数据进行算术平均运算,就可获得新的滤波结果N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4B、优点:对周期性干扰有良好的抑制作用,平滑度高适用于高频振荡的系统C、缺点:灵敏度低对偶然出现的脉冲性干扰的抑制作用较差不易消除由于脉冲干扰所引起的采样值偏差不适用于脉冲干扰比较严重的场合比较浪费RAM5、中位值平均滤波法(又称防脉冲干扰平均滤波法)A、方法:相当于“中位值滤波法”+“算术平均滤波法”连续采样N个数据,去掉一个最大值和一个最小值然后计算N-2个数据的算术平均值N值的选取:3~14B、优点:融合了两种滤波法的优点对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差C、缺点:测量速度较慢,和算术平均滤波法一样比较浪费RAM6、限幅平均滤波法A、方法:相当于“限幅滤波法”+“递推平均滤波法”每次采样到的新数据先进行限幅处理,再送入队列进行递推平均滤波处理B、优点:融合了两种滤波法的优点对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差C、缺点:比较浪费RAM7、一阶滞后滤波法A、方法:取a=0~1本次滤波结果=(1-a)*本次采样值+a*上次滤波结果B、优点:对周期性干扰具有良好的抑制作用适用于波动频率较高的场合C、缺点:相位滞后,灵敏度低滞后程度取决于a值大小不能消除滤波频率高于采样频率的1/2的干扰信号8、加权递推平均滤波法A、方法:是对递推平均滤波法的改进,即不同时刻的数据加以不同的权通常是,越接近现时刻的数据,权取得越大。
c语言完成fir滤波器
实现FIR 滤波器的C 语言代码涉及到定义滤波器的系数和设计滤波的算法。
FIR 滤波器是一种数字滤波器,其输出是输入信号与一组权重系数的卷积。
以下是一个简单的 C 语言实现FIR 滤波器的示例:#include <stdio.h>#define N 5 // 滤波器的阶数// FIR 滤波器的系数const double h[N] = {0.1, 0.2, 0.3, 0.2, 0.1};// FIR 滤波器的状态double x[N];// 函数:FIR 滤波器处理double fir_filter(double input) {int i;double output = 0;// 将输入数据放入滤波器状态数组for (i = N - 1; i > 0; i--) {x[i] = x[i - 1];}x[0] = input;// 计算输出for (i = 0; i < N; i++) {output += h[i] * x[i];}return output;}int main() {// 输入信号double input_signal[] = {1.0, 2.0, 3.0, 4.0, 5.0, 4.0, 3.0, 2.0, 1.0};// 处理输入信号for (int i = 0; i < sizeof(input_signal) / sizeof(double); i++) {double output = fir_filter(input_signal[i]);printf("Input: %.1f, Output: %.3f\n", input_signal[i], output);}return 0;}在这个示例中,fir_filter 函数实现了对输入信号的FIR 滤波操作。
x 数组用于存储FIR 滤波器的状态,h 数组是FIR 滤波器的系数。
10种数字滤波法 c语言
假定从8位AD中读取数据(如果是更高位的AD可定义数据类型为int),子程序为get_ad();1、限副滤波/* A值可根据实际情况调整value为有效值,new_value为当前采样值滤波程序返回有效的实际值*/#define A 10char value;char filter(){char new_value;new_value = get_ad();if ( ( new_value - value > A ) || ( value - new_value > A )return value;return new_value;}2、中位值滤波法/* N值可根据实际情况调整排序采用冒泡法*/#define N 11char filter(){char value_buf[N];char count,i,j,temp;for ( count=0;count<N;count++){value_buf[count] = get_ad();delay();}for (j=0;j<N-1;j++){for (i=0;i<N-j;i++){if ( value_buf>value_buf[i+1] ){temp = value_buf;value_buf = value_buf[i+1];value_buf[i+1] = temp;}}return value_buf[(N-1)/2];}3、算术平均滤波法/**/#define N 12char filter(){int sum = 0;for ( count=0;count<N;count++){sum + = get_ad();delay();}return (char)(sum/N);}4、递推平均滤波法(又称滑动平均滤波法)/**/#define N 12char value_buf[N];char i=0;char filter(){char count;int sum=0;value_buf[i++] = get_ad();if ( i == N ) i = 0;for ( count=0;count<N,count++)sum = value_buf[count];return (char)(sum/N);}5、中位值平均滤波法(又称防脉冲干扰平均滤波法)/**/#define N 12char filter()char count,i,j;char value_buf[N];int sum=0;for (count=0;count<N;count++){value_buf[count] = get_ad();delay();}for (j=0;j<N-1;j++){for (i=0;i<N-j;i++){if ( value_buf>value_buf[i+1] ){temp = value_buf;value_buf = value_buf[i+1];value_buf[i+1] = temp;}}}for(count=1;count<N-1;count++)sum += value[count];return (char)(sum/(N-2));}6、限幅平均滤波法/**/略参考子程序1、37、一阶滞后滤波法/* 为加快程序处理速度假定基数为100,a=0~100 */ #define a 50char value;char filter(){char new_value;new_value = get_ad();return (100-a)*value + a*new_value;}8、加权递推平均滤波法/* coe数组为加权系数表,存在程序存储区。
fir滤波器公式c语言
fir滤波器公式c语言FIR滤波器是一种常用的数字滤波器,它通过对输入信号的加权求和来实现信号的滤波处理。
在这篇文章中,我们将介绍FIR滤波器的公式以及如何用C语言来实现它。
FIR滤波器的全称是有限脉冲响应滤波器(Finite Impulse Response Filter),它的特点是其响应仅在有限的时间范围内存在。
FIR滤波器的输入信号经过一系列的加权系数和延迟单元的处理,最终得到滤波后的输出信号。
FIR滤波器的公式可以表示为:y(n) = h(0) * x(n) + h(1) * x(n-1) + h(2) * x(n-2) + ... + h(N-1) * x(n-(N-1))其中,y(n)表示滤波器的输出信号,x(n)表示滤波器的输入信号,h(i)表示滤波器的第i个加权系数,N表示滤波器的阶数。
在C语言中,我们可以使用数组来表示滤波器的加权系数,使用循环来实现滤波器的延迟处理。
下面是一个简单的示例代码:```c#define N 10 // 滤波器的阶数float h[N] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.4, 0.3, 0.2, 0.1, 0.05}; // 滤波器的加权系数float x[N] = {0}; // 输入信号的延迟单元float y = 0; // 滤波器的输出信号void firFilter(float input) {// 将输入信号插入延迟单元for (int i = N-1; i >= 1; i--) {x[i] = x[i-1];}x[0] = input;// 计算滤波器的输出信号y = 0;for (int i = 0; i < N; i++) {y += h[i] * x[i];}}int main() {// 输入信号float input = 0.5;// 执行滤波处理firFilter(input);// 输出滤波器的输出信号printf("滤波器的输出信号为:%f\n", y);return 0;}```在上面的示例代码中,我们定义了一个长度为N的加权系数数组h,一个长度为N的延迟单元数组x,以及一个输出信号变量y。
拉氏变换差分方程c语言,IIR数字滤波器的实现(C语言)
拉⽒变换差分⽅程c语⾔,IIR数字滤波器的实现(C语⾔)经典滤波器和数字滤波器⼀般滤波器可以分为经典滤波器和数字滤波器。
经典滤波器:假定输⼊信号中的有⽤成分和希望去除的成分各⾃占有不同的频带。
如果信号和噪声的频谱相互重迭,经典滤波器⽆能为⼒。
⽐如 FIR 和 IIR 滤波器等。
现代滤波器:从含有噪声的时间序列中估计出信号的某些特征或信号本⾝。
现代滤波器将信号和噪声都视为随机信号。
包括 Wiener Filter、Kalman Filter、线性预测器、⾃适应滤波器等Z变换和差分⽅程在连续系统中采⽤拉普拉斯变换求解微分⽅程,并直接定义了传递函数,成为研究系统的基本⼯具。
在采样系统中,连续变量变成了离散量,将Laplace变换⽤于离散量中,就得到了Z变换。
和拉⽒变换⼀样,Z变换可⽤来求解差分⽅程,定义Z传递函数成为分析研究采样系统的基本⼯具。
对于⼀般常⽤的信号序列,可以直接查表找出其Z变换。
相应地,也可由信号序列的Z变换查出原信号序列,从⽽使求取信号序列的Z变换较为简便易⾏。
Z变换有许多重要的性质和定理:线性定理设a,a1,a2为任意常数,连续时间函数f(t),f1(t),f2(t)的Z变换分别为F(z),F1(z),F2(z),则有$$\mathbf{Z}[af(t)]=aF(z)$$ $$ \mathbf{Z}[a_1f_1(t)+a_2f_2(t)]=a_1F_1(z)+a_2F_2(z)$$滞后定理设连续时间函数在t<0时,f(t)=0,且f(t)的Z变换为F(z),则有$$\mathbf{Z}[f(t-kT)]=z^{-k}F(z)$$应⽤Z变换求解差分⽅程的⼀个例⼦:已知系统的差分⽅程表达式为$y(n)-0.9y(n-1)=0.05u(n)$,若边界条件$y(-1)=1$,求系统的完全响应。
解:⽅程两端取z变换$$Y(z)-0.9[z^{-1}Y(z)+y(-1)]=0.05\frac{z}{z-1}\\Y(z)=\frac{0.05z^2}{(z-1)(z-0.9)}+\frac{0.9y(-1)z}{z-0.9}$$可得$$\frac{Y(z)}{z}=\frac{A_1z}{z-1}+\frac{A_2z}{z-0.9}$$其中A1=0.5,A2=0.45,于是$y(n)=0.5+0.45 \times(0.9)^n \quad(n\geq0)$IIR数字滤波器的差分⽅程和系统函数IIR数字滤波器是⼀类递归型的线性时不变因果系统,其差分⽅程可以写为:$$y(n)=\sum_{i=0}^{M}a_ix(n-i)+\sum_{i=1}^{N}b_iy(n-i)$$进⾏Z变换,可得:$$Y(z)=\sum_{i=0}^{M}a_iz^{-i}X(z)+\sum_{i=1}^{N}b_iz^{-i}Y(z)$$于是得到IIR数字滤波器的系统函数:$$H(z)=\frac{Y(z)}{X(z)}=\frac{\sum_{i=0}^{M}a_iz^{-i}}{1-\sum_{i=1}^{N}b_iz^{-i}}=a_0\frac{\prod_{i=1}^{M}(1-c_iz^{-1})}{\prod_{i=1}^{N}(1-d_iz^{-1})}$$其中ci为零点⽽di为极点。
快速中值滤波 c代码
快速中值滤波 c代码快速中值滤波是一种非线性信号处理技术,通常用于消除图像或信号中的噪声。
以下是一个简单的快速中值滤波器的C代码实现。
这个实现使用了简单的排序算法,因此对于大数据集可能不是最优的,但对于小到中等大小的数据集,它的性能应该是可以接受的。
c#include <stdio.h>#include <stdlib.h>// 函数声明void findMedian(int arr[], int n, int *median);// 函数定义void findMedian(int arr[], int n, int *median) {// 冒泡排序,对于小的数据集可以直接使用简单的排序算法for(int i = 0; i < n; i++) {for(int j = 0; j < n - i - 1; j++) {if(arr[j] > arr[j+1]) {int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}*median = arr[n/2]; // 计算中值}// 主函数int main() {int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; // 输入数组int n = sizeof(arr) / sizeof(arr[0]); // 数组长度int median; // 中值findMedian(arr, n, &median); // 找到中值printf("The median of the array is: %d\n", median); // 输出中值return 0;}以上代码实现了一个简单版本的快速中值滤波器。
请注意,在实际使用中,可能需要根据应用的具体需求对代码进行相应的修改和优化。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C、缺点: 灵敏度低
对偶然出现的脉冲性干扰的抑制作用较差 不易消除由于脉冲干扰所引起的采样值偏差 不适用于脉冲干扰比较严重的场合 比较浪费 RAM
#define N 12 char value_buf[N]; char i=0; char filter() {
5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
A、方法: 相当于“中位值滤波法”+“算术平均滤波法” 连续采样 N 个数据,去掉一个最大值和一个最小值 然后计算 N-2 个数据的算术平均值 N 值的选取:3~14
B、优点: 融合了两种滤波法的优点 对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差
10、限幅消抖滤波法
略 参考子程序 1、9 A、方法: 相当于“限幅滤波法”+“消抖滤波法” 先限幅,后消抖 B、优点: 继承了“限幅”和“消抖”的优点 改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统 C、缺点: 对于快速变化的参数不宜
}
2、中位值滤波法
/* N 值可根据实际情况调整 排序采用冒泡法*/
A、方法: 连续采样 N 次(N 取奇数) 把 N 次采样值按大小排列 取中间值为本次有效值
B、优点: 能有效克服因偶然因素引起的波动干扰 对温度、液位的变化缓慢的被测参数有良好的滤波效果
C、缺点: 对流量、速度等快速变化的参数不宜
出) 如果计数器溢出,则将本次值替换当前有效值,并清计数器
B、优点: 对于变化缓慢的被测参数有较好的滤波效果, 可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动
C、缺点: 对于快速变化的参数不宜 如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当
作有效值导 入系统 #define N 12 char filter() {
6、限幅平均滤波法
略 参考子程序 1、3 A、方法: 相当于“限幅滤波法”+“递推平均滤波法” 每次采样到的新数据先进行限幅处理, 再送入队列进行递推平均滤波处理 B、优点: 融合了两种滤波法的优点 对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差 C、缺点: 比较浪费 RAM
7、一阶滞后滤波法
本次值 B、优点: 能有效克服因偶然因素引起的脉冲干扰 C、缺点 无法抑制那种周期性的干扰 平滑度差
/* A 值可根据实际情况调整 value 为有效值,new_value 为当前采样值 滤波程序返回有效的实际值 */
#define A 10 char value; char filter() {
char new_value; new_value = get_ad(); if ( ( new_value - value > A ) || ( value - new_value > A ) return value; return new_value;
value_buf[count] = get_ad(); delay(); } for (count=0,count<N;count++) sum += value_buf[count]*coe[count]; return (char)(sum/sum_coe); }
9、消抖滤波法
A、方法: 设置一个滤波计数器 将每次采样值与当前有效值比较: 如果采样值=当前有效值,则计数器清零 如果采样值<>当前有效值,则计数器+1,并判断计数器是否>=上限 N(溢
/* 为加快程序处理速度假定基数为 100,a=0~100 */ A、方法: 取 a=0~1 本次滤波结果=(1-a)*本次采样值+a*上次滤波结果 B、优点: 对周期性干扰具有良好的抑制作用 适用于波动频率较高的场合 C、缺点: 相位滞后,灵敏度低 滞后程度取决于 a 值大小 不能消除滤波频率高于采样频率的 1/2 的干扰信号
if ( value_buf>value_buf[i+1] ) {
temp = value_buf; value_buf = value_buf[i+1]; value_buf[i+1] = temp; } } } for(count=1;count<N-1;count++) sum += value[count]; return (char)(sum/(N-2)); }
char Temp_Value;
Temp_Value = get_ad(); sum += value_buf[i] - Temp_Value; value_buf[i++] = Temp_Value; if ( i == N ) i = 0; return (char)(sum/N); }//注意 value_buf 全部初始化为第一次采集的值!!
char count=0; char new_value; new_value = get_ad(); while (value !=new_value); {
count++; if (count>=N) return new_value; delay(); new_value = get_ad(); } return value; }
if ( value_buf>value_buf[i+1] ) {
temp = value_buf; value_buf = value_buf[i+1]; value_buf[i+1] = temp; } } } return value_buf[(N-1)/2]; }
3、算术平均滤波法
A、方法: 连续取 N 个采样值进行算术平均运算 N 值较大时:信号平滑度较高,但灵敏度较低 N 值较小时:信号平滑度较低,但灵敏度较高 N 值的选取:一般流量,N=12;压力:N=4
B、优点: 适用于对一般具有随机干扰的信号进行滤波 这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动
C、缺点: 对于测量速度较慢或要求数据计算速度较快的实时控制不适用 比较浪费 RAM
#define N 12 char filter() {
int sum = 0; for ( count=0;count<N;count++) {
sum + = get_ad(); delay(); } return (char)(sum/N); }
4、递推平均滤波法(又称滑动平均滤波法)
A、方法: 把连续取 N 个采样值看成一个队列 队列的长度固定为 N 每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先
出原则) 把队列中的 N 个数据进行算术平均运算,就可获得新的滤波结果 N 值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4
#define N 11 char filter() {
char value_buf[N]; char count,i,j,temp; for ( count=0;count<N;count++) {
value_buf[count] = get_ad(); delay(); } for (j=0;j<N-1;j++) { for (i=0;i<N-j;i++) {
#define a 50 char value; char filter() {
char new_value; new_value = get_ad(); return (100-a)*value + a*new_value; }
8、加权递推平均滤波法
/* coe 数组为加权系数表,存在程序存储区。*/ A、方法: 是对递推平均滤波法的改进,即不同时刻的数据加以不同的权 通常是,越接近现时刻的数据,权取得越大。 给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低 B、优点: 适用于有较大纯滞后时间常数的对象 和采样周期较短的系统 C、缺点: 对于纯滞后时间常数较小,采样周期较长,变化缓慢的信号 不能迅速反应系统当前所受干扰的严重程度,滤波效果差
C、缺点: 测量速度较慢,和算术平均滤波法一样 比较浪费 RAM
#define N 12 char filter() {
char count,i,j; char value_buf[N]; int sum=0; for (count=0;count<N;count++) {
value_buf[count] = get_ad(); delay(); } for (j=0;j<N-1;j++) { for (i=0;i<N-j;i++) {
简单数字滤波实现算法(C 语言源程序)
假定从 8 位 AD 中读取数据(如果是更高位的 AD 可定义数据类型为 int),子程序 为 get_ad(); 单片机利用软件抗干扰的几种滤波方法:
1、限幅滤波法(又称程序判断滤波法)
A、方法: 根据经验判断,确定两次采样允许的最大偏差值(设为 A) 每次检测到新值时判断: 如果本次值与上次值之差<=A,则本次值有效 如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替
char count; int sum=0; value_buf[i++] = get_ad(); if ( i == N ) i = 0; for ( count=0;count<N,count++) sum = value_buf[count]; return (char)(sum/N); }
楼主的滑动滤波法不对,应该是: #define N 12 char value_buf[N]; char i=0; int sum=0; char filter() {