五点三次平滑法滤波 C 和 matlab代码

 
 
转载http://blog.csdn.net/liyuanbhu/article/details/11119081
以五点三次平滑为例。取相邻的5个数据点,可以拟合出一条3次曲线来,然后用3次曲线上相应的位置的数据值作为滤波后结果。简单的说就是 Savitzky-Golay 滤波器 。只不过Savitzky-Golay 滤波器并不特殊考虑边界的几个数据点,而这个算法还特意把边上的几个点的数据拟合结果给推导了出来。
首先是线性拟合平滑处理的代码. 分别为三点线性平滑、五点线性平滑和七点线性平滑。
void linearSmooth3 ( double in [], double out [], int N )
{
int i ;
if ( N < 3 )
{
for ( i = 0 ; i <= N - 1 ; i ++ )
{
out [ i ] = in [ i ];
}
}
else
{
out [ 0 ] = ( 5.0 * in [ 0 ] + 2.0 * in [ 1 ] - in [ 2 ] ) / 6.0 ;
for ( i = 1 ; i <= N - 2 ; i ++ )
{
out [ i ] = ( in [ i - 1 ] + in [ i ] + in [ i + 1 ] ) / 3.0 ;
}
out [ N - 1 ] = ( 5.0 * in [ N - 1 ] + 2.0 * in [ N - 2 ] - in [ N - 3 ] ) / 6.0 ;
}
}
void linearSmooth5 ( double in [], double out [], int N )
{
int i ;
if ( N < 5 )
{
for ( i = 0 ; i <= N - 1 ; i ++ )
{
out [ i ] = in [ i ];
}
}
else
{
out [ 0 ] = ( 3.0 * in [ 0 ] + 2.0 * in [ 1 ] + in [ 2 ] - in [ 4 ] ) / 5.0 ;
out [ 1 ] = ( 4.0 * in [ 0 ] + 3.0 * in [ 1 ] + 2 * in [ 2 ] + in [ 3 ] ) / 10.0 ;
for ( i = 2 ; i <= N - 3 ; i ++ )
{
out [ i ] = ( in [ i - 2 ] + in [ i - 1 ] + in [ i ] + in [ i + 1 ] + in [ i + 2 ] ) / 5.0 ;
}
out [ N - 2 ] = ( 4.0 * in [ N - 1 ] + 3.0 * in [ N - 2 ] + 2 * in [ N - 3 ] + in [ N - 4 ] ) / 10.0 ;
out [ N - 1 ] = ( 3.0 * in [ N - 1 ] + 2.0 * in [ N - 2 ] + in [ N - 3 ] - in [ N - 5 ] ) / 5.0 ;
}
}
void linearSmooth7 ( double in [], double out [], int N )
{
int i ;
if ( N < 7 )
{
for ( i = 0 ; i <= N - 1 ; i ++ )
{
out [ i ] = in [ i ];
}
}
else
{
out [ 0 ] = ( 13.0 * in [ 0 ] + 10.0 * in [ 1 ] + 7.0 * in [ 2 ] + 4.0 * in [ 3 ] +
in [ 4 ] - 2.0 * in [ 5 ] - 5.0 * in [ 6 ] ) / 28.0 ;
out [ 1 ] = ( 5.0 * in [ 0 ] + 4.0 * in [ 1 ] + 3 * in [ 2 ] + 2 * in [ 3 ] +
in [ 4 ] - in [ 6 ] ) / 14.0 ;
out [ 2 ] = ( 7.0 * in [ 0 ] + 6.0 * in [ 1 ] + 5.0 * in [ 2 ] + 4.0 * in [ 3 ] +
3.0 * in [ 4 ] + 2.0 * in [ 5 ] + in [ 6 ] ) / 28.0 ;
for ( i = 3 ; i <= N - 4 ; i ++ )
{
out [ i ] = ( in [ i - 3 ] + in [ i - 2 ] + in [ i - 1 ] + in [ i ] + in [ i + 1 ] + in [ i + 2 ] + in [ i + 3 ] ) / 7.0 ;
}
out [ N - 3 ] = ( 7.0 * in [ N - 1 ] + 6.0 * in [ N - 2 ] + 5.0 * in [ N - 3 ] +
4.0 * in [ N - 4 ] + 3.0 * in [ N - 5 ] + 2.0 * in [ N - 6 ] + in [ N - 7 ] ) / 28.0 ;
out [ N - 2 ] = ( 5.0 * in [ N - 1 ] + 4.0 * in [ N - 2 ] + 3.0 * in [ N - 3 ] +
2.0 * in [ N - 4 ] + in [ N - 5 ] - in [ N - 7 ] ) / 14.0 ;
out [ N - 1 ] = ( 13.0 * in [ N - 1 ] + 10.0 * in [ N - 2 ] + 7.0 * in [ N - 3 ] +
4 * in [ N - 4 ] + in [ N - 5 ] - 2 * in [ N - 6 ] - 5 * in [ N - 7 ] ) / 28.0 ;
}
}

