丰田研究:声学共振腔无接触重建心电图的座舱启示

论文信息

项目 内容
标题 Listening to the Heart: Acoustic Resonator Reconstructs ECG Without Electrodes
发表 Communications Engineering (Nature Portfolio)
时间 2026年10月
机构 Toyota Research Institute of North America × USC × Northwestern University
核心 Helmholtz共振器 + 神经网络 = 无接触心电监测
新闻源 bioengineer.org (2026-10-10)

核心创新

丰田研究院联合USC和Northwestern发表了无接触心电监测概念验证:利用19世纪物理学家Helmholtz发明的共振腔原理,被动放大心脏跳动产生的次声波(50-120Hz),再通过神经网络将声学信号重建为ECG波形。

一句话总结: 用一个不接触身体的空气腔体被动放大心脏声音,再用AI把声音翻译成心电图。

为什么这很重要

当前座舱内的心脏监测方案都面临一个困境:

方案 原理 痛点
方向盘ECG 手指接触电极 驾驶员松手即失效,接触阻抗不稳定
rPPG摄像头 面部肤色微变 强光/暗光失效,肤色敏感
雷达感知 胸壁微振动 心率精度受限,无法提取ECG波形
声学共振 被动放大心音→AI重建ECG 无接触、无功耗放大、全天候

声学方案的关键优势:被动放大不需要供电,且信号不受光照影响。

方法详解

1. Helmholtz共振器物理原理

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
import numpy as np
from dataclasses import dataclass

@dataclass
class HelmholtzResonator:
"""
Helmholtz共振器物理模型

共振频率由腔体几何形状决定:
f = (c/2π) * sqrt(A/(V*L))

其中:
- c: 声速 (343 m/s at 20°C)
- A: 颈部截面积 (m²)
- V: 腔体体积 (m³)
- L: 颈部长度 (m)
"""
cavity_volume: float = 0.001 # V: 1L = 0.001 m³
neck_area: float = 3.14e-4 # A: 半径1cm的圆面积
neck_length: float = 0.02 # L: 2cm
sound_speed: float = 343.0 # c: 声速

@property
def resonant_frequency(self) -> float:
"""计算共振频率"""
f = (self.sound_speed / (2 * np.pi)) * \
np.sqrt(self.neck_area / (self.cavity_volume * self.neck_length))
return f

@property
def quality_factor(self) -> float:
"""
Q因子:共振峰锐度

Q = 2π × (储能/每周期耗能)
高Q → 窄带高增益 → 心音频段选择性放大
"""
# 简化估算
f = self.resonant_frequency
# 颈部空气质量
mass = 1.225 * self.neck_area * self.neck_length # ρ_air * A * L
# 弹簧常数
k = (1.225 * self.sound_speed**2 * self.neck_area**2) / self.cavity_volume
# 阻尼(辐射+热损耗简化)
R = 1.225 * self.sound_speed * 2 * np.pi * (self.neck_area**2) / (2 * np.pi * f)
Q = np.sqrt(mass * k) / R
return Q

def frequency_response(self, freqs: np.ndarray) -> np.ndarray:
"""
频率响应:在共振频率附近的增益

Returns:
gain_db: 各频率的增益(dB)
"""
f0 = self.resonant_frequency
Q = max(self.quality_factor, 1)
# 二阶共振传递函数
x = freqs / f0
gain = 1.0 / np.sqrt((1 - x**2)**2 + (x/Q)**2)
return 20 * np.log10(gain)


# 设计目标:50-120 Hz心音频段
resonator = HelmholtzResonator(
cavity_volume=0.003, # 3L腔体
neck_area=7.85e-5, # 半径0.5cm圆面积
neck_length=0.015 # 1.5cm颈部
)

f0 = resonator.resonant_frequency
Q = resonator.quality_factor
print(f"共振频率: {f0:.1f} Hz")
print(f"品质因子 Q: {Q:.1f}")
print(f"3dB带宽: {f0/Q:.1f} Hz")
print(f"峰值增益: {20*np.log10(Q):.1f} dB")

