Fraunhofer goVISCAN:多光谱非接触生命体征传感器的座舱潜力

9通道微透镜阵列实现 1 米距离心率/呼吸/血氧检测

技术信息

核心创新

goVISCAN 是一个多光谱快照相机,通过 9 个微透镜同时捕获多个波长的光,实现非接触生命体征检测:

参数 数值
尺寸 10 × 7.5 × 2.5 cm
视场角 40°
工作距离 70cm - 130cm
传感器 1.25 MP 共享传感器
微透镜阵列 3×3(9个通道)
光谱范围 蓝/绿/红/近红外
内置光源 LED 补光
检测参数 心率、呼吸率、血氧饱和度

精度验证(12人试点研究)

参数 参考设备 平均误差
呼吸率 指夹血氧仪 1.3 次/分
心率 指夹血氧仪 2.8 次/分
血氧饱和度 指夹血氧仪 3.8 个百分点

技术架构

多光谱 rPPG 原理

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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
"""
goVISCAN 多光谱 rPPG(远程光电容积描记)原理复现

核心原理:
1. 血液脉动导致皮肤亮度微小变化
2. 不同波长对血液的吸收/反射特性不同
3. 多通道同时采集 → 信噪比提升 → 运动鲁棒性

对比传统单光谱 rPPG:
- 传统:RGB 三通道,受环境光照影响大
- goVISCAN:9 通道(含近红外),光照鲁棒性强
"""

import numpy as np
from typing import Tuple


class MultispectralRPPG:
"""
多光谱 rPPG 信号提取

模拟 goVISCAN 的 9 通道多光谱采集
"""

# 9 个通道的中心波长 (nm)
WAVELENGTHS = {
'ch1': 450, # 蓝
'ch2': 470, # 蓝
'ch3': 505, # 青绿
'ch4': 530, # 绿
'ch5': 565, # 黄绿
'ch6': 585, # 橙
'ch7': 625, # 红
'ch8': 660, # 深红
'ch9': 850, # 近红外
}

# 血红蛋白吸收系数(近似值,单位 cm^-1)
# HbO2(氧合血红蛋白)和 Hb(脱氧血红蛋白)
HEMOGLOBIN_ABSORPTION = {
'ch1': (8.0, 8.5), # (HbO2, Hb)
'ch2': (7.0, 7.5),
'ch3': (4.5, 5.0),
'ch4': (3.0, 3.5),
'ch5': (2.0, 2.5),
'ch6': (1.5, 2.0),
'ch7': (0.8, 1.2),
'ch8': (0.5, 1.0),
'ch9': (0.3, 0.2), # 近红外:HbO2 > Hb(反转)
}

def __init__(self, fps=30, num_channels=9):
self.fps = fps
self.num_channels = num_channels

def simulate_ppg_signal(self, heart_rate=72,
breathing_rate=16,
spo2=98, duration=10):
"""
模拟多光谱 PPG 信号

Args:
heart_rate: 心率 (bpm)
breathing_rate: 呼吸率 (次/分)
spo2: 血氧饱和度 (%)
duration: 持续时间 (秒)

Returns:
signals: shape=(num_channels, num_samples)
"""
num_samples = int(self.fps * duration)
t = np.linspace(0, duration, num_samples)

# 心率基频
hr_freq = heart_rate / 60.0 # Hz
# 呼吸基频
br_freq = breathing_rate / 60.0 # Hz

signals = np.zeros((self.num_channels, num_samples))

for i, (ch, wl) in enumerate(self.WAVELENGTHS.items()):
# 血红蛋白吸收
hbo2_abs, hb_abs = self.HEMOGLOBIN_ABSORPTION[ch]

# 氧合度对吸收的影响
actual_hbo2_abs = hbo2_abs * (spo2 / 100.0)
actual_hb_abs = hb_abs * ((100 - spo2) / 100.0)
total_abs = actual_hbo2_abs + actual_hb_abs

