《匠人手记》里的10种软件滤波
《匠人手記》里的10種軟件濾波,感覺不錯,在此作為自己的一個筆記,也跟大家分享。感謝“程序匠人”的奉獻。
一、限幅濾波法
1、
先根據經驗判斷,確定兩次采樣允許的最大偏差值,設為A。
每次檢測到新采樣值時進行判斷:
(1)如果本次新采樣值與上一次濾波效果之差<=A,則本次采樣值有效,令本次濾波結果=新采樣值;
(2)如果本次采樣值與上次濾波結果之差>A,則本次采樣值無效,放棄本次采樣值,本次濾波結果=上次濾波結果。
2、例程
#define?A?10
uchar?Value;????//上次采樣有效值
uchar?AmplitudeLimiterFilter()
{
????uchar?NewValue,ReturnValue;
????NewValue=GetAD();??????????//本次采樣值
? ?if(|NewValue-Value| > A){
? ? ? ? ? return?Value;
? ?}else{
? ? ? ? ??return?NewValue;
? ?}
}
二、中位值濾波法
1、連續采樣N次值,把采樣值按大小排列,取中間值為本次有效值。
2、例程
#define?N?9
unchar?MiddleValueFilter()
{
unchar?i,j,k;
uchar?temp;
uchar?ArrDataBuffer[N];
for(i=0;i<N;i++)??//一次采集N個數據放入數組中
{
??ArrDataBuffer[i]=GetAD();
??Delay();
}
for(j=0;j<N-1;j++)//采樣值由小到大排列
{
??for(k=0;k<N-j-1;k++)
??{
????if(ArrDataBuffer[k]>ArrDataBuffer[k+1])
????{
??????temp=ArrDataBuffer[k];
??????ArrDataBuffer[k]=ArrDataBuffer[k+1];
??????ArrDataBuffer[k+1]=temp;
????}
??}
}
return(ArrDataBuffer[(N-1)/2]);//取中間值
}
?
三、算術平均濾波法
1、連續取N個值進行算術平均運算。
N較大時,信號平滑度較高,但靈敏度較低;N較小,信號平滑度低,但靈敏度較高。
2、例程
#define?N?12
uchar?ArithmeticalAverageValueFilter()
{
uchar?i;
uchar?Value;
uchar?sum;
sum=0;
for(i=0;i<N;i++)
{
sum+=GetAD();
Delay();
}
Value=sum/N;
return(Value);
}
四、遞推平均濾波法
1、把連續N個采集值看成一個隊列,每次采集到的新數據放入隊尾,并扔掉原來隊首的數據。把隊列中的N個數據進行平均計算,即可獲得新的濾波結果。
2、例程
#define?N?12
uchar?Data[];
uchar?Gilde(Data[])
{
?ucahr?i,Value,sum;
sum=0;
Data[N]=GetAD();
for(i=0;i<N;i++)
{
??Data[i]=Data[i+1];//所有數據左移,低位仍掉
??sum+=Data[i];
}
Value=sum/N;
return(Value);
}
?
五、中位值平均濾波法
1、中位值平均濾波法又稱脈沖干擾平均濾波法,相當于“中位值濾波法”+“算術平均濾波法”。
連續采集N個數據,去掉一個最大和最小值,然后計算N-2個數的平均值。
2、例程
#define?N?12
uchar?Middle()
{
ucahr?i,j,k,l;
uchar?temp;
uchar?ArrDataBuffer[N];
uchar?sum,Value;
for(i=0;i<N;i++)//一次采集N個數據,存入數組
{
???ArrDataBuffer[i]=GetAD();
???Delay();
}
for(j=0;j<N-1;j++)//采樣值由小到大排列
{
??for(k=0;k<N-j-1;k++)
??{
????if(ArrDataBuffer[k]>ArrDataBuffer[k+1])
????{
??????temp=ArrDataBuffer[k];
??????ArrDataBuffer[k]=ArrDataBuffer[k+1];
??????ArrDataBuffer[k+1]=temp;
????}
??}
}
for(l=0;l<N-1;l++)
{
??sum=ArrDataBuffer[l];
}
Value=Sum/(N-2);
return(Value);
}
?
六、遞推中位值平均濾波法
1、相當于“中位值濾波法”+“遞推平均濾波法”。這種方法把連續N個值看成一個隊列,每次采集到一個新數據放入隊尾,并扔掉原來隊首的值。?把隊列中的N個數據先去掉一個最大值和最小值,然后計算N-2個數據的平均值。
2、例程
char?Filter()
{
char?max.min;
int?sum;
char?i;
QUEUE[0]=NewData;
max=QUEUE[0];
min=QUEUE[0];
sum=QUEUE[0];
for(i=n-1;i!=0;i--)
{
??if(QUEUE[i]>max)?max=QUEUE[i];
??else?if(QUEUE[i]<min)?min=QUEUE[i];
??sum+=QUEUE[i];
??QUEUE[i]=QUEUE[i-1];?
}
??i=n-2;
?sum=sum-max-min+i/2;//加入(n-2)/2目的為了四舍五入
?sum=sum/i;
?return(sum);
}
?
七、限幅平均濾波法
1、相當于“限幅濾波法”+“遞推平均濾波法”。每次采樣先進行限幅處理,再進行隊列平均濾波處理。
2、例程
#define?A?10
#define?N?12
uchar?Data[N];
uchar?Limit()
{
??ucahr?i,Value,sum;
??Data[N]=GetAD();
??if(((Data[N]-Data[N-1])>A)||((Data[N-1]-Data[N])>A)))
???Data[N]=Data[N-1];?
???else?Data[N]=NewValue;
for(i=0;i<N;i++)
{
??Data[i]=Data[i+1];
??sum+=Data[i];
}
Value=sum/N;
return(Value);
}
?
八、一階滯后濾波法
1、本次結果濾波結果=a*本次采樣值+(1-a)*上次結果。
a代表濾波系數,a=0--1。
2、例程
#define?a?128
uchar?Value;
ucahr?OneFactorialFiler()
{
uchar?NewValue;
uchar?ReturnValue;
NewValue=GetAD();
ReturnValue=(255-a)*NewValue+a*Value;
ReturnValue/=255;
return(ReturnValue);
}
?
九、加權遞推平均濾波法
1、加權遞推平均濾波法是對遞推平均濾波法的改進,即不同時刻的數據加以不同的權。通常是越接近現時刻的數據,權取得越大。給予新采樣值的權系數越大,則靈敏度越高,但信號的平滑度越低。
2、例程
#define?N?10
#define?CoeSum?55
const?Coefficient[N]={1,2,3,4,5,6,7,8,9,10};
uchar?Data[N];
uchar?AAGAFilter()
{
?uchar?i,Value,sum;
?sum=0;
?Data[N]=GetAD();
?for(i=0;i<N;i++)
{
??Data[i]=Data[i+1];
??sum+=Data[i]*Coefficient[i];
}
Value=sum/CoeSum;
return(Value);
}
?
十、消抖濾波法
1、將每次采樣值與當前有效值比較,如果采樣值=當前有效值,則計數器清零,否則計數器加1。然后,判斷計數器是否>=上限N(溢出)。如果溢出,將本次值替換當前有效值,并清計數器。
2、例程
#define?N?20
uchar?count;
uchar?Value;
uchar?Avoid()
{
uchar?NewValue;
if(NewValue==Value)?count=0;
else
{
??count++;
??if(count>N)
??{
?????count=0;
?????Value=NewValue;
??}
}
return(Value);
}
?
?
總結
以上是生活随笔為你收集整理的《匠人手记》里的10种软件滤波的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ctf攻防渗透-加密-栅栏密码
- 下一篇: 日历代码(微信小程序)