然后是利用二次函数拟合平滑。

 
 
void quadraticSmooth5 ( double in [], double out [], int N )
{
int i ;
if ( N < 5 )
{
for ( i = 0 ; i <= N - 1 ; i ++ )
{
out [ i ] = in [ i ];
}
}
else
{
out [ 0 ] = ( 31.0 * in [ 0 ] + 9.0 * in [ 1 ] - 3.0 * in [ 2 ] - 5.0 * in [ 3 ] + 3.0 * in [ 4 ] ) / 35.0 ;
out [ 1 ] = ( 9.0 * in [ 0 ] + 13.0 * in [ 1 ] + 12 * in [ 2 ] + 6.0 * in [ 3 ] - 5.0 * in [ 4 ]) / 35.0 ;
for ( i = 2 ; i <= N - 3 ; i ++ )
{
out [ i ] = ( - 3.0 * ( in [ i - 2 ] + in [ i + 2 ]) +
12.0 * ( in [ i - 1 ] + in [ i + 1 ]) + 17 * in [ i ] ) / 35.0 ;
}
out [ N - 2 ] = ( 9.0 * in [ N - 1 ] + 13.0 * in [ N - 2 ] + 12.0 * in [ N - 3 ] + 6.0 * in [ N - 4 ] - 5.0 * in [ N - 5 ] ) / 35.0 ;
out [ N - 1 ] = ( 31.0 * in [ N - 1 ] + 9.0 * in [ N - 2 ] - 3.0 * in [ N - 3 ] - 5.0 * in [ N - 4 ] + 3.0 * in [ N - 5 ]) / 35.0 ;
}
}
void quadraticSmooth7 ( double in [], double out [], int N )
{
int i ;
if ( N < 7 )
{
for ( i = 0 ; i <= N - 1 ; i ++ )
{
out [ i ] = in [ i ];
}
}
else
{
out [ 0 ] = ( 32.0 * in [ 0 ] + 15.0 * in [ 1 ] + 3.0 * in [ 2 ] - 4.0 * in [ 3 ] -
6.0 * in [ 4 ] - 3.0 * in [ 5 ] + 5.0 * in [ 6 ] ) / 42.0 ;
out [ 1 ] = ( 5.0 * in [ 0 ] + 4.0 * in [ 1 ] + 3.0 * in [ 2 ] + 2.0 * in [ 3 ] +
in [ 4 ] - in [ 6 ] ) / 14.0 ;
out [ 2 ] = ( 1.0 * in [ 0 ] + 3.0 * in [ 1 ] + 4.0 * in [ 2 ] + 4.0 * in [ 3 ] +
3.0 * in [ 4 ] + 1.0 * in [ 5 ] - 2.0 * in [ 6 ] ) / 14.0 ;
for ( i = 3 ; i <= N - 4 ; i ++ )
{
out [ i ] = ( - 2.0 * ( in [ i - 3 ] + in [ i + 3 ]) +
3.0 * ( in [ i - 2 ] + in [ i + 2 ]) +
6.0 * ( in [ i - 1 ] + in [ i + 1 ]) + 7.0 * in [ i ] ) / 21.0 ;
}
out [ N - 3 ] = ( 1.0 * in [ N - 1 ] + 3.0 * in [ N - 2 ] + 4.0 * in [ N - 3 ] +
4.0 * in [ N - 4 ] + 3.0 * in [ N - 5 ] + 1.0 * in [ N - 6 ] - 2.0 * in [ N - 7 ] ) / 14.0 ;
out [ N - 2 ] = ( 5.0 * in [ N - 1 ] + 4.0 * in [ N - 2 ] + 3.0 * in [ N - 3 ] +
2.0 * in [ N - 4 ] + in [ N - 5 ] - in [ N - 7 ] ) / 14.0 ;
out [ N - 1 ] = ( 32.0 * in [ N - 1 ] + 15.0 * in [ N - 2 ] + 3.0 * in [ N - 3 ] -
4.0 * in [ N - 4 ] - 6.0 * in [ N - 5 ] - 3.0 * in [ N - 6 ] + 5.0 * in [ N - 7 ] ) / 42.0 ;
}
}
最后是三次函数拟合平滑。

 
 