# 频率响应曲线
freqs = np.linspace(10, 200, 1000)
gain_db = resonator.frequency_response(freqs)
print(f"\n在50Hz增益: {gain_db[np.argmin(np.abs(freqs-50))]:.1f} dB")
print(f"在80Hz增益: {gain_db[np.argmin(np.abs(freqs-80))]:.1f} dB")
print(f"在120Hz增益: {gain_db[np.argmin(np.abs(freqs-120))]:.1f} dB")
print(f"在200Hz增益: {gain_db[np.argmin(np.abs(freqs-200))]:.1f} dB (抑制)")

2. 系统架构

3. 神经网络声学-ECG映射

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
import torch
import torch.nn as nn

class AcousticToECGNet(nn.Module):
"""
声学信号→ECG波形重建网络

论文核心创新:学习心音→心电的跨模态映射

架构:
- Encoder: 1D-CNN提取声学特征
- Transformer: 时序建模
- Decoder: 重建ECG波形
"""

def __init__(self,
audio_sample_rate: int = 1000,
ecg_sample_rate: int = 250,
d_model: int = 256,
n_heads: int = 8,
n_layers: int = 6):
super().__init__()

# 声学特征提取 (1D CNN)
self.audio_encoder = nn.Sequential(
nn.Conv1d(1, 32, kernel_size=15, stride=2, padding=7),
nn.BatchNorm1d(32),
nn.GELU(),
nn.Conv1d(32, 64, kernel_size=15, stride=2, padding=7),
nn.BatchNorm1d(64),
nn.GELU(),
nn.Conv1d(64, d_model, kernel_size=15, stride=2, padding=7),
nn.BatchNorm1d(d_model),
nn.GELU(),
)

# 位置编码
self.pos_encoding = self._create_pos_encoding(5000, d_model) # max 5000 tokens

# Transformer时序建模
encoder_layer = nn.TransformerEncoderLayer(
d_model=d_model,
nhead=n_heads,
dim_feedforward=d_model * 4,
dropout=0.1,
batch_first=True,
activation='gelu'
)
self.transformer = nn.TransformerEncoder(encoder_layer, n_layers)

