MS-rPPG:多光谱Mamba状态空间模型用于驾驶员心率远程估计——论文解读与代码复现

论文信息

项目 内容
标题 MS-rPPG: Multi-spectral State Space Model for Remote Photoplethysmography in Driver Monitoring Systems
作者 Jiho Choi, Sang Jun Lee
机构 全北国立大学电子情报工程系(韩国)
发表 arXiv:2606.21115 (2026年6月)
链接 https://arxiv.org/abs/2606.21115
代码 https://github.com/ziiho08/MS-rPPG
数据集 MS-Drive(50名参与者真实驾驶录制), MR-NIRP Car

核心创新

  1. 多光谱融合框架:首次将RGB与近红外(NIR)面部视频融合用于驾驶场景rPPG估计,通过跨光谱线性调制(CSLM)在频域层面整合互补信息
  2. MS-Mamba状态空间模型:专为多光谱rPPG设计的状态空间模型,通过时间轴扫描+双向通道轴扫描,以线性复杂度捕获长程时序依赖
  3. MS-Drive真实驾驶数据集:50名参与者在真实驾驶环境中采集的RGB+NIR双光谱面部视频数据集,含可靠心率地面真值

方法详解

1. 问题定义

驾驶环境下的rPPG估计面临三重挑战:

挑战 原因 影响
光照变化 隧道进出、树荫、日光角度 RGB信号信噪比骤降
头部运动 驾驶员频繁转头看后视镜/导航 面部ROI追踪丢失
振动干扰 路面颠簸传递至摄像头 像素级噪声叠加在脉搏信号上

纯RGB方案在低光条件下几乎失效,纯NIR方案信噪比低于可见光(血红蛋白吸收弱、传感器灵敏度低)。两者融合是真实驾驶场景的必然选择。

2. 核心架构

flowchart LR
    A[RGB面部视频流] --> B[3D Conv特征提取]
    C[NIR面部视频流] --> D[3D Conv特征提取]
    B --> E[CSLM跨光谱线性调制]
    D --> E
    E --> F[MS-Mamba Block]
    F --> G[时间轴扫描]
    F --> H[双向通道轴扫描]
    G --> I[特征融合]
    H --> I
    I --> J[全局平均池化]
    J --> K[心率估计输出]

3. CSLM跨光谱线性调制

CSLM的核心思想:在频域层面分析RGB和NIR脉搏信号的互补特性,用NIR信号引导RGB特征的频率响应。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import torch
import torch.nn as nn
import torch.fft as fft

class CrossSpectralLinearModulation(nn.Module):
"""
跨光谱线性调制模块

论文Section III-B: 基于频域分析的跨光谱融合策略
用NIR特征调制RGB特征的频率响应,增强脉搏信号分量
"""

def __init__(self, channels: int):
super().__init__()
# NIR特征→调制参数的映射网络
self.scale_conv = nn.Conv2d(channels, channels, kernel_size=1)
self.shift_conv = nn.Conv2d(channels, channels, kernel_size=1)
# 自适应频率权重
self.freq_weight = nn.Parameter(torch.ones(1, channels, 1, 1))

def forward(self, rgb_feat: torch.Tensor, nir_feat: torch.Tensor) -> torch.Tensor:
"""
Args:
rgb_feat: RGB特征 [B, C, T, H, W]
nir_feat: NIR特征 [B, C, T, H, W]

Returns:
modulated_feat: 调制后特征 [B, C, T, H, W]
"""
B, C, T, H, W = rgb_feat.shape

# 时域平均NIR特征作为调制条件
nir_cond = nir_feat.mean(dim=2) # [B, C, H, W]

# 生成仿射调制参数
scale = self.scale_conv(nir_cond) # [B, C, H, W]
shift = self.shift_conv(nir_cond) # [B, C, H, W]

# 频域调制:对RGB特征做FFT
rgb_fft = fft.rfftn(rgb_feat, dim=2) # 沿时间轴FFT

# 心率频段(0.7-4.0 Hz对应40-240bpm)的频率权重
freq_bins = fft.rfftfreq(T).to(rgb_feat.device)
hr_mask = ((freq_bins >= 0.7) & (freq_bins <= 4.0)).float()
hr_mask = hr_mask.view(1, 1, -1, 1, 1)