/**
* 五点三次平滑
*
*/
void cubicSmooth5 ( double in [], double out [], int N )
{
int i ;
if ( N < 5 )
{
for ( i = 0 ; i <= N - 1 ; i ++ )
out [ i ] = in [ i ];
}
else
{
out [ 0 ] = ( 69.0 * in [ 0 ] + 4.0 * in [ 1 ] - 6.0 * in [ 2 ] + 4.0 * in [ 3 ] - in [ 4 ]) / 70.0 ;
out [ 1 ] = ( 2.0 * in [ 0 ] + 27.0 * in [ 1 ] + 12.0 * in [ 2 ] - 8.0 * in [ 3 ] + 2.0 * in [ 4 ]) / 35.0 ;
for ( i = 2 ; i <= N - 3 ; i ++ )
{
out [ i ] = ( - 3.0 * ( in [ i - 2 ] + in [ i + 2 ]) + 12.0 * ( in [ i - 1 ] + in [ i + 1 ]) + 17.0 * in [ i ] ) / 35.0 ;
}
out [ N - 2 ] = ( 2.0 * in [ N - 5 ] - 8.0 * in [ N - 4 ] + 12.0 * in [ N - 3 ] + 27.0 * in [ N - 2 ] + 2.0 * in [ N - 1 ]) / 35.0 ;
out [ N - 1 ] = ( - in [ N - 5 ] + 4.0 * in [ N - 4 ] - 6.0 * in [ N - 3 ] + 4.0 * in [ N - 2 ] + 69.0 * in [ N - 1 ]) / 70.0 ;
}
return ;
}
void cubicSmooth7 ( double in [], double out [], int N )
{
int i ;
if ( N < 7 )
{
for ( i = 0 ; i <= N - 1 ; i ++ )
{
out [ i ] = in [ i ];
}
}
else
{
out [ 0 ] = ( 39.0 * in [ 0 ] + 8.0 * in [ 1 ] - 4.0 * in [ 2 ] - 4.0 * in [ 3 ] +
1.0 * in [ 4 ] + 4.0 * in [ 5 ] - 2.0 * in [ 6 ] ) / 42.0 ;
out [ 1 ] = ( 8.0 * in [ 0 ] + 19.0 * in [ 1 ] + 16.0 * in [ 2 ] + 6.0 * in [ 3 ] -
4.0 * in [ 4 ] - 7.0 * in [ 5 ] + 4.0 * in [ 6 ] ) / 42.0 ;
out [ 2 ] = ( - 4.0 * in [ 0 ] + 16.0 * in [ 1 ] + 19.0 * in [ 2 ] + 12.0 * in [ 3 ] +
2.0 * in [ 4 ] - 4.0 * in [ 5 ] + 1.0 * in [ 6 ] ) / 42.0 ;
for ( i = 3 ; i <= N - 4 ; i ++ )
{
out [ i ] = ( - 2.0 * ( in [ i - 3 ] + in [ i + 3 ]) +
3.0 * ( in [ i - 2 ] + in [ i + 2 ]) +
6.0 * ( in [ i - 1 ] + in [ i + 1 ]) + 7.0 * in [ i ] ) / 21.0 ;
}
out [ N - 3 ] = ( - 4.0 * in [ N - 1 ] + 16.0 * in [ N - 2 ] + 19.0 * in [ N - 3 ] +
12.0 * in [ N - 4 ] + 2.0 * in [ N - 5 ] - 4.0 * in [ N - 6 ] + 1.0 * in [ N - 7 ] ) / 42.0 ;
out [ N - 2 ] = ( 8.0 * in [ N - 1 ] + 19.0 * in [ N - 2 ] + 16.0 * in [ N - 3 ] +
6.0 * in [ N - 4 ] - 4.0 * in [ N - 5 ] - 7.0 * in [ N - 6 ] + 4.0 * in [ N - 7 ] ) / 42.0 ;
out [ N - 1 ] = ( 39.0 * in [ N - 1 ] + 8.0 * in [ N - 2 ] - 4.0 * in [ N - 3 ] -
4.0 * in [ N - 4 ] + 1.0 * in [ N - 5 ] + 4.0 * in [ N - 6 ] - 2.0 * in [ N - 7 ] ) / 42.0 ;
}
}

Matlab代码

加高斯白噪

function [Y,NOISE] = noisegen(X,SNR)
% noisegen add white Gaussian noise to a signal.
% [Y, NOISE] = NOISEGEN(X,SNR) adds white Gaussian NOISE to X. The SNR is in dB.
%X是纯信号,SNR是要求的信噪比,Y是带噪信号,NOISE是叠加在信号上的噪声。
NOISE=randn(size(X));
NOISE=NOISE-mean(NOISE);
signal_power = 1/length(X)*sum(X.*X);
noise_variance = signal_power / ( 10^(SNR/10) );
NOISE=sqrt(noise_variance)/std(NOISE)*NOISE;
Y=X+NOISE;