# ECG波形解码
self.decoder = nn.Sequential(
nn.Linear(d_model, d_model // 2),
nn.GELU(),
nn.Linear(d_model // 2, 1),
nn.Tanh() # ECG信号归一化到[-1, 1]
)

# 下采样比例
self.downsample_ratio = audio_sample_rate // ecg_sample_rate

def _create_pos_encoding(self, max_len, d_model):
pe = torch.zeros(max_len, d_model)
position = torch.arange(0, max_len).float().unsqueeze(1)
div_term = torch.exp(
torch.arange(0, d_model, 2).float() *
(-np.log(10000.0) / d_model)
)
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
return pe.unsqueeze(0)

def forward(self, audio: torch.Tensor) -> torch.Tensor:
"""
Args:
audio: (B, T_audio) 声学信号

Returns:
ecg_pred: (B, T_ecg) 重建ECG波形
"""
# CNN特征提取
x = self.audio_encoder(audio.unsqueeze(1)) # (B, d_model, T_feat)
x = x.transpose(1, 2) # (B, T_feat, d_model)

# 位置编码
T = x.size(1)
x = x + self.pos_encoding[:, :T, :].to(x.device)

# Transformer时序建模
x = self.transformer(x)

# 解码ECG
ecg_pred = self.decoder(x) # (B, T_feat, 1)
ecg_pred = ecg_pred.squeeze(-1) # (B, T_feat)

return ecg_pred


# R-peak检测(从重建ECG提取心率)
class RPeakDetector(nn.Module):
"""
从重建ECG中检测R-peak(心搏事件)

方法:Pan-Tompkins改进 + 深度学习精修
"""

def __init__(self, fs: int = 250):
super().__init__()
self.fs = fs

# 带通滤波(5-15Hz,QRS频段)
nyq = fs / 2
self.bandpass = nn.Sequential(
nn.Conv1d(1, 1, kernel_size=15, padding=7, bias=False),
)

# 自适应阈值
self.threshold = 0.5

def forward(self, ecg: torch.Tensor) -> list:
"""
Args:
ecg: (B, T) ECG信号

Returns:
peaks: list of [(batch_idx, peak_location)]
"""
x = ecg.unsqueeze(1)
filtered = self.bandpass(x).squeeze(1)

# 梯度
diff = torch.diff(filtered, dim=1)
squared = diff ** 2

# 移动平均
kernel = torch.ones(1, 1, self.fs // 4) / (self.fs // 4)
moving_avg = nn.functional.conv1d(
squared.unsqueeze(1),
kernel.unsqueeze(0),
padding=self.fs // 8
).squeeze(1)[:, :squared.size(1)]

# 峰值检测
peaks = []
for b in range(ecg.size(0)):
signal = moving_avg[b].cpu().numpy()
above = signal > self.threshold * signal.max()

# 找上升沿
rising = np.where(np.diff(above.astype(int)) == 1)[0]
for idx in rising:
# 在窗口内找精确峰值
window = 20
start = max(0, idx)
end = min(len(filtered[b]), idx + window)
peak_idx = start + torch.argmax(filtered[b, start:end]).item()
peaks.append((b, peak_idx))

return peaks


# 测试
if __name__ == "__main__":
model = AcousticToECGNet()
detector = RPeakDetector()

# 模拟10秒声学输入
audio = torch.randn(2, 10000) # batch=2, 10s@1kHz
ecg = model(audio)
print(f"输入声学: {audio.shape}")
print(f"输出ECG: {ecg.shape}")

# R-peak检测
peaks = detector(ecg)
for b, p in peaks:
print(f"Batch {b}: R-peak at sample {p} ({p/250:.2f}s)")

# 计算心率
if len(peaks) > 1:
rr_intervals = np.diff([p for _, p in peaks]) / 250
hr = 60 / np.mean(rr_intervals)
print(f"估算心率: {hr:.1f} BPM")

4. 实验性能

论文报告的关键指标:

指标 数值 说明
心率误差 4.23 ± 4.50 BPM vs 参考ECG
R-peak时延 36.50 ± 53.17 ms 与电极ECG对比
频段范围 50-120 Hz 心音频段
共振方式 被动(无源) 无需供电

5. 与现有方案对比

方案 接触方式 精度 功耗 环境敏感度 成本
电极ECG 需接触 金标准 低 低 中
方向盘ECG 需手握 中 低 中 低
rPPG摄像头 无接触 中 高 高(光照) 中
雷达感知 无接触 中低 中 中 中高
声学共振 无接触 中 极低 低 低

IMS开发启示

1. 座舱心电监测新路径

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
# 座舱集成方案概念
class CabinAcousticECG:
"""
座舱声学心电监测集成方案

安装位置:座椅头枕或靠背
优势:
1. 无需身体接触(驾驶员无需佩戴任何设备)
2. 被动放大不耗电(共振腔物理特性)
3. 不受光照影响(暗光/强光均可工作)
4. 隐私保护(不采集图像)

挑战:
1. 车内噪声干扰(发动机/风噪/路噪)
2. 驾驶员移动导致信号丢失
3. 共振腔体积限制(需小型化)
4. 需要个性化校准
"""

def __init__(self):
# 噪声抑制策略
self.noise_sources = {
'engine': (20, 200), # 发动机噪声频段
'wind': (100, 1000), # 风噪频段
'road': (5, 50), # 路面振动频段
'cardiac': (50, 120), # 目标心音频段
}

def snr_estimation(self, signal, noise):
"""
信噪比估计

座舱内目标SNR需要 > 10dB
共振器增益约 20-30dB
车内背景噪声约 40-60dB SPL
心音强度约 30-40dB SPL(1m距离)
→ 增益后心音 50-70dB vs 噪声 40-60dB
→ SNR约 0-15dB,需进一步降噪
"""
signal_power = np.mean(signal**2)
noise_power = np.mean(noise**2)
snr_db = 10 * np.log10(signal_power / noise_power)
return snr_db

def adaptive_noise_cancellation(self, primary, reference):
"""
自适应噪声消除(LMS算法)

primary: 共振器输出(心音+噪声)
reference: 座舱麦克风参考噪声
"""
N = len(reference)
M = 32 # 滤波器阶数
w = np.zeros(M)
mu = 0.01 # 步长

output = np.zeros(N)
for n in range(M, N):
x = reference[n-M:n][::-1]
y = np.dot(w, x)
e = primary[n] - y
w = w + mu * e * x
output[n] = e

return output

2. 与现有DMS/OMS系统融合

3. 开发优先级建议

优先级 方向 理由
🔴 P0 共振腔小型化设计 车载3L腔体太大,需压缩到0.5L以内
🔴 P0 车内噪声鲁棒性验证 发动机/风噪可能完全淹没心音
🟡 P1 多模态融合策略 声学+rPPG+雷达三源融合
🟡 P1 个性化校准流程 不同体型/衣物影响声学耦合
🟢 P2 HRV特征提取 从R-peak序列计算时域/频域HRV
🟢 P2 心律异常分类 房颤/早搏等心律不齐检测

4. 具体硬件清单

组件 型号 参数 用途
共振腔 定制设计 0.5-3L, 50-120Hz共振 心音被动放大
麦克风 PCB 377B02 1/2英寸预极化 声压采集
ADC TI ADS1298 24-bit, 32kHz 高精度采样
处理器 QCS8255 Hexagon NPU 神经网络推理
参考ECG BIOPAC MP160 12导联 训练标签采集

5. 测试场景

AS-01 静态心电监测测试

前置条件:

  • 驾驶员正常坐姿,座椅调整到位
  • 车辆静止,发动机关闭
  • 共振腔安装于座椅头枕

测试步骤:

  1. 驾驶员就座,保持静坐30秒(建立基线)
  2. 记录声学信号和参考ECG
  3. 计算心率误差和R-peak时延

判定条件:

检测项 通过 失败
心率误差 ≤5 BPM >10 BPM
R-peak检测率 >90% <80%
HRV误差 ≤20ms >50ms

AS-02 动态驾驶测试

前置条件:

  • 车辆以60km/h匀速行驶
  • 空调关闭(先测无空调噪声)

测试步骤:

  1. 驾驶10分钟,记录声学信号
  2. 对比参考ECG设备
  3. 逐步加入空调/音响干扰

判定条件:

场景 心率误差要求 说明
静止关引擎 ≤5 BPM 最佳条件
60km/h关空调 ≤8 BPM 风噪加入
60km/h开空调 ≤10 BPM HVAC噪声加入
60km/h开音响 ≤10 BPM 声学干扰

技术路线图

与现有研究的关系

这项研究与2026年10月Nature Scientific Reports发表的”Reliable multimodal signals for in-vehicle heartbeat detection”形成互补:

方面 多模态心跳检测(Nature) 声学共振ECG(本文)
方法 ECG+PPG+相机+红外+热成像 单一声学传感
接触 需握方向盘+面部摄像头 完全无接触
输出 心率 ECG波形+R-peak
优势 多源冗余 被动/零功耗
劣势 系统复杂 单源鲁棒性弱

最佳策略: 将声学共振作为座舱生理监测的被动备选源,与雷达rPPG融合。

结论

丰田这项研究开辟了座舱心电监测的全新技术路径:

  1. 物理创新 — 19世纪Helmholtz共振器在2026年汽车座舱中重生
  2. AI创新 — 声学→ECG跨模态映射解决信号翻译问题
  3. 系统创新 — 被动零功耗放大,不受光照影响
  4. 距离量产 — 概念验证阶段,需解决车内噪声和体积问题

对IMS的启示: 声学共振ECG不应作为独立方案,而应作为多模态生理监测的一个被动增强通道,与雷达感知、rPPG、方向盘ECG形成冗余。Euro NCAP 2026虽未直接要求心电监测,但驾驶员健康监测(cardiac event detection)正在被讨论纳入2028+路线图。


论文来源:bioengineer.org (2026-10-10), Communications Engineering
InCabin Europe 2026 Barcelona 会议同期报道