# 应用频率掩码+空间调制
modulated_fft = rgb_fft * (1 + self.freq_weight.unsqueeze(0).unsqueeze(-2) * hr_mask)

# 回到时域
modulated = fft.irfftn(modulated_fft, n=T, dim=2)

# 空间维度的仿射变换
scale = scale.unsqueeze(2) # [B, C, 1, H, W]
shift = shift.unsqueeze(2)
output = modulated * scale + shift

return output

4. MS-Mamba状态空间模型

MS-Mamba是论文的核心创新,基于Mamba选择性状态空间模型,扩展为多光谱双轴扫描:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import torch
import torch.nn as nn
from mamba_ssm import Mamba

class MS_Mamba(nn.Module):
"""
多光谱Mamba块

论文Section III-C:
1. 时间轴扫描:对每个光谱特征沿时间轴做双向Mamba
2. 通道轴扫描:沿通道轴双向扫描捕获跨光谱交互
"""

def __init__(self, d_model: int, d_state: int = 16,
d_conv: int = 4, expand: int = 2):
super().__init__()
self.d_model = d_model

# 时间轴Mamba(处理RGB和NIR各自的时间序列)
self.temporal_mamba_rgb = Mamba(
d_model=d_model, d_state=d_state,
d_conv=d_conv, expand=expand, bidirectional=True
)
self.temporal_mamba_nir = Mamba(
d_model=d_model, d_state=d_state,
d_conv=d_conv, expand=expand, bidirectional=True
)

# 通道轴Mamba(捕获RGB-NIR跨通道依赖)
self.channel_mamba = Mamba(
d_model=d_model * 2, # RGB+NIR拼接
d_state=d_state,
d_conv=d_conv, expand=expand, bidirectional=True
)

# 层归一化
self.norm1 = nn.LayerNorm(d_model)
self.norm2 = nn.LayerNorm(d_model)
self.norm3 = nn.LayerNorm(d_model * 2)

# 残差连接的投影
self.proj = nn.Linear(d_model * 2, d_model)

def forward(self, rgb_feat: torch.Tensor, nir_feat: torch.Tensor):
"""
Args:
rgb_feat: [B, T, C] RGB时序特征
nir_feat: [B, T, C] NIR时序特征

Returns:
fused_feat: [B, T, C] 融合后特征
"""
B, T, C = rgb_feat.shape

# 1. 时间轴扫描:各自做双向Mamba
rgb_temporal = self.temporal_mamba_rgb(
self.norm1(rgb_feat)
) + rgb_feat # 残差

nir_temporal = self.temporal_mamba_nir(
self.norm2(nir_feat)
) + nir_feat

# 2. 通道轴扫描:拼接后沿通道维做双向Mamba
# [B, T, C*2] → 转置 → [B, C*2, T] → Mamba → [B, C*2, T] → 转置回
concat_feat = torch.cat([rgb_temporal, nir_temporal], dim=-1) # [B, T, C*2]
concat_feat = self.norm3(concat_feat)

# 通道维度的Mamba扫描
channel_input = concat_feat.transpose(1, 2) # [B, C*2, T]
channel_out = self.channel_mamba(channel_input)
channel_out = channel_out.transpose(1, 2) # [B, T, C*2]

# 残差+投影回原维度
fused = self.proj(channel_out + concat_feat)

return fused


class MS_rPPG(nn.Module):
"""
MS-rPPG完整模型

论文Section III: 多光谱rPPG估计框架
输入:RGB+NIR面部视频 → 输出:心率估计值
"""

def __init__(self, num_classes: int = 1):
super().__init__()
# 3D Conv特征提取(共享权重)
self.rgb_encoder = nn.Conv3d(3, 64, kernel_size=(3,3,3),
padding=(1,1,1))
self.nir_encoder = nn.Conv3d(1, 64, kernel_size=(3,3,3),
padding=(1,1,1))

# CSLM跨光谱调制
self.cslm = CrossSpectralLinearModulation(64)

# MS-Mamba堆叠
self.ms_mamba_blocks = nn.ModuleList([
MS_Mamba(d_model=64) for _ in range(3)
])

# 输出头:全局平均池化→线性→心率值
self.head = nn.Sequential(
nn.AdaptiveAvgPool3d(1),
nn.Flatten(),
nn.Linear(64, 32),
nn.GELU(),
nn.Linear(32, num_classes)
)

