我是靠谱客的博主 香蕉蜡烛,这篇文章主要介绍几种滑动平均滤波器的c++模板实现,现在分享给大家,希望可以做个参考。

文章目录

    • 说明
    • 滑动平均模板类
    • 使用与测试
      • 测试代码
      • google test测试结果

说明

本文中几种滑动平均的公式及说明可点击此处

滑动平均模板类

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#pragma once #include <queue> #include <list> namespace ns_filter { template <typename T, int M> class SMA { public: static_assert(M>1, "SMA require window width>1"); SMA() :_last_flt_value{ 0 } {}; ~SMA() {}; T apply(const T& raw) { _queue.push(raw); if (_queue.size() > M) { _last_flt_value += ((raw - _queue.front()) / M); _queue.pop(); } else { _last_flt_value = (_last_flt_value * (_queue.size() - 1) + raw) / _queue.size(); } return _last_flt_value; } private: std::queue<T> _queue; T _last_flt_value{0}; }; template <typename T, int M> class WMA { public: static_assert(M > 1, "WMA require window width>1"); WMA() {}; ~WMA() {}; T apply(const T& raw) { _ls.push_back(raw); if (_ls.size() > M) { _ls.pop_front(); } int sz = _ls.size(); int den = sz * (sz + 1) / 2; int w = 1; T sum{0}; for (auto v : _ls) { sum += (w * v); ++w; } return sum/den; } private: std::list<T> _ls; }; template <typename T> class EMA { public: EMA() = delete; EMA(double alpha) { _alpha = alpha; }; ~EMA() {}; T apply(const T& raw) { if (_initlized == false) { _last_y = raw; _initlized = true; } else { _last_y = _alpha * _last_y + (1 - _alpha) * raw; } return _last_y; } private: T _last_y; double _alpha = 0.1f; bool _initlized = false; }; }

使用与测试

测试代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include "gtest/gtest.h" #include "lowPassFilter.h" TEST(Testfilter, TestEMA) { ns_filter::EMA<double> flt2(0.1); double r = flt2.apply(1); EXPECT_TRUE(abs(r - 1) < 1e-5); r = flt2.apply(2); EXPECT_TRUE(abs(r - 1.9) < 1e-5); r = flt2.apply(4); EXPECT_TRUE(abs(r - 0.19-3.6) < 1e-5); r = flt2.apply(3); EXPECT_TRUE(abs(r - 0.019-0.36-2.7) < 1e-5); } TEST(Testfilter, TestSMA) { ns_filter::SMA<double> flt(3); double r = flt.apply(1); EXPECT_TRUE(abs(r - 1) < 1e-5); r = flt.apply(2); EXPECT_TRUE(abs(r - 1.5) < 1e-5); r = flt.apply(4); EXPECT_TRUE(abs(r - 7.0 / 3) < 1e-5); r = flt.apply(3); EXPECT_TRUE(abs(r - 3) < 1e-5); } TEST(Testfilter, TestWMA) { ns_filter::WMA<double> flt2(3); double r = flt2.apply(1); EXPECT_TRUE(abs(r - 1) < 1e-5); r = flt2.apply(2); EXPECT_TRUE(abs(r - 5.0 / 3) < 1e-5); r = flt2.apply(4); EXPECT_TRUE(abs(r - (1 + 4 + 12) * 1.0 / (1 + 2 + 3)) < 1e-5); r = flt2.apply(3); EXPECT_TRUE(abs(r - (2 + 8 + 9) * 1.0 / (1 + 2 + 3)) < 1e-5); }

google test测试结果

visual studio 和 cygwin下测试结果如下,
在这里插入图片描述
在这里插入图片描述

最后

以上就是香蕉蜡烛最近收集整理的关于几种滑动平均滤波器的c++模板实现的全部内容,更多相关几种滑动平均滤波器内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(82)

评论列表共有 0 条评论

立即
投稿
返回
顶部