对信号的峰值进行分析
Step1.
简单的寻找最大值点
load sunspot.dat
year=sunspot(:,1);
relNums=sunspot(:,2);
findpeaks(relNums,year);
xlabel('Year');
ylabel('Sunspot Number')
title('Find All Peaks');

图片.png
Step2.
计算峰值点的距离
findpeaks(relNums,year,'MinPeakProminence',40);
xlabel('Year');
ylabel('Sunspot Number')
title('Find Prominent Peaks');

图片.png
先用直方图分析
figure
[pks, locs] = findpeaks(relNums,year,'MinPeakProminence',40);
peakInterval = diff(locs);
hist(peakInterval);
grid on
xlabel('Year Intervals');
ylabel('Frequency of Occurrence')
title('Histogram of Peak Intervals (years)')
AverageDistance_Peaks = mean(diff(locs))

图片.png
Step3.
查看截止或者饱和信号的峰值点
load clippedpeaks.mat
figure
% Show all peaks in the first plot
ax(1) = subplot(2,1,1);
findpeaks(saturatedData);
xlabel('Samples')
ylabel('Amplitude')
title('Detecting Saturated Peaks')
% Specify a minimum excursion in the second plot
ax(2) = subplot(2,1,2);
findpeaks(saturatedData,'threshold',5)
xlabel('Samples');
ylabel('Amplitude')
title('Filtering Out Saturated Peaks')
% link and zoom in to show the changes
linkaxes(ax(1:2),'xy');
axis(ax,[50 70 0 250])

图片.png
可以通过增加门限进行设定,否则对于一个平坦的峰,上升沿的第一个点会被认为是峰值
step4.
测量峰值幅度
用ECG信号举例说明
load noisyecg.mat
t = 1:length(noisyECG_withTrend);
figure
plot(t,noisyECG_withTrend)
title('Signal with a Trend')
xlabel('Samples');
ylabel('Voltage(mV)')
legend('Noisy ECG Signal')
grid on

图片.png
step5.
去除信号趋势
[p,s,mu] = polyfit((1:numel(noisyECG_withTrend))',noisyECG_withTrend,6);
f_y = polyval(p,(1:numel(noisyECG_withTrend))',[],mu);
ECG_data = noisyECG_withTrend - f_y; % Detrend data
figure
plot(t,ECG_data); grid on
ax = axis; axis([ax(1:2) -1.2 1.2])
title('Detrended ECG Signal')
xlabel('Samples'); ylabel('Voltage(mV)')
legend('Detrended ECG Signal')

图片.png
下图是一个标准的ECG信号图

图片.png
Step6.
感兴趣的峰值点门限,ECG主要的三个部分,包括S波,Q波,R波
R波可以通过设定0.5mv的门限检出
[~,locs_Rwave] = findpeaks(ECG_data,'MinPeakHeight',0.5,...
'MinPeakDistance',200);
对于S波,要设置适当门限
ECG_inverted = -ECG_data;
[~,locs_Swave] = findpeaks(ECG_inverted,'MinPeakHeight',0.5,...
'MinPeakDistance',200);
然后标记出来如下
figure
hold on
plot(t,ECG_data);
plot(locs_Rwave,ECG_data(locs_Rwave),'rv','MarkerFaceColor','r');
plot(locs_Swave,ECG_data(locs_Swave),'rs','MarkerFaceColor','b');
axis([0 1850 -1.1 1.1]); grid on;
legend('ECG Signal','R-waves','S-waves');
xlabel('Samples'); ylabel('Voltage(mV)')
title('R-wave and S-wave in Noisy ECG Signal')

图片.png
为了定位Q波,先滤波,采用Savitzky-Golay滤波器
smoothECG = sgolayfilt(ECG_data,7,21);
figure
plot(t,ECG_data,'b',t,smoothECG,'r'); grid on
axis tight;
xlabel('Samples'); ylabel('Voltage(mV)');
legend('Noisy ECG Signal','Filtered Signal')
title('Filtering Noisy ECG Signal')

图片.png
查找Q波如下
[~,min_locs] = findpeaks(-smoothECG,'MinPeakDistance',40);
% Peaks between -0.2mV and -0.5mV
locs_Qwave = min_locs(smoothECG(min_locs)>-0.5 & smoothECG(min_locs)<-0.2);
figure
hold on
plot(t,smoothECG);
plot(locs_Qwave,smoothECG(locs_Qwave),'rs','MarkerFaceColor','g');
plot(locs_Rwave,smoothECG(locs_Rwave),'rv','MarkerFaceColor','r');
plot(locs_Swave,smoothECG(locs_Swave),'rs','MarkerFaceColor','b');
grid on
title('Thresholding Peaks in Signal')
xlabel('Samples'); ylabel('Voltage(mV)')
ax = axis; axis([0 1850 -1.1 1.1])
legend('Smooth ECG signal','Q-wave','R-wave','S-wave');

图片.png
查看噪声信号和平滑后哦信号的误差
% Values of the Extrema
[val_Qwave, val_Rwave, val_Swave] = deal(smoothECG(locs_Qwave), smoothECG(locs_Rwave), smoothECG(locs_Swave));
meanError_Qwave = mean((noisyECG_withTrend(locs_Qwave) - val_Qwave))
meanError_Rwave = mean((noisyECG_withTrend(locs_Rwave) - val_Rwave))
meanError_Swave = mean((noisyECG_withTrend(locs_Swave) - val_Swave))

图片.png
峰值分析
主要分析上升时间,下降时间等
avg_riseTime = mean(locs_Rwave-locs_Qwave); % Average Rise time
avg_fallTime = mean(locs_Swave-locs_Rwave); % Average Fall time
avg_riseLevel = mean(val_Rwave-val_Qwave); % Average Rise Level
avg_fallLevel = mean(val_Rwave-val_Swave); % Average Fall Level
helperPeakAnalysisPlot(t,smoothECG,...
locs_Qwave,locs_Rwave,locs_Swave,...
val_Qwave,val_Rwave,val_Swave,...
avg_riseTime,avg_fallTime,...
avg_riseLevel,avg_fallLevel)

图片.png
总结:
- 学会几个函数的使用
findpeaks, 查找峰值点
linkaxes, 关联子图的坐标轴
polyfit, 拟合
polyval,拟合后的应用
sgolayfilt,滤波器
deal, 输入到输出的赋值
helperPeakAnalysisPlot,peak峰值点绘图,内部函数看不到介绍
- 查找峰值点的一般方法
如何设置参数范围大小
针对ECG如何获取Q,R,S波峰位置