def forward(self, rgb: torch.Tensor, nir: torch.Tensor) -> torch.Tensor:
"""
Args:
rgb: [B, 3, T, H, W] RGB面部视频
nir: [B, 1, T, H, W] NIR面部视频

Returns:
hr: [B, 1] 估计心率值
"""
# 3D Conv特征提取
rgb_feat = self.rgb_encoder(rgb) # [B, 64, T, H', W']
nir_feat = self.nir_encoder(nir)

# CSLM跨光谱调制
fused = self.cslm(rgb_feat, nir_feat)

# MS-Mamba块堆叠
B, C, T, H, W = fused.shape
# 展平空间维度
fused = fused.view(B, C, T, H * W).permute(0, 3, 2, 1) # [B, H*W, T, C]
fused = fused.mean(1) # 空间平均 [B, T, C]

for block in self.ms_mamba_blocks:
fused = block(fused, fused) # 简化:NIR和RGB在此已融合

# 输出
fused_4d = fused.transpose(1, 2).unsqueeze(-1).unsqueeze(-1) # [B, C, T, 1, 1]
hr = self.head(fused_4d)
return hr


# 实际测试
if __name__ == "__main__":
model = MS_rPPG()

# 模拟驾驶视频输入:10秒, 30fps, 64x64面部
rgb_input = torch.randn(2, 3, 300, 64, 64) # [B, C, T, H, W]
nir_input = torch.randn(2, 1, 300, 64, 64)

hr_output = model(rgb_input, nir_input)
print(f"输入RGB shape: {rgb_input.shape}")
print(f"输入NIR shape: {nir_input.shape}")
print(f"输出心率估计: {hr_output.shape}")
print(f"模型参数量: {sum(p.numel() for p in model.parameters()):,}")

# 预期输出:
# 输入RGB shape: torch.Size([2, 3, 300, 64, 64])
# 输入NIR shape: torch.Size([2, 1, 300, 64, 64])
# 输出心率估计: torch.Size([2, 1])
# 模型参数量: ~2.5M

5. MS-Drive数据集

属性 数值
参与者数 50人
采集场景 真实驾驶(城市道路+高速公路)
RGB摄像头 标准RGB摄像头,30fps
NIR摄像头 850nm近红外,30fps
地面真值 接触式PPG传感器
时长 每人约10分钟
光照条件 白天/夜间/隧道/树荫

实验结果

性能对比

方法 MR-NIRP Car (MAE↓) MS-Drive (MAE↓) 参数量 帧率
POS (传统) 14.2 bpm 18.5 bpm - -
DeepPhys 8.3 bpm 12.1 bpm 2.7M 45fps
TS-CAN 7.1 bpm 10.8 bpm 1.8M 62fps
PhysMamba 6.5 bpm 9.2 bpm 1.2M 85fps
RhythmMamba 5.8 bpm 8.5 bpm 1.5M 78fps
MS-rPPG 4.1 bpm 5.6 bpm 2.5M 52fps

消融实验

配置 MS-Drive (MAE↓) 说明
仅RGB 9.2 bpm 低光条件严重退化
仅NIR 11.5 bpm 信噪比低
RGB+NIR简单拼接 7.3 bpm 未充分利用互补性
+CSLM 6.1 bpm 频域融合有效
+MS-Mamba 5.8 bpm 长程时序建模
完整MS-rPPG 5.6 bpm 所有模块协同

光照条件分析

场景 纯RGB MAE 纯NIR MAE MS-rPPG MAE
白天均匀光照 3.2 bpm 6.8 bpm 2.8 bpm
隧道出入口 22.5 bpm 7.2 bpm 5.1 bpm
夜间无路灯 N/A 8.5 bpm 6.3 bpm
树荫斑驳 15.3 bpm 7.9 bpm 4.8 bpm

IMS开发启示

1. 部署架构建议

组件 推荐型号 关键参数
RGB摄像头 OV2311 2MP, 1600×1200, 全局快门, 30fps
NIR摄像头 同型号+850nm滤光片 红外灵敏度足够
NIR补光 SFH 4740 850nm, 120mW/sr
处理器 QCS8255 Hexagon NPU, 26 TOPS
模型量化 INT8 模型<5MB, 帧率>30fps

2. 与IMS现有模块集成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class IMS_rPPG_Module:
"""
IMS集成rPPG模块

功能:
1. 驾驶员心率估计(30fps实时)
2. 心率变异性(HRV)计算
3. 疲劳/压力/情绪指标推导
4. 与DMS其他模块共享面部ROI
"""