五点三次平滑滤波

function y = smooth5_3(x, m)
% x为需要的数据
% m 为平滑次数
n=length(x);
a=x;
for k=1: m
b(1) = (69*a(1) +4*(a(2) +a(4)) -6*a(3) -a(5)) /70;
b(2) = (2* (a(1) +a(5)) +27*a(2) +12*a(3) -8*a(4)) /35;
for j=3:n-2
b (j) = (-3*(a(j-2) +a(j+2)) +12*(a(j-1) +a(j+1)) +17*a(j)) /35;
end
b (n-1) = (2*(a(n) +a(n-4)) +27*a(n-1) +12*a(n-2) -8*a(n-3)) /35;
b (n) = (69*a(n) +4* (a(n-1) +a(n-3)) -6*a(n-2) -a(n-4)) /70;
a=b;
end
y =a;



  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 寻峰算Matlab中的一种信号处理算,主要用于寻找信号中的峰值。峰值是指信号中最高的点或数据点,通常用于分析信号中的峰或波峰。 Matlab中的寻峰算主要有两种:基于阈值和基于拟合。基于阈值的方将信号与给定阈值进行比较,寻找高于阈值的峰值。基于拟合的方则将信号拟合为多项式函数,在函数的极值处寻找峰值。 寻峰算在很多领域中得到广泛应用,如化学分析中的光谱峰值、医学领域中的ECG信号处理等。它不仅可以提取信号特征,还可以为后续分析提供重要的数据支持。 在实际应用中,需要根据信号的特点和处理需求选择合适的寻峰算。同时,还需考虑信噪比、采样率等因素对算的影响,以达到最佳的处理效果。 ### 回答2: Matlab中的寻峰算是一种用于信号处理和谱分析的方,它可以找到信号中存在的最大峰值,并在一定程度上帮助识别信号的特征。 寻峰算的实现方比较简单,在Matlab中可以通过自带的findpeaks函数或自定义函数来实现寻峰功能。该算的基本思想是在信号中找到极值点,并通过对两个峰之间的信息进行分析,找到信号中的最大峰值。 在Matlab中使用findpeaks函数可以方便地找到信号中的峰值,该函数支持多种不同的寻峰参数设置,可以根据不同的信号特征进行调整,以得到最佳结果。通常情况下,通过设定合适的峰宽、最小峰高度、斜率阈值和最小峰距等参数,可以在信号中找到真正的峰值。 除了使用自带函数外,用户也可以通过自定义函数来实现寻峰功能。比如,可以通过利用差分和阈值处理来找到峰值点,也可以使用高斯拟合和二次曲线拟合等方来对信号进行处理和分析,以找到最大峰值。 综上所述,Matlab的寻峰算是一种简单而有效的信号处理工具,可以用于多种不同类型的信号处理和分析任务。在实际应用中,用户可以根据具体需求来选择合适的寻峰方和参数设置,以得到准确、可靠的结果。 ### 回答3: Matlab是一个强大的数学计算软件,其中包含多种寻峰算。寻峰算可以用于寻找数据集中的最高点或最低点,是信号处理和图像处理中常用的技术。 在Matlab中,寻峰算主要有几种:基于导数和二阶导数的峰值检测、基于FFT的峰值检测、基于小波分析的峰值检测等。 其中,基于导数和二阶导数的峰值检测是最常用的方之一。该方通过对数据求取导数或二阶导数,利用导数的零点或二阶导数的极值点来检测峰值。这种方的优点是简单易用,计算速度快,对于单峰和峰不重叠的情况效果较好。 基于FFT的峰值检测方是另一种常用的方。该方利用FFT将数据变换到频域进行分析,通过对频谱进行峰值检测来确定数据集中的最高峰值。该方的优点是能够处理峰重叠和峰宽不同的情况,但需要对数据进行预处理和频域分析,计算量较大。 基于小波分析的峰值检测方是比较新的一种方。该方利用小波变换对数据进行分解,通过计算小波系数来检测峰值。该方的优点是能够处理峰重叠和峰宽不同的情况,但需要对小波变换进行理解和掌握。 总的来说,在Matlab中选择合适的寻峰算要根据实际数据的情况来确定。如果数据比较简单,可以选择基于导数和二阶导数的峰值检测方;如果数据比较复杂,可以考虑基于FFT或小波分析的峰值检测方。在使用时,需要对算的原理和参数进行理解和调整,以保证峰值检测的准确性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值