# PPG 信号 = 心率脉动 + 呼吸调制 + 噪声
cardiac = np.sin(2 * np.pi * hr_freq * t)
respiratory = 0.3 * np.sin(2 * np.pi * br_freq * t)
noise = 0.1 * np.random.randn(num_samples)

# 通道间差异:不同波长对血液体积变化敏感度不同
sensitivity = total_abs / max(
self.HEMOGLOBIN_ABSORPTION['ch4']
)

signals[i, :] = (
sensitivity * (cardiac + respiratory) + noise
)

return signals

def extract_heart_rate(self, signals):
"""
从多光谱信号提取心率

使用多通道融合 + FFT

Args:
signals: shape=(num_channels, num_samples)

Returns:
hr: 心率 (bpm)
"""
# 方法:对每个通道做 FFT,然后融合
freqs = np.fft.rfftfreq(signals.shape[1], 1/self.fps)

# 去趋势
signals_detrended = signals - np.mean(
signals, axis=1, keepdims=True
)

# 每个通道的频谱
spectra = np.abs(
np.fft.rfft(signals_detrended, axis=1)
)

# 多通道融合:取加权平均频谱
# 权重:绿光通道(对血液最敏感)
weights = np.ones(self.num_channels)
weights[3] = 2.0 # ch4 (530nm 绿)
weights[4] = 1.5 # ch5
weights /= weights.sum()

fused_spectrum = np.average(spectra,
axis=0,
weights=weights)

# 在心率范围 (0.7-3.5 Hz = 42-210 bpm) 扻最大值
hr_mask = (freqs > 0.7) & (freqs < 3.5)
hr_indices = np.where(hr_mask)[0]

if len(hr_indices) > 0:
peak_idx = hr_indices[
np.argmax(fused_spectrum[hr_indices])
]
hr = freqs[peak_idx] * 60
else:
hr = 0

return hr

def extract_breathing_rate(self, signals):
"""
从多光谱信号提取呼吸率

呼吸信号通过低频幅度调制传递

Returns:
br: 呼吸率 (次/分)
"""
# 提取低频包络
from scipy.signal import hilbert

# 取绿光通道(对血液最敏感)
green_signal = signals[3, :]

# Hilbert 变换取包络
analytic = hilbert(green_signal - np.mean(green_signal))
envelope = np.abs(analytic)

# FFT 找呼吸频率
freqs = np.fft.rfftfreq(len(envelope), 1/self.fps)
spectrum = np.abs(np.fft.rfft(envelope - np.mean(envelope)))

# 呼吸范围 (0.1-0.5 Hz = 6-30 次/分)
br_mask = (freqs > 0.1) & (freqs < 0.5)
br_indices = np.where(br_mask)[0]

if len(br_indices) > 0:
peak_idx = br_indices[
np.argmax(spectrum[br_indices])
]
br = freqs[peak_idx] * 60
else:
br = 0

return br

def estimate_spo2(self, signals):
"""
估算血氧饱和度

利用红光和近红外通道的比值
SpO2 = f(AC_red/DC_red) / (AC_nir/DC_nir)

Returns:
spo2: 血氧饱和度 (%)
"""
# 红光通道 (660nm)
red_signal = signals[7, :]
# 近红外通道 (850nm)
nir_signal = signals[8, :]

# AC 分量(脉动)
red_ac = np.std(red_signal)
nir_ac = np.std(nir_signal)

# DC 分量(直流)
red_dc = np.mean(red_signal)
nir_dc = np.mean(nir_signal)

# 比值
if red_dc > 0 and nir_dc > 0 and nir_ac > 0:
ratio = (red_ac / red_dc) / (nir_ac / nir_dc)
# 经验公式(简化版)
spo2 = 110 - 25 * ratio
spo2 = np.clip(spo2, 70, 100)
else:
spo2 = 0

return spo2


# ========== 测试 ==========

