前几天写过一篇介绍 Savitzky-Golay滤波器的文章, 没想到最近做项目还真的用上了。
因此就顺便写了个 C 语言的自动计算生成 SG 滤波器系数的程序。利用这里的代码可以生成任意阶数的 SG 滤波器。对于一些需要动态调整 SG 滤波器系数的场合,这里的代码还是很实用的。 上次的文章中给出了计算 SG 滤波器系数的 matlab 代码。

    x=[zeros(1,M),1,zeros(1,M)]
a=polyfit([-M:M],x,N)
polyval(a,[-M:M])

只有三行,非常的简单。但是现在项目需要用 C 语言来实现。要是 用 C 语言从头写起这个代码会非常的长,光一个 ployfit 函数实现起来就很麻烦。我的程序中直接调用了 GSL 的相关函数。使得整个程序简化了很多。
先说说 polyfit 函数。多项式函数拟合可以转换成超定线性代数方程组的最小二乘解的问题。标准解法是 SVD 分解。不过GSL库中提供了 gsl_multifit_linear 函数进行线性模型的拟合,可以直接使用。下面给出代码。很简单,就不多做解释了。这个例子也可以作为 gsl_multifit_linear 函数用法的一个小例子。

/**
* 多项式拟合函数
* 根据 x y 拟合出一个N次多项式。返回多项式的系数。
*/
gsl_vector* PolyFit(gsl_vector *x, gsl_vector *y, int N)
{
int i, j;
int M = GSL_MIN(x->size, y->size);
double chisq, xi; gsl_matrix *XX = gsl_matrix_alloc(M, N + 1);
gsl_vector *c = gsl_vector_alloc(N + 1);
gsl_matrix *cov = gsl_matrix_alloc(N + 1, N + 1); for(i = 0; i < M; i++)
{
gsl_matrix_set(XX, i, 0, 1.0);
xi = gsl_vector_get(x, i);
for(j = 1; j <= N; j++)
{
gsl_matrix_set(XX, i, j, pow(xi, j));
}
}
gsl_multifit_linear_workspace *workspace = gsl_multifit_linear_alloc(M, N + 1);
gsl_multifit_linear(XX, y, c, cov, &chisq, workspace); gsl_matrix_free(XX);
gsl_matrix_free(cov);
gsl_multifit_linear_free(workspace);
return c;
}

有了 PolyFit 函数就可以计算 SG 滤波器的系数了。

Matlab 中的 polyval 函数 可以用 gsl_poly_eval 来实现。

下面是具体的代码。

/**
* 计算 Savitzky-Golay 滤波器系数
* SG 滤波器的阶数为 2M+1,多项式的最高次数为 N
*/
gsl_vector* SG_FilterCreate(int M, int N /* Poly Order */)
{
int i;
gsl_vector *x = gsl_vector_alloc(2 * M + 1);
gsl_vector *y = gsl_vector_alloc(2 * M + 1); gsl_vector_set_zero(y);
gsl_vector_set(y, M, 1); for(i= -M; i <= M; i++)
{
gsl_vector_set(x, i + M, i);
}
gsl_vector *c = PolyFit(x, y, N);
gsl_vector_free(x);
gsl_vector_free(y); gsl_vector *fir = gsl_vector_alloc(2 * M + 1);
for(i = -M; i <= M; i++)
{
gsl_vector_set(fir, i + M, gsl_poly_eval (c->data, N + 1, i));
}
gsl_vector_free(c);
return fir;
}

