十一种通用滤波算法(转载)

十一种通用滤波算法

1、限幅滤波法(又称程序判断滤波法)
A、方法:
   根据经验判断,确定两次采样允许的最大偏差值(设为A)
   每次检测到新值时判断:
   如果本次值与上次值之差<=A,则本次值有效
   如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值
B、优点:
   能有效克服因偶然因素引起的脉冲干扰
C、缺点
   无法抑制那种周期性的干扰
   平滑度差


2、中位值滤波法
A、方法:
   连续采样N次(N取奇数)
   把N次采样值按大小排列
   取中间值为本次有效值
B、优点:
   能有效克服因偶然因素引起的波动干扰
   对温度、液位的变化缓慢的被测参数有良好的滤波效果
C、缺点:
   对流量、速度等快速变化的参数不宜


3、算术平均滤波法
A、方法:
   连续取N个采样值进行算术平均运算
   N值较大时:信号平滑度较高,但灵敏度较低
   N值较小时:信号平滑度较低,但灵敏度较高
   N值的选取:一般流量,N=12;压力:N=4
B、优点:
   适用于对一般具有随机干扰的信号进行滤波
   这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动
C、缺点:
   对于测量速度较慢或要求数据计算速度较快的实时控制不适用
   比较浪费RAM
   
4、递推平均滤波法(又称滑动平均滤波法)
A、方法:
   把连续取N个采样值看成一个队列
   队列的长度固定为N
   每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则)
   把队列中的N个数据进行算术平均运算,就可获得新的滤波结果
   N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4
B、优点:
   对周期性干扰有良好的抑制作用,平滑度高
   适用于高频振荡的系统 
C、缺点:
   灵敏度低
   对偶然出现的脉冲性干扰的抑制作用较差
   不易消除由于脉冲干扰所引起的采样值偏差
   不适用于脉冲干扰比较严重的场合
   比较浪费RAM
   
5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
A、方法:
   相当于“中位值滤波法”+“算术平均滤波法”
   连续采样N个数据,去掉一个最大值和一个最小值
   然后计算N-2个数据的算术平均值
   N值的选取:3~14
B、优点:
   融合了两种滤波法的优点
   对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差
C、缺点:
   测量速度较慢,和算术平均滤波法一样
   比较浪费RAM




6、限幅平均滤波法
A、方法:
   相当于“限幅滤波法”+“递推平均滤波法”
   每次采样到的新数据先进行限幅处理,
   再送入队列进行递推平均滤波处理
B、优点:
   融合了两种滤波法的优点
   对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差
C、缺点:
   比较浪费RAM


7、一阶滞后滤波法
A、方法:
   取a=0~1
   本次滤波结果=(1-a)*本次采样值+a*上次滤波结果
B、优点:
   对周期性干扰具有良好的抑制作用
   适用于波动频率较高的场合
C、缺点:
   相位滞后,灵敏度低
   滞后程度取决于a值大小
   不能消除滤波频率高于采样频率的1/2的干扰信号
   
8、加权递推平均滤波法
A、方法:
   是对递推平均滤波法的改进,即不同时刻的数据加以不同的权
   通常是,越接近现时刻的数据,权取得越大。
   给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低
B、优点:
   适用于有较大纯滞后时间常数的对象
   和采样周期较短的系统
C、缺点:
   对于纯滞后时间常数较小,采样周期较长,变化缓慢的信号
   不能迅速反应系统当前所受干扰的严重程度,滤波效果差


9、消抖滤波法
A、方法:
   设置一个滤波计数器
   将每次采样值与当前有效值比较:
   如果采样值=当前有效值,则计数器清零
   如果采样值<>当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出)
      如果计数器溢出,则将本次值替换当前有效值,并清计数器
B、优点:
   对于变化缓慢的被测参数有较好的滤波效果,
   可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动
C、缺点:
   对于快速变化的参数不宜
   如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导入系统


10、限幅消抖滤波法
A、方法:
   相当于“限幅滤波法”+“消抖滤波法”
   先限幅,后消抖
