raj*_*jat 5 c++ algorithm signal-processing filter
我写了这段代码来平滑曲线.它在一个点旁边需要5个点并添加它们并对其求平均值.
/* Smoothing */
void smoothing(vector<Point2D> &a)
{
//How many neighbours to smooth
int NO_OF_NEIGHBOURS=10;
vector<Point2D> tmp=a;
for(int i=0;i<a.size();i++)
{
if(i+NO_OF_NEIGHBOURS+1<a.size())
{
for(int j=1;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x+=a.at(i+j).x;
a.at(i).y+=a.at(i+j).y;
}
a.at(i).x/=NO_OF_NEIGHBOURS;
a.at(i).y/=NO_OF_NEIGHBOURS;
}
else
{
for(int j=1;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x+=tmp.at(i-j).x;
a.at(i).y+=tmp.at(i-j).y;
}
a.at(i).x/=NO_OF_NEIGHBOURS;
a.at(i).y/=NO_OF_NEIGHBOURS;
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是我为每个点获得了非常高的值,而不是与前一点相似的值.形状最大化了很多,这个算法出了什么问题?
lea*_*vst 10
你在这里看到的是有限脉冲响应(FIR)滤波器的低音实现,它实现了一个boxcar窗口函数.考虑到DSP方面的问题,你需要vector用NO_OF_NEIGHBOURS相等的FIR系数过滤你的输入,每个系数的值都是1/NO_OF_NEIGHBOURS.通常最好使用既定算法而不是重新发明轮子.
这是一个非常笨拙的实现,我很快就敲定了过滤器加倍.您可以轻松修改此选项以过滤数据类型.该演示显示了上升锯功能(0,.25,.5,1)的几个周期的过滤,仅用于演示目的.它编译,所以你可以玩它.
#include <iostream>
#include <vector>
using namespace std;
class boxFIR
{
int numCoeffs; //MUST be > 0
vector<double> b; //Filter coefficients
vector<double> m; //Filter memories
public:
boxFIR(int _numCoeffs) :
numCoeffs(_numCoeffs)
{
if (numCoeffs<1)
numCoeffs = 1; //Must be > 0 or bad stuff happens
double val = 1./numCoeffs;
for (int ii=0; ii<numCoeffs; ++ii) {
b.push_back(val);
m.push_back(0.);
}
}
void filter(vector<double> &a)
{
double output;
for (int nn=0; nn<a.size(); ++nn)
{
//Apply smoothing filter to signal
output = 0;
m[0] = a[nn];
for (int ii=0; ii<numCoeffs; ++ii) {
output+=b[ii]*m[ii];
}
//Reshuffle memories
for (int ii = numCoeffs-1; ii!=0; --ii) {
m[ii] = m[ii-1];
}
a[nn] = output;
}
}
};
int main(int argc, const char * argv[])
{
boxFIR box(1); //If this is 1, then no filtering happens, use bigger ints for more smoothing
//Make a rising saw function for demo
vector<double> a;
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
box.filter(a);
for (int nn=0; nn<a.size(); ++nn)
{
cout << a[nn] << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
使用此行增加滤波器系数的数量,以查看逐渐更平滑的输出.只有1个滤波器系数,没有平滑.
boxFIR box(1);
Run Code Online (Sandbox Code Playgroud)
代码足够灵活,您甚至可以根据需要更改窗口形状.通过修改构造函数中定义的系数来完成此操作.
注意:这将为您的实现提供略有不同的输出,因为这是一个因果过滤器(仅取决于当前样本和以前的样本).您的实现不是因果关系,因为它在未来的样本中及时展望以获得平均值,这就是为什么您需要条件语句来处理接近矢量末尾的情况.如果你想要输出就像你试图用你的过滤器一样使用这个算法,那么通过这个算法反向运行你的向量(只要窗口函数是对称的,这个工作正常).这样你就可以得到类似的输出而没有讨厌的条件部分算法.
在以下块中:
for(int j=0;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x=a.at(i).x+a.at(i+j).x;
a.at(i).y=a.at(i).y+a.at(i+j).y;
}
Run Code Online (Sandbox Code Playgroud)
对于每个邻居,您分别将 a.at(i)'sx 和 y 添加到邻居值。
我理解正确,应该是这样的。
for(int j=0;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x += a.at(i+j+1).x
a.at(i).y += a.at(i+j+1).y
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15448 次 |
| 最近记录: |