使用 PPG(光电容积描记图)估计心率和 SpO2 水平(Matlab代码实现)

 💥💥💞💞欢迎来到本博客❤️❤️💥💥

🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。

⛳️座右铭:行百里者,半于九十。

📋📋📋本文目录如下:🎁🎁🎁

目录

💥1 概述

📚2 运行结果

🎉3 参考文献

🌈4 Matlab代码实现


💥1 概述

使用PPG(光电容积描记图)技术可以准确估计心率和SpO2水平。PPG是一种非侵入性的生物测量技术,通过测量血液在皮肤表面的光吸收变化来获取心率和氧饱和度信息。

在测量过程中,通过将940纳米和660纳米的波长光照射到皮肤上,PPG设备可以捕捉到光的反射和吸收情况。血红蛋白的吸收特性使得在心跳时血液的光吸收量发生变化,这可以用来推测心率。另外,氧合血红蛋白和脱氧血红蛋白对不同波长光的吸收比例不同,因此可以根据这种差异来估计SpO2水平。

为了提高精度,需要稳定的信号质量和准确的数据处理方法。常见的方法包括滤波、峰值检测、时域和频域分析等。通过这些处理步骤,可以得到准确可靠的心率和SpO2水平估计结果。

此外,还有一些关键的注意事项和技术细节需要考虑。例如,保持被测物体静止以避免运动伪影,确保PPG传感器正确贴合皮肤的位置,以及抵御环境光干扰等。这些因素都能够对测量结果产生影响。

总的来说,PPG是一种非常有用的技术,可以在非侵入性和方便的条件下估计心率和SpO2水平。它在医疗护理、运动健康监测、睡眠质量评估等领域具有广泛应用前景,并为人们提供了更好的生物监测和健康管理手段。

📚2 运行结果

部分代码:

%% Data frame
for n=1:fix((length(X)/(2*fs))-2)
y1=X(n*fs:(n*fs+FFT_size-1),1); %RED
y2=X(n*fs:(n*fs+FFT_size-1),2); %IR

%% FFT Transform RED
NFFT = FFT_size ; % Next power of 2 from length of y
Y1 = fft(y1,NFFT);
f1 = fs/2*linspace(0,1,NFFT/2+1);

figure(1)
plot(f1,abs(Y1(1:NFFT/2+1)));
axis([0.5 2.5 0 3e5])

%% FFT Transform IR
NFFT = FFT_size; % Next power of 2 from length of y
Y2 = fft(y2,NFFT);
f2 = fs/2*linspace(0,1,NFFT/2+1);

figure(2)
plot(f2,abs(Y2(1:NFFT/2+1)));
axis([0.5 2.5 0 2e5])
hold on

%% Find local maximum in RED spectrum

YY=abs(Y1(6:12));
local_max_i=1;
local_max=YY(1);
for i=2:(length(YY)-1)
    if local_max<(YY(i))
        local_max_i=i;
        local_max=YY(i);
    end    
end
pk_RED_i=6-1+local_max_i;

%% Find local maximum in IR spectrum

YY=abs(Y2(6:12));
local_max_i=1;
local_max=YY(1);
for i=2:(length(YY)-1)
    if local_max<(YY(i))
        local_max_i=i;
        local_max=YY(i);
    end    
end
pk_IR_i=6-1+local_max_i;

%% Heart rate
HEART_RATE(n) = f2(pk_IR_i)*60  %%In fact, using FFT limits the accuracy of heart rate estimation. See the points on f1/ f2 arrays and you know why. I wrote a peak detection algorithm for heart rate only. See the second .m file. 

%% SpO2 
R_RED = abs(Y1(pk_RED_i)/abs(Y1(1)));
R_IR = abs(Y2(pk_IR_i)/abs(Y2(1)));
R=R_RED/R_IR;
SpO2(n) = 104 - 28*R

end

%% Take average value of heart rate and SpO2
HR=sum(HEART_RATE(2:(length(HEART_RATE)-1)))/(length(HEART_RATE)-2);
S=sum(SpO2(2:(length(SpO2)-1)))/(length(SpO2)-2);
Heart_Rate=round(HR)
SpO2_Level=round(S)

%% Plot result
y1=X(:,1);
y2=X(:,2);

% Denoising
for i=1:(length(y1)-1)
    if ((y1(i+1)-y1(i))>50000)
        y1(i+1)=y1(i+1)+ 65100;
    elseif ((y1(i)-y1(i+1))>50000)
        y1(i+1)=y1(i+1)+65100;
    end
end

