C++实现三种滤波算法(过程详细)

目录

 

1 写在前面

2 数据导入(c++)

3 滤波处理

3.1 处理前准备

3.2 均值滤波

3.3 中值滤波

3.4 一阶高斯滤波

4 导出数据

5 滤波效果展示

5.1 原数据成像

5.2 均值滤波

5.3 中值滤波

5.4 一阶高斯滤波


1 写在前面

        由于本人并未了解过代码优化相关知识,因此本文代码仅是能够实现滤波算法的功能,可能效率会低一点,效果验证通过Python语言。代码根据相关滤波算法定义而写。

2 数据导入(c++)

数据为csv文件(三轴加速度),以“,”分隔每个数据。

251ba9acd7cb416aa30b7d664f78c2a5.png

写相关代码将数据导入并转换为浮点数(用一个二维数组保存,方便之后操作,三列)

ba81e0ccb04e4401823219d7a8865ab1.png

1c50bcfc66cb4a02952d4c288beaa059.png

3 滤波处理

3.1 处理前准备

63fc9ee2796449da8c19c7b214f43efe.png

        引入库文件,定义行数,列数,定义滤波滑动窗口,由于有三列数据,之后处理会一列列进行,DataNum用来创建滤波后数据的数组以及其他参数功能(其实直接用row也行)

051414b000a74270a0fdcc4373a66369.png dataR就是处理后的数据的数组(二维数组,三列)

46207e1b018c4dd7938aef692a76c2dd.png 经历三次循环,每次处理一列。 

3.2 均值滤波

均值滤波,简单来说就是将几个数据求平均的值作为结果值。

1b25c7313e6948fd910b7344151f63e4.png

定义一个计算均值的函数

9da724596a084c44a137c3dee9fc243d.png

        此为while循环里的内容,这个是之前写的代码,其实前三行没有必要,可以直接对原始的二维数组操作,本来想的是将三列数据分离开用一维数组操作。第二个循环内,定义滤波滑动窗口,每次计算滑动窗口的值。滑动窗口的理解,如果window为3的话,10个数据,第一次存储1-3个,第二次存储2-4个 。窗口在原始数组滑动。之后计算均值并保存在存储数据处理后结果的数组中。

3.3 中值滤波

中值滤波,顾名思义,就是计算滑动窗口中数据的中值。

10a03f4db3204e8782c58fe31b6c1fec.png

编写计算中值的函数,不要忘了之前的均值函数,滑动窗口内数据排序后可以简单得到中值。

24445f0a0b0b4f6d8ae3a2715bbe021b.png 

while循环内滤波的代码,与均值类似。

3.4 一阶高斯滤波

        高斯滤波,就相对麻烦了。它与均值有相似之处,他利用的是权重。可以这么理解,当你计算均值的时候,比如10个数,你会把它们相加并除以10,我们利用学习的知识,可以将那个求均值的分式分开,也就是每个数都除以10再相加,相当于每个数据的权重都是十分之一。权重越大,他在计算时对结果的影响就越大,占的比重越大。

        而我们要做的就是确定窗口内每个数据的权重,之后利用窗口内数据乘以权重之后相加,就得到我们想要的值,均值相当于每个数据的权重都是一样的,而高斯滤波是越靠近窗口的中心,其权重也就越大。而这个权重的确定依靠一阶标准正态分布(钟形曲线)。

cf34d833fda34eca8e035cf833eb7a49.png

42931a948fa34760a302cb0130545685.png

         相当于突出中心,对周围数据的处理,离中心越远,对整体数据影响越小。而权重的值的计算通过一维高斯函数的公式

 c8ae50e288344171b3a0e248c7a71b05.png

 定义σ的值,Gaussian用来存储窗口中每个数据的权重值,gaussian即一阶高斯函数。

69614e2402bb4105b09f7c0624a060d4.png

        我们现在要根据我们定义的窗口值,计算相应一阶高斯函数的结果值。我们定义window为5时,我们要确保窗口中心正好对应0(等于0的权重计算结果最大),这个时候在带入一阶函数前,x的值就应该分别是(-2,-1,0,1,2),这样就可以保证中间的值对应权重大。之后带入一阶高斯函数,得到的值保存在Gaussion内部。

650386949fd94c1cbbeb0dcbfba3121d.png

        我们将Guassion的值相加得GaussionSum,之后让Gaussian的每一个值都除以这个总值,就可以保证我们窗口内权重值的和为1。之后我们就可以算加权平均了。

 75b1f73374f446f5a9289a9fa8be915c.png

f3a5e4291a44409ea91116f708d0068f.png 

        我们定义Weight函数用来计算窗口内每一个值乘以权重(Gaussion中对应权重)之后相加得加权平均,而这个值正是我们想要的值。 

4 导出数据

c056cee7216743a49ea09cb7c842f4c8.png

处理完的数据就可以保存为csv文件了,方便之后利用python查看效果(注意csv文件格式)。 

5 滤波效果展示

cb87f557024a4ae782aac802d8872965.png

python生成图像的代码 

5.1 原数据成像

6013a204ede31b56f969d5fbaa368068.jpeg

5.2 均值滤波

window 3

5a949ff6dd644691a3ba659f5bc97855.png

 window 5

7707ff0280dc43d2a1039708093b41e7.png

window 11

 ece08a4e4fa140a2a079ba9672acdcaa.png

5.3 中值滤波

window 3

362b3f25cb1d450385b58c83b0a7369d.png

window 5

fcdbb685e32f4c5e9ca144e8c27ad77b.png 

window 11

4fb23ad7294c4278b20be61a7fb8bd7c.png

5.4 一阶高斯滤波

        经过一阶高斯滤波处理,原始数据平滑程度较小,这里就不展示效果了,分析原因,我们利用的一阶高斯滤波是越靠近中心权重越大,导致其与原始数据的差值较小。高斯滤波被用在图像处理更多,利用的是二阶高斯滤波,可以对图像噪点进行处理。

 

 

 

 

 

 

 

物联沃分享整理
物联沃-IOTWORD物联网 » C++实现三种滤波算法(过程详细)

发表评论