Matlab 从听诊器输入的心脏信号中寻找R峰值

Matlab 从听诊器输入的心脏信号中寻找R峰值,matlab,signals,signal-processing,Matlab,Signals,Signal Processing,通过硬件(主要是截止频率为100hz的放大器和低通滤波器)将使用听诊器测量的心跳信号发送到计算机的声卡。 现在,信号用截止100hz进行滤波。下面给出了查找峰值和每分钟拍数的代码。该代码仅适用于某些情况。 请帮我找出错误 clear all %input the signal into matlab [x,fs]=wavread('heartbeat.wav'); figure(1) subplot(2,1,1) x1=x(:,2); plot(x1(500:10000),'r-'); ti

通过硬件(主要是截止频率为100hz的放大器和低通滤波器)将使用听诊器测量的心跳信号发送到计算机的声卡。 现在,信号用截止100hz进行滤波。下面给出了查找峰值和每分钟拍数的代码。该代码仅适用于某些情况。 请帮我找出错误

clear all
%input the signal into matlab


[x,fs]=wavread('heartbeat.wav');
figure(1)
subplot(2,1,1)
x1=x(:,2);
plot(x1(500:10000),'r-');
title('unfiltered input x(n),cut off frequency 0.0270,passband 60hz,stopband 70hz');
ylabel('amplitude in volts');
xlabel('number of samples')
grid on

%to filter the signal above 50-60 hz
order=4;
h=fir1(4,0.0270,hamming(order+1));
y=filter(h,1,x1);
subplot(2,1,2)
plot(y(500:10000),'b-')
title('filtered output y(n),cut off frequency 0.0270,passband 50hz,stopband 60hz');
ylabel('amplitude in volts');
xlabel('number of samples')
grid on
%sound(y,5000)


th = max(y) * 0.9; %So here I'm considering anything less than 90% of the max as not a real peak... this bit really depends on your logic of finding peaks though which you haven't explained
Yth = zeros(length(y), 1);
Yth(y > th) = y(y > th);

Ydiff = diff(Yth);
Ydiff_logical = Ydiff < 0;
Ypeaks = diff(Ydiff_logical) == 1;

p=sum(Ypeaks)

N = length(y);
duration_seconds=N/fs;
duration_minutes=duration_seconds/60;
BPM=p/duration_minutes;
bpm=ceil(BPM)




figure(2)
%frequency response of the filter
freqz(h,1)
title('Frequency response');
xlabel('normalized frequency (X pi) radians per sample');
ylabel('Magnitude');
grid on;
全部清除
%将信号输入matlab
[x,fs]=wavread('heartbeat.wav');
图(1)
子地块(2,1,1)
x1=x(:,2);
图(x1(500:10000),'r-');
标题(“未滤波输入x(n),截止频率0.0270,通带60hz,阻带70hz”);
ylabel(“振幅单位为伏特”);
xlabel(“样本数”)
网格化
%对50-60 hz以上的信号进行滤波
顺序=4;
h=fir1(4,0.0270,汉明(订单+1));
y=滤波器(h,1,x1);
子地块(2,1,2)
图(y(500:10000),‘b-’)
标题(“滤波输出y(n),截止频率0.0270,通带50hz,阻带60hz”);
ylabel(“振幅单位为伏特”);
xlabel(“样本数”)
网格化
%声音(y,5000)
th=最大值(y)*0.9;%所以这里我认为任何小于最大值90%的都不是真正的峰值。。。这一点实际上取决于你寻找峰值的逻辑,尽管你没有解释
Yth=零(长度(y),1);
Yth(y>th)=y(y>th);
Ydiff=diff(Yth);
Ydiff_logical=Ydiff<0;
Ypeaks=diff(Ydiff_逻辑)==1;
p=总和(Ypeaks)
N=长度(y);
持续时间_秒=N/fs;
持续时间分钟=持续时间秒/60;
BPM=p/持续时间\分钟;
bpm=ceil(bpm)
图(2)
%滤波器的频率响应
freqz(h,1)
标题(“频率响应”);
xlabel(“每个样本的标准化频率(Xπ)弧度”);
伊拉贝尔(“震级”);
网格化;

没有示例数据,我只是猜测,但我认为阈值化无法获得正确的数据:很可能,每次峰值的高度都不同(我所说的“每次”指的是每次跑步和每个单独的节拍)。因此,如果您使用的峰值太高,它将错过一些真正的峰值,因为心跳太低。如果您使用的峰值太低,则可能会重复计算某些心跳,因为每个心跳都包含多个峰值(抱歉,我不记得这些峰值的名称)。事情很可能会随着时间的推移而改变,所以我甚至不会尝试为一个单独的记录设置阈值并让它过去,或者甚至从数据中导出阈值可能会有问题


你可能会在其他技术上有更好的运气,比如互相关或某种修改过的零交叉,或者专门为心跳的独特功能设计的东西(我想有什么东西。你搜索过文献吗?)。

这是如何实现我在这里发布的代码的:?还有一些示例数据显示了代码在哪些情况下不起作用essential@Dan对不起。。。。th=最大值(y)*0.9;只适用于一个信号,而对于其他信号,我必须将90%更改为60%(赌博)…给出一个屏幕截图,其中每分钟的节拍为1(这是不可能的!)。。阈值为0.2647,这对于检测峰值非常高。例子。数据。或者在dsp.stackexchange.com上询问您的问题是如何正确选择阈值。如果您发布了一小部分数据的图像,可能会有所帮助。这与你之前的问题不同,因为那是关于ECG的,这是一种完全不同的信号类型。我不能代表这里的任何人说话,但我肯定不熟悉听诊器的录音。因此,很难判断您的筛选是否合适。您还应该绘制检测心跳的位置,以检查阈值是否正常工作,而不仅仅是查看输出BPM。正如我在对OP的前一个问题的评论中提到的,一种流行的(尽管现在可能有点灰尘-可能有新的化身)算法是ECG QRS检测算法,它实际上使用了一对阈值和一些简单的自适应阈值更新规则,这些规则基于通常的心跳计时。