B、优点:
   继承了“限幅”和“消抖”的优点
   改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统
C、缺点:
   对于快速变化的参数不宜




第11种方法:IIR 数字滤波器 


A. 方法:
确定信号带宽, 滤之。
Y(n) = a1*Y(n-1) + a2*Y(n-2) + … + ak*Y(n-k) + b0*X(n) + b1*X(n-1) + b2*X(n-2) + … + bk*X(n-k)


B. 优点:高通,低通,带通,带阻任意。设计简单(用matlab)
C. 缺点:运算量大。



//——————————————————————— 


软件滤波的C程序样例


10种软件滤波方法的示例程序


假定从8位AD中读取数据(如果是更高位的AD可定义数据类型为int),子程序为get_ad();

 

1、限副滤波

 

 
  1. /* A值可根据实际情况调整

  2. value为有效值,new_value为当前采样值

  3. 滤波程序返回有效的实际值 */

  4. #define A 10

  5.  
  6. char value;

  7.  
  8. char filter() {

  9. char new_value;

  10. new_value = get_ad();

  11. if ( ( new_value - value > A ) || ( value - new_value > A )

  12. return value;

  13. return new_value;

  14.  
  15. }

 


2、中位值滤波法

 

 
  1. /* N值可根据实际情况调整

  2. 排序采用冒泡法*/

  3. #define N 11

  4.  
  5. char filter() {

  6. char value_buf[N];

  7. char count, i, j, temp;

  8. for (count = 0; count < N; count++) {

  9. value_buf[count] = get_ad();

  10. delay();

  11. }

  12. for (j = 0; j < N - 1; j++) {

  13. for (i = 0; i < N - j; i++) {

  14. if (value_buf > value_buf[i + 1]) {

  15. temp = value_buf;

  16. value_buf = value_buf[i + 1];

  17. value_buf[i + 1] = temp;

  18. }

  19. }

  20. }

  21. return value_buf[(N - 1) / 2];

  22. }


 

3、算术平均滤波法

 

 
  1. /*

  2. */

  3.  
  4. #define N 12

  5.  
  6. char filter() {

  7. int sum = 0;

  8. for (count = 0; count < N; count++) {

  9. sum + = get_ad();

  10. delay();

  11. }

  12. return (char) (sum / N);

  13. }


 

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

 

 
  1. /*

  2. */

  3. #define N 12

  4.  
  5. char value_buf[N];

  6. char i = 0;

  7.  
  8. char filter() {

  9. char count;

  10. int sum = 0;

  11. value_buf[i++] = get_ad();

  12. if (i == N)

  13. i = 0;

  14. for ( count=0;count<N,count++)

  15. sum = value_buf[count];

  16. return (char) (sum / N);

  17. }


 

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

 

 
  1. /*

  2. */

  3. #define N 12

  4.  
  5. char filter() {

  6. char count, i, j;

  7. char value_buf[N];

  8. int sum = 0;

  9. for (count = 0; count < N; count++) {

  10. value_buf[count] = get_ad();

  11. delay();

  12. }

  13. for (j = 0; j < N - 1; j++) {

  14. for (i = 0; i < N - j; i++) {

  15. if (value_buf > value_buf[i + 1]) {

  16. temp = value_buf;

  17. value_buf = value_buf[i + 1];

  18. value_buf[i + 1] = temp;

  19. }

  20. }

  21. }

  22. for (count = 1; count < N - 1; count++)

  23. sum += value[count];

  24. return (char) (sum / (N - 2));

  25. }


 

6、限幅平均滤波法

 
  1. /*

  2. * 略 参考子程序1、3

  3. */


 

7、一阶滞后滤波法

 

 
  1. /* 为加快程序处理速度假定基数为100,a=0~100 */

  2.  
  3. #define a 50

  4.  
  5. char value;

  6.  
  7. char filter() {

  8. char new_value;

  9. new_value = get_ad();

  10. return (100 - a) * value + a * new_value;

  11. }


 

8、加权递推平均滤波法

 

 
  1. /* coe数组为加权系数表,存在程序存储区。*/

  2.  
  3. #define N 12

  4.  
  5. char code coe[N] = {1,2,3,4,5,6,7,8,9,10,11,12};

  6. char code sum_coe = 1+2+3+4+5+6+7+8+9+10+11+12;

  7.  
  8. char filter() {

  9. char count;

  10. char value_buf[N];

  11. int sum = 0;

  12. for (count=0,count<N;count++)

  13. {

  14. value_buf[count] = get_ad();

  15. delay();

  16. }

  17. for (count=0,count<N;count++)

  18. sum += value_buf[count]*coe[count];

  19. return (char) (sum / sum_coe);

  20. }


 

9、消抖滤波法

 

 
  1. #define N 12

  2.  
  3. char filter() {

  4. char count = 0;

  5. char new_value;

  6. new_value = get_ad();

  7. while (value != new_value)

  8. ;

  9. {

  10. count++;

  11. if (count >= N)

  12. return new_value;

  13. delay();

  14. new_value = get_ad();

  15. }

  16. return value;

  17. }


 

10、限幅消抖滤波法

 

 
  1. /*

  2. * 略 参考子程序1、9

  3. */


 

11、IIR滤波例子

 

 
  1. int BandpassFilter4(int InputAD4) {

  2. int ReturnValue;

  3. int ii;

  4. RESLO = 0;

  5. RESHI = 0;

  6. MACS = *PdelIn;

  7. OP2 = 1068; //FilterCoeff4[4];

  8. MACS = *(PdelIn + 1);

  9. OP2 = 8; //FilterCoeff4[3];

  10. MACS = *(PdelIn + 2);

  11. OP2 = -2001; //FilterCoeff4[2];

  12. MACS = *(PdelIn + 3);

  13. OP2 = 8; //FilterCoeff4[1];

  14. MACS = InputAD4;

  15. OP2 = 1068; //FilterCoeff4[0];

  16. MACS = *PdelOu;

  17. OP2 = -7190; //FilterCoeff4[8];

  18. MACS = *(PdelOu + 1);

  19. OP2 = -1973; //FilterCoeff4[7];

  20. MACS = *(PdelOu + 2);

  21. OP2 = -19578; //FilterCoeff4[6];

  22. MACS = *(PdelOu + 3);

  23. OP2 = -3047; //FilterCoeff4[5];

  24. *p = RESLO;

  25. *(p + 1) = RESHI;

  26. mytestmul <<= 2;

  27. ReturnValue = *(p + 1);

  28. for (ii = 0; ii < 3; ii++) {

  29. DelayInput[ii] = DelayInput[ii + 1];

  30. DelayOutput[ii] = DelayOutput[ii + 1];

  31. }

  32. DelayInput[3] = InputAD4;

  33. DelayOutput[3] = ReturnValue;

  34.  
  35. // if (ReturnValue<0)

  36. // {

  37. // ReturnValue=-ReturnValue;

  38. // }

  39. return ReturnValue;

  40. }


 

二.在图像处理中应用到的滤波算法实例:

 

 
  1. BOOL WINAPI MedianFilter(LPSTR lpDIBBits, LONG lWidth, LONG lHeight,

  2. int iFilterH, int iFilterW, int iFilterMX, int iFilterMY) {

  3.  
  4. // 指向源图像的指针

  5. unsigned char* lpSrc;

  6.  
  7. // 指向要复制区域的指针

  8. unsigned char* lpDst;

  9.  
  10. // 指向复制图像的指针

  11. LPSTR lpNewDIBBits;

  12. HLOCAL hNewDIBBits;

  13.  
  14. // 指向滤波器数组的指针

  15. unsigned char * aValue;

  16. HLOCAL hArray;

  17.  
  18. // 循环变量

  19. LONG i;

  20. LONG j;

  21. LONG k;

  22. LONG l;

  23.  
  24. // 图像每行的字节数

  25. LONG lLineBytes;

  26.  
  27. // 计算图像每行的字节数

  28. lLineBytes = WIDTHBYTES(lWidth * 8);

  29.  
  30. // 暂时分配内存,以保存新图像

  31. hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);

  32.  
  33. // 判断是否内存分配失败

  34. if (hNewDIBBits == NULL) {

  35. // 分配内存失败

  36. return FALSE;

  37. }

  38.  
  39. // 锁定内存

  40. lpNewDIBBits = (char *) LocalLock(hNewDIBBits);

  41.  
  42. // 初始化图像为原始图像

  43. memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight);

  44.  
  45. // 暂时分配内存,以保存滤波器数组

  46. hArray = LocalAlloc(LHND, iFilterH * iFilterW);

  47.  
  48. // 判断是否内存分配失败

  49. if (hArray == NULL) {

  50. // 释放内存

  51. LocalUnlock(hNewDIBBits);

  52. LocalFree(hNewDIBBits);

  53.  
  54. // 分配内存失败

  55. return FALSE;

  56. }

  57.  
  58. // 锁定内存

  59. aValue = (unsigned char *) LocalLock(hArray);

  60.  
  61. // 开始中值滤波

  62. // 行(除去边缘几行)

  63. for (i = iFilterMY; i < lHeight - iFilterH + iFilterMY + 1; i++) {

  64. // 列(除去边缘几列)

  65. for (j = iFilterMX; j < lWidth - iFilterW + iFilterMX + 1; j++) {

  66. // 指向新DIB第i行,第j个象素的指针

  67. lpDst = (unsigned char*) lpNewDIBBits

  68. + lLineBytes * (lHeight - 1 - i) + j;

  69.  
  70. // 读取滤波器数组

  71. for (k = 0; k < iFilterH; k++) {

  72. for (l = 0; l < iFilterW; l++) {

  73. // 指向DIB第i - iFilterMY + k行,第j - iFilterMX + l个象素的指针

  74. lpSrc = (unsigned char*) lpDIBBits

  75. + lLineBytes * (lHeight - 1 - i + iFilterMY - k) + j

  76. - iFilterMX + l;

  77.  
  78. // 保存象素值

  79. aValue[k * iFilterW + l] = *lpSrc;

  80. }

  81. }

  82.  
  83. // 获取中值

  84. *lpDst = GetMedianNum(aValue, iFilterH * iFilterW);

  85. }

  86. }

  87.  
  88. // 复制变换后的图像

  89. memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);

  90.  
  91. // 释放内存

  92. LocalUnlock(hNewDIBBits);

  93. LocalFree(hNewDIBBits);

  94. LocalUnlock(hArray);

  95. LocalFree(hArray);

  96.  
  97. // 返回

  98. return TRUE;

  99. }


 

三.RC滤波的一种实现:

 

 
  1. RcDigital(double & X, double & Y)

  2. {

  3. static int MidFlag;

  4. static double Yn_1,Xn_1;

  5. double MyGetX=0,MyGetY=0;

  6. double Alfa;

  7. Alfa=0.7;

  8. if(X==0||Y==0)

  9. {

  10. MidFlag=0;

  11. Xn_1=0;

  12. Yn_1=0;

  13. MyGetX=0;

  14. MyGetY=0;

  15. }

  16. if(X>0&&Y>0)

  17. {

  18. if(MidFlag==1)

  19. {

  20. MyGetY = (1 - Alfa) * Y + Alfa * Yn_1;

  21. MyGetX = (1 - Alfa) * X + Alfa * Xn_1;

  22. Xn_1 = MyGetX;

  23. Yn_1 = MyGetY;

  24. }

  25. else

  26. {

  27. MidFlag=1;

  28. MyGetX = X;

  29. MyGetY = Y;

  30. Xn_1 = X;

  31. Yn_1 = Y;

  32. }

  33. }

  34. X = MyGetX;

  35. Y = MyGetY;

  36. }

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值