Savitzky-Golay滤波器(2)的更多相关文章

  1. Matlab 高斯_拉普拉斯滤波器处理医学图像

    前言:本程序是我去年实现论文算法时所做.主要功能为标记切割肝脏区域.时间有点久,很多细节已经模糊加上代码做了很多注释,因此在博客中不再详述. NOTE: 程序分几大段功能模块,仔细阅读,对解决医学图像 ...

  2. QMF滤波器组 理论

    QMF滤波器组  经常被用来子带信号分解,降低信号带宽,使各个子带可顺利由通道处理.    2^M个通道,等宽 QMF   正交镜像滤波器 正交滤波器 A(W)  与  A(W+pi)  之间的关系 ...

  3. IIR滤波器和FIR滤波器的区别与联系zz

      -------------------------------------------------------------------------------------------------- ...

  4. 巴特沃斯(Butterworth)滤波器 (1)

    下面深入浅出讲一下Butterworth原理及其代码编写. 1. 首先考虑一个归一化的低通滤波器(截止频率是1),其幅度公式如下: 当n->∞时,得到一个理想的低通滤波反馈: ω<1时,增 ...

  5. Google开源SLAM软件cartographer中使用的UKF滤波器解析

    在Google开源SLAM软件cartographer中,相对<SLAM for dummies>使用了更为复杂.性能更好的Scan匹配与UKF算法,这里简单介绍下cartographer ...

  6. 卡尔曼滤波器 Kalman Filter (转载)

    在学习卡尔曼滤波器之前,首先看看为什么叫“卡尔曼”.跟其他著名的理论(例如傅立叶变换,泰勒级数等等)一样,卡尔曼也是一个人的名字,而跟他们不同的是,他是个现代人! 卡 尔曼全名Rudolf Emil ...

  7. [转]第1讲 什么是EMI滤波器

    转:http://www.murata.com/zh-cn/products/emiconfun/emc/2010/10/28/en-20101028-p1 <前言> EMI是Electr ...

  8. matlab的滤波器仿真——低通滤波器与插值滤波器

    项目里面有用到插值滤波器的场合,用matlab做了前期的滤波器性能仿真,产生的滤波器系数保存下来输入到FPGA IP中使用即可. 下面是仿真的代码 % clear all close all Nx = ...

  9. [转载]卡尔曼滤波器及其基于opencv的实现

    卡尔曼滤波器及其基于opencv的实现 源地址:http://hi.baidu.com/superkiki1989/item/029f65013a128cd91ff0461b 这个是维基百科中的链接, ...

  10. Matlab滤波器设计(转)

    滤波器设计是一个创建满足指定滤波要求的滤波器参数的过程.滤波器的实现包括滤波器结构的选择和滤波器参数的计算.只有完成了滤波器的设计和实现,才能最终完成数据的滤波. 滤波器设计的目标是实现数据序列的频率 ...

随机推荐

  1. 使用LiveWriter发布Orchard博客

    我们可以Windows Live Writer来发布Orchard博客 在Dashboard–> Modules菜单找到 Remote Blog Publishing 模块.点击 Enable ...

  2. Struts2项目中使用Ajax报错

    在Struts2项目中使用Ajax向后台请求数据,当添加了json-lib-2.3-jdk15.jar和struts2-json-plugin-2.3.4.1.jar两个包时,在result中配置ty ...

  3. iOS 滤镜 转载,原文见正文首行链接

    转载自:http://blog.sina.com.cn/s/blog_5fb39f9101018gv7.html 直接上代码了: // // ViewController.m // 图片模糊处理 // ...

  4. Windows最常用的几个网络CMD命令总结

    Windows最常用的几个网络CMD命令总结 http://www.cnblogs.com/sbaicl/archive/2013/03/05/2944001.html 一.ping 主要是测试本机T ...

  5. BZOJ 100题留念

  6. BZOJ 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课( BFS )

    BFS... 我连水题都不会写了QAQ ------------------------------------------------------------------------- #inclu ...

  7. Square(hdu 1511)

    题目描述: Problem Description Given a set of sticks of various lengths, is it possible to join them end- ...

  8. 转 fiddler教程

    Fiddler 教程 Fiddler是最强大最好用的Web调试工具之一,它能记录所有客户端和服务器的http和https请求,允许你监视,设置断点,甚至修改输入输出数据. 使用Fiddler无论对开发 ...

  9. grawlew 编译

    http://somefuture.iteye.com/blog/2002052 Gradlew behind a proxy systemProp.http.proxyHost=www.someho ...

  10. dubbo 服务化

    当网站变大后,不可避免的需要拆分应用进行服务化,以提高开发效率,调优性能,节省关键竞争资源等. 当服务越来越多时,服务的URL地址信息就会爆炸式增长,配置管理变得非常困难,F5硬件负载均衡器的单点压力 ...