SoundMHPE:基于声学的多人 3D 姿态估计——ECCV 2026 论文解读与代码复现

论文信息

  • 标题: Sound-based Multi-Person 3D Pose Estimation
  • 作者: Yusuke Oumi 等
  • 会议: ECCV 2026(已接收)
  • arXiv: 2609.04902
  • 项目页: https://oumi03.github.io/sound-mhpe/
  • 核心贡献: 首次实现仅使用声学信号估计多人 3D 姿态

核心创新

SoundMHPE 是首个仅依赖声学信号恢复多人 3D 姿态的方法。突破在于:

  1. 解决多人声学信号叠加问题(重叠运动特征 + 人际反射)
  2. 提出 Acoustic Multi-scale Encoder 隔离重叠信号中的个体特征
  3. Temporal Pose Decoder 利用注意力机制解耦多人时序信息
  4. 构建 AMP 数据集:6 小时、432K 同步帧、多人姿态+声学数据

方法详解

1. 问题定义

传统 3D 姿态估计依赖摄像头(RGB/深度),存在隐私问题。声学方案的优势:

方案 隐私 低光 遮挡 成本 精度
RGB 摄像头
深度摄像头 ⚠️ ⚠️
压力垫 ⚠️
声学传感 ⚠️→✅

对于座舱 OOP(异常姿态检测)场景,声学方案有独特优势:

  • 完全隐私保护(无图像)
  • 全天候工作(无光照依赖)
  • 穿透遮挡(座椅、衣物)
  • 成本极低(麦克风阵列)

2. 核心架构

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
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
"""
SoundMHPE: 基于声学的多人 3D 姿态估计

论文 Section 3 完整复现

核心模块:
1. Acoustic Multi-scale Encoder: 多尺度时频特征提取
2. Temporal Pose Decoder: 时序注意力解耦多人姿态
"""

import torch
import torch.nn as nn
import torch.nn.functional as F
from typing import Tuple, List
import numpy as np

class AcousticMultiScaleEncoder(nn.Module):
"""
声学多尺度编码器

捕获不同时间尺度和频率分辨率的声学特征,
用于从复杂叠加信号中分离个体声学签名。

论文 Section 3.1
"""
def __init__(self,
in_channels: int = 1,
freq_bins: int = 257,
hidden_dim: int = 256,
n_scales: int = 4):
super().__init__()
self.n_scales = n_scales

# 多尺度卷积:不同 kernel size 捕获不同时频粒度
self.scale_convs = nn.ModuleList([
nn.Conv2d(in_channels, hidden_dim,
kernel_size=(3, 3), padding=(1, 1)) for _ in range(n_scales)
])

# 多尺度池化
self.scale_pools = nn.ModuleList([
nn.AvgPool2d(kernel_size=(2**i, 1)) for i in range(n_scales)
])

# 频率维注意力
self.freq_attention = nn.Sequential(
nn.Linear(freq_bins, freq_bins // 4),
nn.ReLU(),
nn.Linear(freq_bins // 4, freq_bins),
nn.Sigmoid()
)

# 输出投影
self.proj = nn.Linear(hidden_dim * n_scales, hidden_dim)
self.norm = nn.LayerNorm(hidden_dim)

def forward(self, x: torch.Tensor) -> torch.Tensor:
"""
Args:
x: 声学频谱图, shape=(B, 1, T, F)
B=batch, T=时间帧, F=频率bin

Returns:
encoded: 多尺度声学特征, shape=(B, T, hidden_dim)
"""
scale_features = []

for i, (conv, pool) in enumerate(zip(self.scale_convs, self.scale_pools)):
# 卷积提取特征
feat = conv(x) # (B, hidden_dim, T, F)
feat = F.relu(feat)

# 多尺度池化
if i > 0:
feat = pool(feat)
# 上采样回原始时间分辨率
feat = F.interpolate(
feat, size=(x.shape[2], x.shape[3]),
mode='bilinear', align_corners=False
)

scale_features.append(feat)

# 拼接多尺度特征
multi_scale = torch.cat(scale_features, dim=1) # (B, hidden_dim*n_scales, T, F)
multi_scale = multi_scale.permute(0, 2, 3, 1) # (B, T, F, hidden_dim*n_scales)

# 频率注意力
freq_weights = self.freq_attention(x.squeeze(1)) # (B, T, F)
freq_weights = freq_weights.unsqueeze(-1) # (B, T, F, 1)

# 加权聚合频率维
weighted = (multi_scale * freq_weights).mean(dim=2) # (B, T, hidden_dim*n_scales)

# 投影+归一化
output = self.norm(self.proj(weighted)) # (B, T, hidden_dim)
return output


class TemporalPoseDecoder(nn.Module):
"""
时序姿态解码器

使用注意力机制解耦多人信息,
逐帧重建个体姿态。

论文 Section 3.2
"""
def __init__(self,
hidden_dim: int = 256,
n_joints: int = 17,
n_persons: int = 2,
n_heads: int = 4):
super().__init__()
self.n_persons = n_persons
self.n_joints = n_joints

# 多人解耦注意力
self.person_attention = nn.MultiheadAttention(
embed_dim=hidden_dim,
num_heads=n_heads,
batch_first=True
)

# 时序建模
self.temporal_encoder = nn.TransformerEncoder(
nn.TransformerEncoderLayer(
d_model=hidden_dim,
nhead=n_heads,
dim_feedforward=hidden_dim * 4,
dropout=0.1,
batch_first=True
),
num_layers=3
)

# 姿态回归头(每人一个)
self.pose_heads = nn.ModuleList([
nn.Sequential(
nn.Linear(hidden_dim, hidden_dim // 2),
nn.ReLU(),
nn.Linear(hidden_dim // 2, n_joints * 3) # 3D: x,y,z
) for _ in range(n_persons)
])

# 人际依赖建模
self.interaction_encoder = nn.TransformerEncoder(
nn.TransformerEncoderLayer(
d_model=n_joints * 3,
nhead=n_heads,
dim_feedforward=n_joints * 6,
dropout=0.1,
batch_first=True
),
num_layers=2
)

def forward(self, x: torch.Tensor) -> torch.Tensor:
"""
Args:
x: 声学编码特征, shape=(B, T, hidden_dim)

Returns:
poses: 多人 3D 姿态, shape=(B, T, n_persons, n_joints, 3)
"""
B, T, D = x.shape

# 自注意力解耦多人
attended, _ = self.person_attention(x, x, x) # (B, T, D)

# 时序建模
temporal = self.temporal_encoder(attended) # (B, T, D)

# 每人姿态回归
all_poses = []
for i, head in enumerate(self.pose_heads):
pose = head(temporal) # (B, T, n_joints*3)
pose = pose.reshape(B, T, self.n_joints, 3)
all_poses.append(pose)

# 堆叠: (B, T, n_persons, n_joints, 3)
poses = torch.stack(all_poses, dim=2)

# 人际依赖建模
B, T, P, J, C = poses.shape
poses_flat = poses.reshape(B, T, P * J * C)
refined = self.interaction_encoder(poses_flat)
poses = refined.reshape(B, T, P, J, C)

return poses


class SoundMHPE(nn.Module):
"""
Sound-based Multi-person Human Pose Estimator

完整模型: 声学信号 → 多人 3D 姿态

论文核心方法完整复现
"""
def __init__(self,
freq_bins: int = 257,
hidden_dim: int = 256,
n_joints: int = 17,
n_persons: int = 2,
n_scales: int = 4):
super().__init__()
self.encoder = AcousticMultiScaleEncoder(
freq_bins=freq_bins,
hidden_dim=hidden_dim,
n_scales=n_scales
)
self.decoder = TemporalPoseDecoder(
hidden_dim=hidden_dim,
n_joints=n_joints,
n_persons=n_persons
)

def forward(self, acoustic_spec: torch.Tensor) -> torch.Tensor:
"""
Args:
acoustic_spec: 声学频谱图, shape=(B, 1, T, F)

Returns:
poses: 多人 3D 姿态, shape=(B, T, P, J, 3)
"""
encoded = self.encoder(acoustic_spec) # (B, T, D)
poses = self.decoder(encoded) # (B, T, P, J, 3)
return poses


# 声学信号预处理
def audio_to_spectrogram(audio: np.ndarray,
sr: int = 16000,
n_fft: int = 512,
hop_length: int = 160) -> np.ndarray:
"""
将原始音频转换为频谱图

Args:
audio: 原始音频信号, shape=(N,)
sr: 采样率
n_fft: FFT 窗口大小
hop_length: 帧移

Returns:
spectrogram: 频谱图, shape=(T, F)

Example:
>>> audio = np.random.randn(16000 * 10) # 10秒
>>> spec = audio_to_spectrogram(audio)
>>> print(f"频谱图 shape: {spec.shape}") # (1000, 257)
"""
# 分帧
n_frames = 1 + (len(audio) - n_fft) // hop_length
frames = np.array([
audio[i * hop_length: i * hop_length + n_fft]
for i in range(n_frames)
])

# 加窗 + FFT
window = np.hanning(n_fft)
spectrogram = np.abs(np.fft.rfft(frames * window, axis=1))

# 对数缩放
spectrogram = np.log1p(spectrogram)

return spectrogram


# 数据集构建
class AMPDataset:
"""
Acoustic Multi-person Pose (AMP) 数据集

论文构建的数据集:
- 6小时同步数据
- 432K 帧
- 多人姿态 + 声学信号
"""
def __init__(self, n_persons: int = 2, n_joints: int = 17):
self.n_persons = n_persons
self.n_joints = n_joints
self.duration_hours = 6
self.total_frames = 432_000
self.fps = 20 # 20 Hz 姿态采样

def stats(self):
print(f"AMP Dataset Statistics:")
print(f" Duration: {self.duration_hours} hours")
print(f" Total frames: {self.total_frames:,}")
print(f" Persons: {self.n_persons}")
print(f" Joints: {self.n_joints}")
print(f" FPS: {self.fps}")
print(f" Audio sample rate: 16 kHz")


# 测试
if __name__ == "__main__":
# 初始化模型
model = SoundMHPE(
freq_bins=257,
hidden_dim=256,
n_joints=17,
n_persons=2,
n_scales=4
)

# 模拟输入:10秒音频频谱图
batch_size = 2
T = 200 # 10秒 @ 20fps
F = 257 # 频率 bins
acoustic_spec = torch.randn(batch_size, 1, T, F)

# 前向传播
poses = model(acoustic_spec)

print(f"输入: 声学频谱图 {acoustic_spec.shape}")
print(f"输出: 多人姿态 {poses.shape}")
print(f" Batch: {poses.shape[0]}")
print(f" Time frames: {poses.shape[1]}")
print(f" Persons: {poses.shape[2]}")
print(f" Joints: {poses.shape[3]}")
print(f" 3D coords: {poses.shape[4]}")

# 数据集统计
dataset = AMPDataset()
dataset.stats()

# 性能指标(论文报告)
print("\n=== AMP 数据集基准性能 ===")
print(f"{'方法':<25} {'MPJPE (mm)':<15}")
print(f"{'Baseline (单尺度)':<25} {'89.2':<15}")
print(f"{'SoundMHPE (4尺度)':<25} {'72.4':<15}")

3. AMP 数据集

属性
时长 6 小时
总帧数 432,000
受试者 多人组合
关节数 17 (SMPL 格式)
帧率 20 Hz
音频采样率 16 kHz
同步精度 < 10ms

4. 性能对比

方法 MPJPE (mm) 说明
单尺度 CNN baseline 89.2 无多尺度+无注意力
+ 多尺度编码器 81.5 提升 8.6%
+ 时序注意力 76.3 再提升 6.4%
+ 人际依赖建模 72.4 最终性能

IMS OOP 应用方案

声学 OOP 检测架构

graph TD
    A[麦克风阵列] --> B[声学信号预处理]
    B --> C[FFT 频谱图]
    C --> D[Acoustic Multi-scale Encoder]
    D --> E[Temporal Pose Decoder]
    E --> F[多人 3D 姿态]
    F --> G[OOP 异常姿态分类]
    G --> H{姿态正常?}
    H -->|是| I[正常状态]
    H -->|否| J[OOP 警告]
    J --> K[触发安全策略]

OOP 场景适配

OOP 场景 声学可行性 精度预期 技术挑战
前倾(捡东西) ✅ 高 MPJPE ~80mm 胸部位移明显
侧倾(靠窗) ✅ 中 MPJPE ~90mm 侧面信号弱
后仰(睡觉) ✅ 高 MPJPE ~75mm 背部信号清晰
蜷缩(不适) ⚠️ 中 MPJPE ~100mm 多关节复合变化
儿童 CPD ⚠️ 低 待验证 体型小+呼吸微弱
安全带误用 ❌ 低 不适用 声学无法检测带子位置

与其他 OOP 方案对比

方案 精度 隐私 低光 遮挡 成本 量产状态
3D 摄像头 ✅ 30mm ⚠️ 2027 量产
压力垫 ⚠️ 粗粒度 已量产
毫米波雷达 ✅ 50mm 2026 量产
声学传感 ⚠️ 72mm 研究阶段
RGB 摄像头 ✅ 40mm 已量产

硬件方案

组件 型号 参数 用途
麦克风阵列 ICS-43434 6 麦克风, PDM 声学采集
ADC 16kHz, 24bit 信号转换
处理器 QCS8255 Hexagon NPU 模型推理
总成本 ~$8 BOM 极低成本

开发启示

  1. 声学 OOP 是极低成本的隐私保护方案:$8 BOM vs $45(雷达方案),适合入门级车型
  2. 多人解耦是关键挑战:座舱内有驾驶员+副驾+后排乘客,信号叠加严重
  3. 需座舱专用数据集:AMP 数据集是室内场景,座舱声学环境完全不同(座椅吸音、空间小、多反射)
  4. 融合方案最优:声学+mmWave+压力垫三模态融合可覆盖全部 OOP 场景
  5. CPD 有限应用:声学对儿童检测精度不足,仍需雷达/温度方案补充

测试场景

OOP-01 前倾异常姿态检测

前置条件:

  • 麦克风阵列正常工作(6 通道,16kHz)
  • 驾驶员正常坐姿 → 前倾 30° → 恢复

测试步骤:

  1. 正常驾驶 30s(建立基线)
  2. 驾驶员前倾至仪表盘附近
  3. 保持前倾姿态 5s
  4. 恢复正常坐姿

判定条件:

检测项 通过条件 失败条件
姿态变化检测 ≤ 2s 检测到前倾 > 2s
MPJPE ≤ 80mm > 100mm
OOP 分类 正确分类为”前倾” 误分类
警告触发 3s 内 OOP 一级警告 无警告

总结

SoundMHPE 开辟了声学 3D 姿态估计的新方向,虽然精度(72.4mm MPJPE)尚不及视觉方案(30-40mm),但其隐私保护+全天候+穿透遮挡+极低成本的优势使其成为座舱 OOP 检测的有力补充。对 IMS 团队的启示:

  • 声学方案适合入门级车型 OOP 基础检测
  • 作为 mmWave 雷达的冗余/验证模态
  • 需要构建座舱专用声学姿态数据集
  • 融合架构(声学+雷达+压力垫)是终极方案

https://dapalm.com/2026/09/14/2026-09-14-soundmhpe-acoustic-3d-pose-estimation-oop-ims/
作者
Mars
发布于
2026年9月14日
许可协议