if __name__ == "__main__":
rppg = MultispectralRPPG(fps=30, num_channels=9)

# 模拟信号
np.random.seed(42)
true_hr = 72
true_br = 16
true_spo2 = 98

signals = rppg.simulate_ppg_signal(
heart_rate=true_hr,
breathing_rate=true_br,
spo2=true_spo2,
duration=10
)

# 提取参数
est_hr = rppg.extract_heart_rate(signals)
est_br = rppg.extract_breathing_rate(signals)
est_spo2 = rppg.estimate_spo2(signals)

print(f"=== goVISCAN 多光谱 rPPG 模拟结果 ===")
print(f" 设定心率: {true_hr} bpm | 检测: {est_hr:.1f} bpm | "
f"误差: {abs(est_hr-true_hr):.1f}")
print(f" 设定呼吸: {true_br}/min | 检测: {est_br:.1f}/min | "
f"误差: {abs(est_br-true_br):.1f}")
print(f" 设定SpO2: {true_spo2}% | 检测: {est_spo2:.1f}% | "
f"误差: {abs(est_spo2-true_spo2):.1f}")
print(f"\n goVISCAN 论文报告误差:")
print(f" 呼吸: 1.3/min | 心率: 2.8 bpm | SpO2: 3.8%")

座舱应用潜力

从医疗到汽车的迁移

医疗场景 汽车座舱场景 挑战
床旁监测 驾驶员监测 振动、光照变化
70-130cm 距离 60-80cm 距离 距离更近但角度变化
静态患者 运动驾驶员 运动伪影更严重
室内恒定光照 日夜变化光照 光照范围极大
12人试点 全人群适用 皮肤色调泛化

对比传统 rPPG 方案

方案 通道数 波长范围 鲁棒性 量产状态
传统 RGB rPPG 3 R/G/B ⚠️ 光照敏感 研究阶段
goVISCAN 9 450-850nm ✅ 多光谱融合 医疗验证
红外摄像头 rPPG 1-2 850/940nm ⚠️ 仅红外 部分量产
60GHz 雷达 - - ✅ 不受光照影响 量产

座舱集成方案

对 IMS 开发的启示

1. 多光谱比单光谱更鲁棒

goVISCAN 的核心优势是9 通道同时采集,通过多光谱融合克服了传统 rPPG 的光照敏感性。对 IMS 的启示:

  • 考虑在 DMS 摄像头中增加多光谱通道
  • RGB-IR 传感器(如 OV2311)已支持 2 通道,但远不如 9 通道

2. 10×7.5×2.5cm 可以嵌入顶控台

goVISCAN 的尺寸(10×7.5×2.5cm)与汽车顶控台相当,可以集成到 overhead console 中。

3. 血氧检测在座舱中的价值

应用场景 SpO2 检测价值
疲劳驾驶 低 SpO2 与疲劳相关
突发疾病 心脏/呼吸问题导致 SpO2 下降
酒驾检测 酒精影响呼吸和血氧
高原驾驶 高海拔低氧环境监测

4. 开发路线建议

阶段 时间 目标 方案
Phase 1 0-6月 RGB-IR rPPG 现有 DMS 摄像头 + rPPG 算法
Phase 2 6-12月 多通道 rPPG 评估多光谱传感器方案
Phase 3 12-24月 goVISCAN 类似方案 9 通道多光谱定制
Phase 4 24-36月 融合生命体征 rPPG + 雷达 + 座椅传感器

结论

Fraunhofer goVISCAN 证明了多光谱非接触生命体征检测在 1 米距离可靠工作。虽然设计用于医疗场景,但其技术原理可直接迁移到汽车座舱——特别是驾驶员健康监测和突发疾病检测。

对 IMS 开发而言,多光谱 rPPG 是传统摄像头和雷达之间的有力补充,可以在不需要额外硬件的情况下增加血氧检测能力,为 Euro NCAP 2026/2027 的驾驶员健康监测要求提供技术储备。


参考链接: