学习永无止境
- C语言进阶第一弹:滤波算法
- 前言
- 一、学前必看
- 二、正文
- 1.加权平均递推法
- 2.递推平均滤波法
- 3:一阶低通滤波
- 4:其他滤波算法
- 总结
前言
大家好,这里是亿只萌新,一个从机械行业进阶码农的秃顶少年。最近也是突然想起了刚学C语言那会儿被十大滤波函数支配的恐惧。如今,小新想着再次拾起这个当初的恐惧,克服他,然后分享最简单的理解给可爱的网友们
温馨提示:以下内容为作者原创,全部免费,支持转载,但不得作商业用途
一、学前必看今天下了一场大雪,窗外一片白茫茫,颇有种世外高人的感觉,小新也是刚刚看完了所谓的十大滤波算法,看完之后,我心理有很多的想法,所谓的网上的十大算法,不过是提供了一个编程思路,但是这些程序并不能直接写入我们自己的程序中使用。
相对来说,它们只是一个概念模板,所以,这也是我们看了那么多算法,却始终无法应用到自己程序的原因。
这次,小新将用自己的理解,将这些算法编写成可以直接套用的模板。
温馨提示:以下教程小新仅仅挑选了小新认为有难度的几个算法。学会这几个算法,原则是已经掌握了其他算法 二、正文 1.加权平均递推法
假设我们有一个数组,该数组含有十个数据。现在我们需要处理这十个数据。为了达到某种滤波的效果,我们给每一个数据乘上一个权重(唯一的数字),十个数据就有十个权,将这个十个权(十个数字)依次相加,得到一个总的权,然后将十个数据和自己相乘之后的新的加权数据也依次相加,得到一个加权后的数据总和,数据总和和总权重相除,我们就得到一个全新的加权平均数。以后每十个数据进行依次加权。
提示:经过测试,加权平均的数据偏大一点,所以适合过滤那些跳动幅度较小的比较平滑的数据。
//加权平均递推法:同样以10个数组为例,这种方法滤得数值偏大
int add_data[10]={1,2,3,4,5,6,7,8,9,10};//权的存放,不变
int my_add_data[10]={0},flag;//数据存放数组,数据溢出标志
double add_average(int a)//使用程序时,只需要将一个数据传入,本程序自动组建数组。
{
int sum=0,i=0,add_data_total=0;
my_add_data[flag]=a;
flag++;
if(flag<10)return -1;//如果数组没有够10个的话,不允许下面的操作
flag=0;//初始化标志位
for(i=0;i<10;i++)
{
add_data_total+=(i+1);
sum+=my_add_data[i]*add_data[i];
}
return (double)sum/add_data_total;//返回平均值
}
//函数使用示范
int main()
{
int a=0;
double x=0.00;
while(1)
{
printf("请输入一个数字:");
scanf("%d",&a);//每次只需要传入你要传的一个数据,不需要组成十个数据传入
if((x=add_average(a))>0)printf("%.2fn",x);//如果x=-1,说明十个数据还没有溢出,程序不作处理。
if(a==90)
{
return 1;
}
}
return 1;
}
2.递推平均滤波法
原理:将数据传入十个大小的数组之中,通过冒泡排序从小到大排序,取中间八个数据计算其平均值,处理完毕后剔除原数组(没有进行排序的数组)的第一个位置的数据,新数据添加至数组末尾,看着就像一个管道,从一边进去,另一边出来。
同原理算法:中位值平均滤波法,去掉管道那个部分,每次重新组十个数据,学会使用下面这个算法,中位值j将对您来说小菜一碟。
//除去最大值和最小值,计算平均
//然后数组整体向前移一位
//江湖人称:递推平均法滤波
//同时:中位值平均滤波法将最后一部存储去掉就可以了,每次都重新写10个数据。
int mydata[10]={0};
double eliminate_max(int a)
{
int i=0,j=0,data[10];
mydata[9]=a;
for(i=0;i<10;i++)
{
data[i]=mydata[i];
}
//按从小到大排序,冒泡排序
for(i=0;i<10;i++)
{
for(j=i+1;j<10;j++)
{
if(data[i]>data[j])
{
int temp=data[i];
data[i]=data[j];
data[j]=temp;
}
}
}
//从次小值域开始计算
for(i=8;i>0;i--)
{
data[0]+=data[i];
}
//数组前进一个位置
for(i=0;i<9;i++)
{
mydata[i]=mydata[i+1];
}
return (double)data[0]/8;
}
//使用方法
int main()
{
int a=0;
while(1)
{
printf("请输入一个数字:");
scanf("%d",&a);
printf("%.2fn",eliminate_max(a));//将数据扔进括号就行,是不是简单多了。
if(a==90)
{
return 1;
}
}
}
以上算法包含了平均值滤波
3:一阶低通滤波这个算法我们只需要知道他的数学原理就行了,相信没人不会写程序吧!
低通滤波:f=A*X+(1-A)*Y:就是这个公式,照着抄就完事了。
X:当前的数据,Y为上一次的数据,在程序中只需要定义一个外部变量记录下就OK了。
A为滤波系数,根据你爱好设置A(0~1)之间。
之所以把这个滤波单独放出来说并不是因为他的程序很难理解,而是小新觉得网上的例子写的并不清楚,不适合萌新去学习,所以单独写了出来。
剩下的算法其实在加权平均递推中都能找到自己的影子,下面我简单阐述下其他几种滤波的原理。
1:消抖滤波法:设置有效值后和传入数据做对比,目的是得到一条平滑的直线。简而言之,就是让你传入的数据始终在某个设定值之间晃动。
2:算数平均滤波:直接加起来求平均,可以每十个一组。
3:中位值滤波法:一个数组,只取最中间位置的一个值,然后清空数组。
总结
以上就是今天要讲的内容了,如果有看不懂的,欢迎私信小新哦。
小懒虫们如果有需要源码的,可以关注小新或者加群。
Q群:928357277