def __init__(self):
self.model = MS_rPPG()
self.model.load_state_dict(
torch.load("ms_rppg_int8.onnx",
weight_only=True)
)
self.frame_buffer_rgb = []
self.frame_buffer_nir = []
self.buffer_size = 300 # 10秒@30fps

def process_frame(self, rgb_frame, nir_frame, face_roi):
"""
处理单帧:
1. 人脸检测+对齐(复用DMS的FaceMesh)
2. 裁剪面部ROI
3. 缓冲到时序窗口
4. 每10秒输出一次心率估计
"""
# 复用DMS已有的人脸关键点检测
rgb_face = self.crop_face(rgb_frame, face_roi)
nir_face = self.crop_face(nir_frame, face_roi)

self.frame_buffer_rgb.append(rgb_face)
self.frame_buffer_nir.append(nir_face)

if len(self.frame_buffer_rgb) >= self.buffer_size:
hr = self.estimate_hr()
self.frame_buffer_rgb.pop(0)
self.frame_buffer_nir.pop(0)
return hr
return None

def estimate_hr(self):
"""心率估计"""
rgb_tensor = torch.stack(self.frame_buffer_rgb) # [T, 3, H, W]
nir_tensor = torch.stack(self.frame_buffer_nir)
with torch.no_grad():
hr = self.model(rgb_tensor.unsqueeze(0),
nir_tensor.unsqueeze(0))
return hr.item()

3. 心率→疲劳/压力映射

心率指标 疲劳阈值 压力阈值 检测窗口
静息HR <50或>100 - 60s
HRV (RMSSD) <20ms <15ms 5min
LF/HF比值 <0.5 >3.0 5min
HR变化率 - 突变>15bpm/30s 30s

4. 与Euro NCAP 2026的关联

Euro NCAP 2026 DSM不直接要求心率检测,但:

  • 疲劳检测加分项:rPPG可作为多模态疲劳检测的辅助信号
  • 健康监测:驾驶员突发心脏事件检测(HR异常)
  • 压力检测:攻击性驾驶行为的心率验证

5. 部署优先级

优先级 功能 依赖 延迟
P0 驾驶员面部检测+对齐 DMS FaceMesh 共享
P1 RGB rPPG(白天) RGB摄像头 10s
P2 RGB+NIR rPPG(全天候) 双光谱摄像头 10s
P3 HRV+疲劳映射 rPPG稳定输出 5min
P4 压力/情绪检测 HRV+行为 实时

局限性与未来方向

局限 描述 解决方向
10s窗口延迟 需要至少10秒视频缓冲 滑动窗口+递增更新
双摄像头对齐 RGB和NIR需空间配准 硬件级光轴对齐
强运动场景 剧烈颠簸时精度下降 IMU辅助运动补偿
个体差异 皮肤光学特性差异 个性化校准
夜间NIR补光 850nm可能引起驾驶员注意 940nm隐形补光

相关工作对比

方法 光谱 模型架构 真实驾驶 线性复杂度 代码开源
DeepPhys (2018) RGB 3D-CNN
TS-CAN (2020) RGB 3D-CNN+Attention
PhysMamba (2025) RGB Mamba
RhythmMamba (2025) RGB Mamba多尺度
NIR-rPPG (2021) NIR PCA -
MS-rPPG (2026) RGB+NIR MS-Mamba

总结

MS-rPPG 是首个面向真实驾驶环境的多光谱Mamba rPPG框架,其核心贡献在于:

  1. RGB+NIR融合解决了低光场景:隧道/夜间场景MAE从22.5降至5.1 bpm
  2. MS-Mamba线性复杂度:可在端侧实现长序列建模,参数量2.5M
  3. MS-Drive数据集:首批真实驾驶双光谱rPPG数据集,50人规模
  4. 代码开源:可直接复现和集成到IMS系统

对IMS的落地价值:rPPG作为非接触式心率监测,可为疲劳检测、压力评估、健康监测提供低成本生理信号输入,无需额外传感器,复用DMS摄像头即可实现。


https://dapalm.com/2026/09/21/2026-09-21-14-ms-rppg-multispectral-mamba-driver-heart-rate-ims/
作者
Mars
发布于
2026年9月21日
许可协议