for i=1:(length(y2)-1)
    if ((y2(i+1)-y2(i))>50000)
        y2(i+1)=y2(i+1)+ 65100;
    elseif ((y2(i)-y2(i+1))>50000)
        y2(i+1)=y2(i+1)+65100;
    end
end

x=0:1:length(y1)-1;
plot(x,y1+3e5,'r');
hold on
plot(x,y2,'b');
legend('RED','IR');
legend('boxoff');
str1 = ['Heart rate = ',num2str(HR)];
text(length(y2)/2,max(y2)*4/5,str1);

%% Data frame
for n=1:fix((length(X)/(2*fs))-2)
y1=X(n*fs:(n*fs+FFT_size-1),1); %RED
y2=X(n*fs:(n*fs+FFT_size-1),2); %IR

%% FFT Transform RED
NFFT = FFT_size ; % Next power of 2 from length of y
Y1 = fft(y1,NFFT);
f1 = fs/2*linspace(0,1,NFFT/2+1);

figure(1)
plot(f1,abs(Y1(1:NFFT/2+1)));
axis([0.5 2.5 0 3e5])

%% FFT Transform IR
NFFT = FFT_size; % Next power of 2 from length of y
Y2 = fft(y2,NFFT);
f2 = fs/2*linspace(0,1,NFFT/2+1);

figure(2)
plot(f2,abs(Y2(1:NFFT/2+1)));
axis([0.5 2.5 0 2e5])
hold on

%% Find local maximum in RED spectrum

YY=abs(Y1(6:12));
local_max_i=1;
local_max=YY(1);
for i=2:(length(YY)-1)
    if local_max<(YY(i))
        local_max_i=i;
        local_max=YY(i);
    end    
end
pk_RED_i=6-1+local_max_i;

%% Find local maximum in IR spectrum

YY=abs(Y2(6:12));
local_max_i=1;
local_max=YY(1);
for i=2:(length(YY)-1)
    if local_max<(YY(i))
        local_max_i=i;
        local_max=YY(i);
    end    
end
pk_IR_i=6-1+local_max_i;

%% Heart rate
HEART_RATE(n) = f2(pk_IR_i)*60  %%In fact, using FFT limits the accuracy of heart rate estimation. See the points on f1/ f2 arrays and you know why. I wrote a peak detection algorithm for heart rate only. See the second .m file. 

%% SpO2 
R_RED = abs(Y1(pk_RED_i)/abs(Y1(1)));
R_IR = abs(Y2(pk_IR_i)/abs(Y2(1)));
R=R_RED/R_IR;
SpO2(n) = 104 - 28*R

end

%% Take average value of heart rate and SpO2
HR=sum(HEART_RATE(2:(length(HEART_RATE)-1)))/(length(HEART_RATE)-2);
S=sum(SpO2(2:(length(SpO2)-1)))/(length(SpO2)-2);
Heart_Rate=round(HR)
SpO2_Level=round(S)

%% Plot result
y1=X(:,1);
y2=X(:,2);

% Denoising
for i=1:(length(y1)-1)
    if ((y1(i+1)-y1(i))>50000)
        y1(i+1)=y1(i+1)+ 65100;
    elseif ((y1(i)-y1(i+1))>50000)
        y1(i+1)=y1(i+1)+65100;
    end
end

for i=1:(length(y2)-1)
    if ((y2(i+1)-y2(i))>50000)
        y2(i+1)=y2(i+1)+ 65100;
    elseif ((y2(i)-y2(i+1))>50000)
        y2(i+1)=y2(i+1)+65100;
    end
end

x=0:1:length(y1)-1;
plot(x,y1+3e5,'r');
hold on
plot(x,y2,'b');
legend('RED','IR');
legend('boxoff');
str1 = ['Heart rate = ',num2str(HR)];
text(length(y2)/2,max(y2)*4/5,str1);

🎉3 参考文献

文章中一些内容引自网络,会注明出处或引用为参考文献,难免有未尽之处,如有不妥,请随时联系删除。

[1]张列亮,朱娟,徐磊.光电容积脉搏波临床应用研究进展[J].临床麻醉学杂志, 2013, 29(11):3.DOI:CNKI:SUN:LCMZ.0.2013-11-040.

[2]王楠,王霞,付晓静,等.视频中提取光电容积脉搏波的盲信号估计方法[J].电子设计工程, 2017(3):5.DOI:CNKI:SUN:GWDZ.0.2017-03-043.

[3]喻思源,魏蔚.光电容积脉搏波描记法(photoplethysmography,PPG)用于评价术后疼痛程度可行性的研究[C]//全国青年麻醉学科医师学术论坛.2012.

🌈4 Matlab代码实现

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荔枝科研社

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值