信号处理中简单实用的方法

news2024/10/4 22:05:32

最小二乘法拟合消除趋势项

消除趋势项函数

在MATLAB的工具箱中已有消除线性趋势项的detrend函数;再介绍以最小二乘法拟合消除趋势项的polydetrend 函数。

函数:detrend功能:消除线性趋势项

调用格式:y=detrend(x)

说明:输入参数x是带有线性趋势项的信号序列,输出参数y是消除趋势项的序列。

函数:polydetrend功能:最小二乘法拟合消除多项式的趋势项

调用格式:[y,xtrend]=polydetrend(x,fs,m)

说明:输人参数x是带有趋势项的信号,fs是采样频率,m是调用本函数时设置的多项式阶次。输出参数y是消除趋势项后的信号序列,xtrend是叠加在信号上的趋势项序列。函数polydetrend的程序清单如下:

function [y,xtrend]=polydetrend(x, fs, m)
x=x(:);                 % 把语音信号x转换为列数据
N=length(x);            % 求出x的长度
t= (0: N-1)'/fs;        % 按x的长度和采样频率设置时间序列
a=polyfit(t, x, m);     % 用最小二乘法拟合语音信号x的多项式系数a
xtrend=polyval(a, t);   % 用系数a和时间序列t构成趋势项
y=x-xtrend;             % 从语音信号x中清除趋势项

基线漂移的修正

1.概 述

在实际采集到的信号中经常会发生基线漂移,这可能是由多种原因造成的。本案例将介绍在心电图检测中,若由于病人身体的轻微活动造成了心电图信号的基线漂移,则在后期处理中就可以用最小二乘法拟合消除消除基线的漂移。

2.实例

读入已知的心电图ecgdata2.mat数据,用最小二乘法拟合消除基线的漂移。程序清单如下:

clear all; clc; close all;
load ecgdata2.mat                   % 读入心电图数据
N=length(y);                        % 数据长度
time=(0:N-1)/fs;                    % 计算出时间刻度
[x,xtrend]=polydetrend(y, fs, 3);   % 用多项式拟合法求出趋势项及消除后的序列
% 作图
subplot 311; plot(time,y,'k')
title('输入心电信号'); ylabel('幅值');
axis([0 max(time) -2000 6000]); grid;
subplot 312; plot(time,xtrend,'k','linewidth',1.5);
title('趋势项信号'); ylabel('幅值');
axis([0 max(time) -2000 6000]); grid;
subplot 313; plot(time,x,'k'); 
title('消除趋势项心电信号'); ylabel('幅值');
xlabel('时间/s');
axis([0 max(time) -2000 6000]); grid;
set(gcf,'color','w');

3.案例延伸

除了以最小二乘法拟合消除趋势项以外,还有其他方法可以消除趋势项,只是最小二乘法拟合的方法用得较多。其他的方法主要是一些平滑或滤波的方法,只取信号中的低频信号。例如可以用sgolay滤波器求取趋势项。sgolay滤波器是由SavitzkyA和GolayM在1964年提出的一种基于多项式拟合的最佳形式的低通滤波器[23,将在4.5.3小节中详细地说明。下面给出用sgolay滤波器对中的心电图数据消除趋势项的方法。读人已知的心电图ecgdata2.mat数据,用sgolay 滤波器消除基线的漂移。程序清单如下:

clear all; clc; close all;
load ecgdata2.mat                   % 读入心电图数据
N=length(y);                        % 数据长度
time=(0:N-1)/fs;                    % 计算出时间刻度
y1=sgolayfilt(y,3,2001);            % 用sgolay滤波器求出趋势项
x=y-y1;                             % 计算消除趋势项后的序列
% 作图
subplot 311; plot(time,y,'k')
title('输入心电信号'); ylabel('幅值');
axis([0 max(time) -2000 6000]); grid;
subplot 312; plot(time,y1,'k','linewidth',1.5);
title('趋势项信号'); ylabel('幅值');
axis([0 max(time) -2000 6000]); grid;
subplot 313; plot(time,x,'k'); 
title('消除趋势项心电信号'); ylabel('幅值');
xlabel('时间/s');
axis([0 max(time) -2000 6000]); grid;
set(gcf,'color','w');

寻找信号中的峰值和谷值

MATLAB中峰谷值检测的函数

1.检测峰值的函数

检测峰值的函数是MATLAB自带的,在signal工具箱中

函数:findpeaks

功能:寻找待测信号的峰值

调用格式:
pks = findpeaks(x)
[pks,locs] = findpeaks(x)
[pks,locs]=findpeaks(x,'属性',参数)

说明:如果只找一个峰值可以用max函数,而需要寻找多个峰值才用本函数findpeaks。输入参数中x是被检测的信号序列,pks是被检测到信号中峰值的幅值,locs是被检测到峰值的位置,是序列的索引号。为了检测到峰值可以设置各种条件,即由属性和对应的参数来限定。可以利用findpeaks函数中的属性和参数较灵活地寻求序列中的峰值,在以下案例中还会介绍利用findpeaks函数来寻找谷值。

2.检测峰值和谷值的函数

本函数检测峰值和谷值,但不是MATLAB自带的,而是由帝国理工学院电气电子工程系的Mike Brookes教授在voicebox中提供的。该函数原名为findpeaks,为了避免和 MATLAB自带的findpeaks混淆,在本书中改名为findpeakm。

所数:findpeakm功能:寻找待测信号的峰值和谷值

调用格式:[K,V]= findpeakm(x,m,w)

说明:输入变量x是被测序列;m是方式,选用'g'时是用二次曲线内插后寻找峰值,选用v'时是寻找谷值;w是在寻找峰值时,两个峰值之间最小间隔的样点数。

已知一个脉动信号,如何求信号的周期

1.概 述

在实际信号处理中经常会遇到脉动信号,可通过提取峰值求出峰值间的距离计算出脉动信号的平均周期,如果有谷值的话也可以从谷值间的距离计算出脉动信号的平均周期。在本节中用脉搏信号分别从峰值和谷值位置获取脉动信号的平均周期。

2.实 例

某一患者的脉搏信号在ffpulse.txt文件中,采样频率是200Hz。脉搏不稳定,通过脉搏信号的峰值求出脉搏的平均周期。程序第一部分清单如下:

clear all; clc; close all;
y=load('ffpulse.txt');       % 读入脉搏数据
x=detrend(y);                % 消除趋势项
fs=200;                      % 采样频率
N=length(x);                 % 数据长度
time=(0:N-1)/fs;             % 时间刻度
% 第一部分,用findpeaks函数求峰值位置
[Val,Locs]=findpeaks(x,'MINPEAKHEIGHT',200,'MINPEAKDISTANCE',100);
T1=time(Locs);               % 取得脉搏峰值时间
M1=length(T1);
T11=T1(2:M1);
T12=T1(1:M1-1);
Mdt1=mean(T11-T12);          % 从峰值得的平均周期值
fprintf('峰值求得的平均周期值=%5.4f\n',Mdt1);
% 作图
pos = get(gcf,'Position');
set(gcf,'Position',[pos(1), pos(2)-100,pos(3),(pos(4)-140)]);
plot(time,x,'k'); hold on; grid;
plot(time(Locs),Val,'ro','linewidth',3);
xlabel('时间/s'); ylabel('幅值'); title('脉搏信号波形图')
set(gcf,'color','w');
% pause
% 第二部分,用findpeakm函数求谷值位置
[K,V]=findpeakm(x,'v',100);
T2=time(K);                  % 取得脉搏谷值时间
M2=length(T2);
T21=T2(2:M1);
T22=T2(1:M1-1);
Mdt2=mean(T21-T22);          % 从谷值得的平均周期值
fprintf('谷值求得的平均周期值=%5.4f\n',Mdt2);
% 作图
plot(time(K),V,'gO','linewidth',3);
set(gcf,'color','w');

如何利用findpeaks 函数求谷值

1.概 述

一般是利用findpeaks函数来寻找峰值,但有时也会利用findpeaks函数来寻找谷值,因为在findpeaks函数中可以设置较多的限制条件,在需要用到这些限制条件会比用findpeakm寻找谷值更有利。

2.实 例

采集到一组数据在文件SDgdata2.mat中,由于外界干扰的原因信号的基线有不规则的漂移,故希望能把基线拉平。读人 SDgdata2.mat文件得到如图4-2-3所示的数据波形图,从图中可看出数据的基线极不规则,下面用找出极小值(谷值点)的方法把基线拉平。

clear all; clc; close all;
load SDqdata2.mat                      % 读入信号
y=-mix_signal;                         % 把输入信号反相
% 信号反相后用findpeaks函数检测峰值替代谷值的检测
[Val,Locs]=findpeaks(y,'MINPEAKHEIGHT',-1400,'MINPEAKDISTANCE',5);
b0=interp1(time(Locs),-Val,time);      % 延伸谷值,构成基线偏离曲线
x=-y-b0;                               % 基线拉平的信号
% 作图 
subplot 211; plot(time,y,'k'); hold on; grid
plot(time(Locs),Val,'r.','linewidth',3);
xlabel('时间/s'); ylabel('幅值'); 
title('把信号颠倒过来用寻找峰值替代寻找谷值'); 
subplot 212; plot(time,x,'k');
xlabel('时间/s'); ylabel('幅值');
title('把基线拉平后的波形图'); grid;
set(gcf,'color','w');

说明:为了能使用findpeaks函数,把读入的信号反相操作,即正值变负值;负值变正值,这样就能用求峰值替代求谷值了。读人的数据mix_signal同样不是一条平滑的曲线,有许许多多的峰值和谷值,为了能获取基线的漂移,必须要适当地选择findpeaks函数中的一些限制参数。在这里选择了MINPEAKIIEIGHT',-1400和MINPEAKDISTANCE',5.从findpeaks函数得到极值点的位置和数值,但这些不是基线的漂移曲线中每一点的位置和数值,而是基线漂移曲线中极值点的位移和数值。通过内插可得到整条基线漂移曲线,再从信号中减去基线漂移,基线基本上得到了校正。

寻找信号中的峰值和谷值

在信号处理中经常会对时间域或频率域的信号提取信号波形的包络,在提取包络后往往还要做进一步处理。提取包络最常用的方法是希尔伯特变换,此外还有其他方法,介绍几种实用的方法。

用希尔伯特变换计算信号的包络

1.概况

在求某一信号包络时用得最多的是希尔伯特变换,但并不是希尔伯特变换适用于所有信号求包络的情况。这是因为对于包络没有一个很严格的定义,在求包络时不同的情况会有不同的要求。本小节介绍用希尔伯特变换求取信号的包络。

2.实例

设信号x(n)=120+96e-(m/1500)cos(2xn/600),n=-5000:20:例4-3-1(pr4 31)5000,求该信号的包络线。设置信号后直接调用hilbert函数求信号的包络,程序清单的第一部分如下:

clear ; clc; close all;
n=-5000:20:5000;            % 样点设置
% 程序第一部分:直接做做希尔伯特变换
N=length(n);                % 信号样点数
nt=0:N-1;                   % 设置样点序列号
x=120+96*exp(-(n/1500).^2).*cos(2*pi*n/600); % 设置信号
Hx=hilbert(x);              % 希尔伯特变换
% 作图
plot(nt,x,'k',nt,abs(Hx),'r');
grid; legend('信号','包络');
xlabel('样点'); ylabel('幅值')
title('信号和包络')
set(gcf,'color','w');

% 程序第二部分:消除直流后做希尔伯特变换
y=x-120;                    % 消除直流分量
Hy=hilbert(y);              % 希尔伯特变换
% 作图
figure(2)
plot(nt,y,'k',nt,abs(Hy),'r');
grid; legend('信号','包络');
xlabel('样点'); ylabel('幅值')
title('信号和包络')
set(gcf,'color','w');

figure(3);
plot(nt,x,'k',nt,abs(Hy)+120,'r');
grid; legend('信号','包络'); hold on;
xlabel('样点'); ylabel('幅值')
title('信号和包络')
set(gcf,'color','w');

% 程序第三部分:通过频域做希尔伯特变换
y_fft=fft(y);               % FFT
y_hit(1)=y_fft(1);          % 按式(4-3-11)设置y_hit
y_hit(2:(N+1)/2)=2*y_fft(2:(N+1)/2);
y_hit((N+1)/2+1:N)=0;
z=ifft(y_hit);              % 对y_hit做IFFT
% 作图
figure(4)
subplot 211; plot(n,real(Hy),'r',n,real(z),'g');
xlabel('样点'); ylabel('幅值'); legend('时域','频域')
title('频域和时域希尔伯特变换实部比较');
subplot 212; plot(n,imag(Hy),'r',n,imag(z),'g');
xlabel('样点'); ylabel('幅值'); legend('时域','频域')
title('频域和时域希尔伯特变换虚部比较');set(gcf,'color','w');

figure(5)
plot(nt,x,'k',nt,abs(z)+120,'r');
grid; legend('信号','包络');
xlabel('样点'); ylabel('幅值')
title('信号和包络')
set(gcf,'color','w');

用求极大值和极小值的方法来计算信号的包络线

1.概 述

指出用hilbert函数求包络线不一定适用于所有的信号,有时对包络线的要求也不完全相同,所以在某些情况下可以用极大值,、极小值的方法来求取信号的包络线。

2.案例分析

从文件pulsedata0.txt中读出脉冲信号,求取该脉冲信号的上、下包络线。本例将分为两部分:第一部分用hilbert函数求包络线,第二部分用极大值、极小值的方法来求取包络线。程序第一部分清单如下:

clear all; clc; close all;
xx=load('pulsedata0.txt');   % 读入信号
N=length(xx);                % 数据长度
n=1:N;                       % 设置样点序列
% 作图
plot(n,xx,'k'); grid;
xlabel('样点'); ylabel('幅值');
title('原始信号波形图')
set(gcf,'color','w');
% 程序第一部分用hilbert计算信号的包络
xm=sum(xx)/N;                % 计算信号的直流分量
x=xx-xm;                     % 消除直流分量
z=hilbert(x);                % 进行希尔伯特变换
% 作图
figure(2)
plot(n,x,'k'); hold on; grid;
plot(n,abs(z),'r');
xlabel('样点'); ylabel('幅值');
title('消除直流分量用求取包络曲线图')
set(gcf,'color','w');
% 程序第二部分用求极大极小值计算信号的包络 
% 利用findpeakm函数计算信号的极大极小值
[K1,V1]=findpeakm(x,[],120); % 求极大值位置和幅值
up=spline(K1,V1,n);          % 内插,获取上包络曲线
[K2,V2]=findpeakm(x,'v',120);% 求极小值位置和幅值
down=spline(K2,V2,n);        % 内插,获取下包络曲线
% 作图
figure(3)
plot(n,x,'k'); hold on; grid;
plot(n,up,'r');
plot(n,down,'r');
xlabel('样点'); ylabel('幅值');
title('用求取极大极小值方法获取包络曲线图')
set(gcf,'color','w');

用倒谱法来计算语音信号频谱的包络线

1.概述

语音信号频谱的包络线对语音分析来说是比较重要的,它反映了人类发声器官的共振结构,从频谱的包络可提取共振峰参数(频率和带宽)。在语音分析中常用倒谱方法来提取语音信号频谱的包络线。

clear all; clc; close all;
y=load('su1.txt');                            % 读入数据
fs=16000; nfft=1024;                          % 采样频率和FFT的长度
time=(0:nfft-1)/fs;                           % 时间刻度
nn=1:nfft/2; ff=(nn-1)*fs/nfft;               % 计算频率刻度
Y=log(abs(fft(y)));                           % 取幅值的对数
z=ifft(Y);                                    % 按式(4-3-16)求取倒谱
mcep=29;                                      % 分离声门激励脉冲和声道冲击响应
zy=z(1:mcep+1);
zy=[zy' zeros(1,1024-2*mcep-1) zy(end:-1:2)']; % 构建声道冲击响应的倒谱序列
ZY=fft(zy);                                   % 计算声道冲击响应的频谱
% 作图
plot(ff,Y(nn),'k'); hold on;                  % 画出信号的频谱图
plot(ff,real(ZY(nn)),'k','linewidth',2.5);    % 画出包络线
grid; hold off; ylim([-4 5]);
title('信号频谱和声道冲击响频谱(频谱包络)')
ylabel('幅值'); xlabel('频率/Hz'); 
legend('信号频谱','频谱包络')
set(gcf,'color','w');

获取代码请关注MATLAB科研小白的个人公众号(即文章下方二维码),并回复信号处理中简单实用的方法本公众号致力于解决找代码难,写代码怵。各位有什么急需的代码,欢迎后台留言~不定时更新科研技巧类推文,可以一起探讨科研,写作,文献,代码等诸多学术问题,我们一起进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1714824.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OrangePi Kunpeng Pro 开发板测评 | AI 边缘计算 大模型部署

0 前言 此次很幸运能够参与 OrangePi Kunpeng Pro 开发板的测评,感谢 CSDN 给予这次机会。 香橙派联合华为发布了基于昇腾的 OrangePi Kunpeng Pro 开发板,具备 8TOPS 的 AI 算力,能覆盖生态开发板者的主流应用场景,具备完善的配…

这些项目,我当初但凡参与一个,现在也不至于还是个程序员

10年前,我刚开始干开发不久,我觉得这真是一个有前景的职业,我觉得我的未来会无限广阔,我觉得再过几年,我一定工资不菲。于是我开始像很多大佬说的那样,开始制定职业规划,并且坚决执行。但过去这…

使用C语言openssl库实现 RSA加密 和 消息验证

Q:什么是RSA? A:RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,是最早的一种用于公开密钥加密和数字签名的算法。它使用一对公钥(public key)和私钥(private key&…

小阿轩yx-Shell编程之正则表达式与文本处理器

小阿轩yx-Shell编程之正则表达式与文本处理器 正则表达式 (RegularExpression,RE) 正则表达式概述 正则表达式的定义 又称 正规表达式常规表达式 代码中常简写为 regex、regexp 或 RE 正则表达式 使用单个字符串来描述、匹配一系列符…

社会网络,生态网络,贸易网络,复杂网络边介数蓄意和随机攻击(增边策略)

网络分析工具使用说明 简介 本工具是一个用于进行网络分析的客户端应用。用户可以加载包含网络边信息的Excel文件,根据设定的百分比增加网络边,并将结果导出为新的Excel文件。以下是详细的使用说明。 使用步骤 1. 加载输入文件 输入文件: 输入文件…

大数据技术分享 | Kylin入门系列:基础介绍篇

Kylin入门教程 在大数据时代,如何高效地处理和分析海量数据成为了企业面临的挑战之一。Apache Kylin作为一个开源的分布式分析引擎,提供了Hadoop之上的SQL查询接口及多维分析(OLAP)能力,使得对超大规模数据集的分析变…

4月平板电脑行业线上销售数据分析

由于全球科技发展趋势,如AI技术的应用,以及厂商新品发布计划;同时,平板电脑作为个人电脑的延伸产品,其便携性和生产力相较于手机具有明显优势,这也为行业的进一步发展提供了动力。 据鲸参谋数据统计&#…

【PB案例学习笔记】-12秒表实现

写在前面 这是PB案例学习笔记系列文章的第11篇,该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习,提高编程技巧,以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码,小凡都上传到了gite…

安卓赤拳配音v1.0.2Ai配音神器+百位主播音色

Ai配音神器 本人自用版本!超级稳定!百位主播音色 登陆即可用 链接:https://pan.baidu.com/s/1WVsrYZqLaPAriHMMLMdPBg?pwdz9ru 提取码:z9ru

如何编写高效的单片机代码?

单片机的程序比软开少一些,真正想编写出高效的代码,还是要积累很多年的。 在做研发工程师的10年里,我经历过几个公司,看过很多工程师写的代码,但真正能让我跪着看完的,极少。哪怕是大厂工程师,也…

装机必备——截图软件PixPin安装教程

装机必备——截图软件PixPin安装教程 软件下载 软件名称:PixPin 1.5 软件语言:简体中文 软件大小:30.1M 系统要求:Windows7或更高, 64位操作系统 硬件要求:CPU2GHz ,RAM2G或更高 下载通道①迅…

断开自定义模块与自定义库的链接

断开自定义模块与自定义库的链接 1、断开模块与库的链接 1、断开模块与库的链接 如果摸个库文件添加到模型中,无法“Disable Link”时,可以使用save_system命令进行断开到模型中用户定义的库模块的链接; 参考链接: 传送门 save…

软件无线电学习-发射机体系结构

本文知识内容摘自《软件无线电原理和应用》 软件无线电主要由发射机和接收机两大部分组成。软件无线电发射机的主要功能是把需发射或传输的用户信息(话音、数据或图像)经基带处理(完成诸如FM、AM、FSK、PSK、MSK、QAM 等调制)和上变频,调制到规定的载频(中心频率)上…

leetCode-hot100-数组专题之子数组+二维数组

数组专题之子数组二维数组 子数组238.除自身以外数组的乘积560.和为K的子数组 二维数组48.旋转图像 子数组 数组的子数组问题是算法中常见的一类问题,通常涉及到数组的连续元素。在解决这类问题时,常用的方法有前缀和、滑动窗口、双指针,分治…

SAP 没有项目类别表存在(表 T184L LF LEIH CHSP)

在项目上,客户在废品出库的时候,出现这个报错 查了相关资料,是因为后台确少配置:IMG-后勤执行-装运-交货-在交货时定义项目类别确定

敏感数据的授权和传输加密解决方案

需求背景:解决敏感数据的访问授权和安全传输。 KSP密钥管理系统结合USB Key实现CA证书签发的过程可以大致分为以下几个步骤: 1. 生成密钥对: 用户首先使用USB Key生成一对密钥,包括公钥和私钥。公钥用于加密和验证数字签名&…

Keil5 ~STM32报错Solutions#1

一、error: #268: declaration may not appear after executable statement in block

STM32的时钟介绍

目录 前言1. 简介1.1 时钟是用来做什么的1.2 时钟产生的方式 2. 时钟树的组成2.1 时钟源2.1.1 内部时钟2.1.2 外部时钟 2.2 PLL锁相环2.3 SYSCLK2.4 AHB和HCLK2.5 APB和PCLK2.6 总结 3. STM32时钟的如何进行工作4.我的疑问4.1 使用MSI和HSI有什么区别吗?4.2 MSI的频…

tensorrt输出结果为nan的解决方案

系统环境: ubuntu20.04 python3.9 cuda11.8 cudnn8.9.7.29 torch1.13.1cu117(pip install torch1.13.1) 1.针对cuda版本查了一下trt支持版本,发现V10和V8版本都支持 本着用新不用旧标准,果断下载了8.6&#xff0c…

【4.vi编辑器使用(下)】

一、vi编辑器的光标移动 二、vi编辑器查找命令 1、命令::/string 查找字符串 n:继续查找 N:反向继续查找 /^the 查找以the开头的行 /end 查找以 查找以 查找以结尾的行 三、vi编辑器替换命令 1、语法: : s[范围,范围]str1/str2[g] g表示全…