PressurePose+PressureNet:压力传感垫实现3D人体姿态估计,座舱OOP检测新方案

论文信息

项目 内容
论文标题 Bodies at Rest: 3D Human Pose and Shape Estimation From a Pressure Image Using Synthetic Data
作者 Mackenzie E. McDermott, Henry M. Clever, Roni O. Nasim
会议 CVPR 2020
DOI 10.1109/cvpr42600.2020.00625
OpenReview https://openreview.net/forum?id=7x6AkzZaFck
代码/数据 PressurePose Dataset (206K synthetic pressure images)

核心创新

首次提出完全基于合成数据训练的3D人体姿态和形状估计方法,从压力传感垫图像直接推断3D人体网格。

特性 说明
传感器 压力传感阵列 (pressure mat)
输出 3D人体网格 (mesh)
训练数据 206K 合成压力图像
测试数据 1,051 真实压力图像 (20人)
关键突破 纯合成训练→真实域迁移成功

方法详解

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
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
"""
PressurePose 数据生成管线
两阶段: 刚体→软体仿真

依赖: pybullet, trimesh, pytorch3d
数据集: 206K 合成压力图像
"""

import numpy as np
from dataclasses import dataclass
from typing import Tuple

@dataclass
class PressureMatConfig:
"""压力传感垫配置"""
mat_width: int = 192 # 传感单元数 (水平)
mat_height: int = 96 # 传感单元数 (垂直)
mat_physical_width: float = 0.48 # 物理宽度 (m)
mat_physical_height: float = 0.24 # 物理高度 (m)
cell_size: float = 0.0025 # 每个传感单元物理尺寸 (m)
force_range: float = 0.0 # 测力范围 (N)
max_force: float = 100.0 # 最大测力 (N)
sampling_rate: int = 10 # 采样率 (Hz)


class Stage1_RigidBodySimulator:
"""
阶段1: 刚体物理仿真

目标: 找到人体在软床/座椅上的稳定静止姿态
- 模拟关节化刚体人体模型
- 与软床和压力垫交互
- 使用物理引擎找到稳定平衡姿态
"""

def __init__(self, config: PressureMatConfig):
self.config = config
# 人体模型参数 (SMPL-X)
self.num_joints = 55 # SMPL-X 关芽数
self.num_vertices = 10475 # SMPL-X 顶点数

def generate_pose(self,
gender: str = 'neutral',
posture: str = 'supine',
limb_variation: float = 0.3) -> dict:
"""
生成一个稳定的静止姿态

Args:
gender: 'male', 'female', 'neutral'
posture: 'supine'(仰卧), 'lateral'(侧卧), 'prone'(俯卧)
limb_variation: 四肢位置变化幅度 (0-1)

Returns:
pose_dict: 包含关节角度、顶点、接触点
"""
# 基础姿态模板
base_poses = {
'supine': self._supine_template(),
'lateral': self._lateral_template(),
'prone': self._prone_template(),
}

# 随机扰动四肢
pose = base_poses[posture].copy()
if limb_variation > 0:
# 手臂: 肩关节旋转
pose[16:19] += np.random.uniform(
-0.5, 0.5, 3
) * limb_variation
pose[19:22] += np.random.uniform(
-0.5, 0.5, 3
) * limb_variation

# 腿部: 髋关节和膝关节
pose[1:4] += np.random.uniform(
-0.3, 0.3, 3
) * limb_variation
pose[4:7] += np.random.uniform(
-0.3, 0.3, 3
) * limb_variation

# 物理仿真找到稳定姿态
stable_pose = self._physics_relax(pose)

return {
'pose': stable_pose,
'gender': gender,
'posture': posture,
}

def _supine_template(self):
"""仰卧模板"""
pose = np.zeros(55 * 3) # SMPL-X pose参数
# 头部略偏
pose[12] = 0.1
# 手臂自然放置
pose[16] = -0.3 # 左肩外旋
pose[19] = 0.3 # 右肩外旋
return pose

def _lateral_template(self):
"""侧卧模板"""
pose = np.zeros(55 * 3)
pose[3] = 1.5 # 躯干旋转90度
pose[12] = 0.2 # 颈部
return pose

def _prone_template(self):
"""俯卧模板"""
pose = np.zeros(55 * 3)
pose[3] = 3.14 # 躯干旋转180度
return pose

def _physics_relax(self, pose, max_iter=1000):
"""物理引擎松弛,找到稳定姿态"""
# 简化版: 迭代降低势能
for _ in range(max_iter):
# 模拟重力、接触力
# 调整关节角度直到合力<阈值
pass
return pose


class Stage2_SoftBodySimulator:
"""
阶段2: 软体仿真生成压力图像

输入: 阶段1的稳定姿态
输出: 模拟压力传感垫图像 (192×96)
"""

def __init__(self, config: PressureMatConfig):
self.config = config
self.mat_shape = (config.mat_height, config.mat_width)

def generate_pressure_image(self, pose_dict: dict) -> np.ndarray:
"""
从3D人体姿态生成压力图像

Args:
pose_dict: 包含姿态、性别等

Returns:
pressure_img: (H, W) 压力值矩阵 0-max_force
"""
# 1. 从SMPL-X参数生成人体网格
mesh_vertices = self._get_mesh_vertices(pose_dict)

# 2. 软体变形计算接触面积
contact_points = self._compute_contact(mesh_vertices)

# 3. 模拟压力分布
pressure_img = self._simulate_pressure(contact_points, mesh_vertices)

return pressure_img

def _get_mesh_vertices(self, pose_dict):
"""从SMPL-X参数获取顶点"""
# 简化: 返回N×3顶点坐标
num_verts = 10475
return np.random.randn(num_verts, 3) * 0.5

def _compute_contact(self, vertices):
"""计算与压力垫的接触点"""
# 找z坐标最低的顶点
z_threshold = np.percentile(vertices[:, 2], 5)
contact_mask = vertices[:, 2] < z_threshold
return vertices[contact_mask]

def _simulate_pressure(self, contact_points, all_vertices):
"""软体压力仿真"""
pressure_img = np.zeros(self.mat_shape)

for point in contact_points:
# 将3D点映射到压力垫坐标
x, y, z = point
mat_x = int((x + self.config.mat_physical_width/2) /
self.config.cell_size)
mat_y = int((y + self.config.mat_physical_height/2) /
self.config.cell_size)

if 0 <= mat_x < self.config.mat_width and \
0 <= mat_y < self.config.mat_height:
# 高斯扩散
sigma = 3
for dx in range(-sigma*2, sigma*2+1):
for dy in range(-sigma*2, sigma*2+1):
xi, yi = mat_x+dx, mat_y+dy
if 0 <= xi < self.config.mat_width and \
0 <= yi < self.config.mat_height:
pressure_img[yi, xi] += \
np.exp(-(dx**2+dy**2)/(2*sigma**2))

# 归一化到力范围
pressure_img = np.clip(pressure_img, 0, self.config.max_force)
return pressure_img


class PressurePoseDataset:
"""PressurePose 数据集"""

def __init__(self, root_dir='/data/PressurePose'):
self.root = root_dir
self.config = PressureMatConfig()

# 数据集统计
self.total_images = 206_000 # 206K合成
self.train_split = 184_000 # 训练集
self.test_split = 22_000 # 测试集
self.real_images = 1_051 # 真实测试集
self.real_subjects = 20 # 20个真实受试者

def get_stats(self):
return {
'total_synthetic': self.total_images,
'train': self.train_split,
'test': self.test_split,
'real_test': self.real_images,
'real_subjects': self.real_subjects,
'postures': ['supine', 'lateral', 'prone', 'hands_behind_head'],
}


if __name__ == "__main__":
config = PressureMatConfig()

print("=" * 60)
print("PressurePose 数据生成管线")
print("=" * 60)

print(f"\n压力垫配置:")
print(f" 尺寸: {config.mat_width}×{config.mat_height} 传感单元")
print(f" 物理尺寸: {config.mat_physical_width}m × {config.mat_physical_height}m")
print(f" 单元大小: {config.cell_size*1000:.1f}mm")

# 阶段1: 刚体仿真
stage1 = Stage1_RigidBodySimulator(config)
pose = stage1.generate_pose(gender='neutral', posture='supine')
print(f"\n阶段1 - 刚体仿真:")
print(f" 姿态: {pose['posture']}")
print(f" 关节数: {stage1.num_joints}")

# 阶段2: 软体仿真
stage2 = Stage2_SoftBodySimulator(config)
pressure_img = stage2.generate_pressure_image(pose)
print(f"\n阶段2 - 软体仿真:")
print(f" 压力图像: {pressure_img.shape}")
print(f" 非零单元: {np.count_nonzero(pressure_img)}/{pressure_img.size}")
print(f" 最大压力: {pressure_img.max():.2f} N")
print(f" 总压力: {pressure_img.sum():.2f} N")

2. PressureNet 架构

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
"""
PressureNet: 从压力图像推断3D人体网格

架构: 两阶段(Mod1+Mod2) + 压力图重建(PMR)网络

输入: 压力图像 (96×192) + 性别
输出: 3D人体网格 (10475顶点×3坐标)

关键创新: PMR网络强制一致性
"""

import torch
import torch.nn as nn

class PressureMapReconstruction(nn.Module):
"""
PMR (Pressure Map Reconstruction) 网络

核心创新: 从预测的3D网格重建压力图
与输入压力图比较,强制一致性

作用: 防止模型将接触点误判为错误姿态
"""

def __init__(self, hidden_dim=128):
super().__init__()

# 从3D顶点特征预测压力图
self.vertex_to_pressure = nn.Sequential(
nn.Linear(10475 * 3, hidden_dim * 4),
nn.ReLU(),
nn.Linear(hidden_dim * 4, hidden_dim * 2),
nn.ReLU(),
nn.Linear(hidden_dim * 2, 96 * 192), # 压力图尺寸
nn.Sigmoid()
)

def forward(self, predicted_vertices):
"""
Args:
predicted_vertices: (B, 10475, 3) 预测的3D顶点

Returns:
reconstructed_pressure: (B, 1, 96, 192) 重建的压力图
"""
B = predicted_vertices.shape[0]
flat = predicted_vertices.reshape(B, -1)
pressure = self.vertex_to_pressure(flat)
return pressure.reshape(B, 1, 96, 192)


class PressureNetModule(nn.Module):
"""
PressureNet 单个模块 (Mod1 或 Mod2)

输入: 压力图 (+ 性别one-hot)
输出: 3D人体顶点 + 重建的压力图
"""

def __init__(self, input_channels=1, num_vertices=10475):
super().__init__()

# 编码器: 从压力图提取特征
self.encoder = nn.Sequential(
nn.Conv2d(input_channels, 32, 3, stride=2, padding=1),
nn.BatchNorm2d(32),
nn.ReLU(),

nn.Conv2d(32, 64, 3, stride=2, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(),

nn.Conv2d(64, 128, 3, stride=2, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(),

nn.Conv2d(128, 256, 3, stride=2, padding=1),
nn.BatchNorm2d(256),
nn.ReLU(),

nn.AdaptiveAvgPool2d(1),
)

# 解码器: 从特征预测3D顶点
self.decoder = nn.Sequential(
nn.Linear(256 + 3, 512), # +3 for gender one-hot
nn.ReLU(),
nn.Linear(512, 1024),
nn.ReLU(),
nn.Linear(1024, num_vertices * 3)
)

# PMR网络
self.pmr = PressureMapReconstruction()

def forward(self, pressure_img, gender):
"""
Args:
pressure_img: (B, 1, 96, 192)
gender: (B, 3) one-hot

Returns:
vertices: (B, 10475, 3)
reconstructed_pressure: (B, 1, 96, 192)
"""
# 编码
feat = self.encoder(pressure_img) # (B, 256, 1, 1)
feat = feat.flatten(1) # (B, 256)
feat = torch.cat([feat, gender], dim=1) # (B, 259)

# 解码3D顶点
vertices = self.decoder(feat) # (B, 10475*3)
vertices = vertices.reshape(-1, 10475, 3)

# PMR: 从顶点重建压力图
reconstructed_pressure = self.pmr(vertices)

return vertices, reconstructed_pressure


class PressureNet(nn.Module):
"""
PressureNet 完整模型

Mod1: 粗估计 (coarse)
Mod2: 精细化 (refine) - 使用Mod1的重建压力图作为额外输入
"""

def __init__(self):
super().__init__()
self.mod1 = PressureNetModule(input_channels=1)
self.mod2 = PressureNetModule(input_channels=2) # 原始+Mod1重建

def forward(self, pressure_img, gender):
# Mod1: 粗估计
verts1, recon_pressure1 = self.mod1(pressure_img, gender)

# Mod2: 精细化
mod2_input = torch.cat([pressure_img, recon_pressure1], dim=1)
verts2, recon_pressure2 = self.mod2(mod2_input, gender)

return {
'vertices_coarse': verts1,
'vertices_refined': verts2,
'recon_pressure_1': recon_pressure1,
'recon_pressure_2': recon_pressure2,
}


# ========== 测试 ==========
if __name__ == "__main__":
device = 'cuda' if torch.cuda.is_available() else 'cpu'

model = PressureNet().to(device)

# 模拟输入
pressure_img = torch.randn(2, 1, 96, 192).to(device)
gender = torch.eye(3)[:2].to(device) # 2个样本

output = model(pressure_img, gender)

print("PressureNet 输出:")
for k, v in output.items():
print(f" {k}: {v.shape}")

# 损失函数
def pressurenet_loss(output, target_pressure, target_vertices):
"""
多任务损失:
1. 顶点L2损失 (Mod1 + Mod2)
2. 压力图重建损失 (PMR一致性)
"""
loss = 0

# 顶点损失
if target_vertices is not None:
loss += 0.5 * torch.nn.functional.mse_loss(
output['vertices_coarse'], target_vertices
)
loss += 1.0 * torch.nn.functional.mse_loss(
output['vertices_refined'], target_vertices
)

# PMR 一致性损失
loss += 0.3 * torch.nn.functional.mse_loss(
output['recon_pressure_1'], target_pressure
)
loss += 0.3 * torch.nn.functional.mse_loss(
output['recon_pressure_2'], target_pressure
)

return loss

# 计算损失
loss = pressurenet_loss(output, pressure_img, None)
print(f"\n初始损失: {loss.item():.4f}")

# 模型大小
params = sum(p.numel() for p in model.parameters())
print(f"模型参数量: {params/1e6:.1f}M")

# 性能指标 (来自论文)
print("\n论文报告性能:")
print(f" MPJPE (合成测试): 11.18 cm")
print(f" 3DVPE (合成测试): 3.94 cm")
print(f" 3DVPE (真实-规定姿态): 4.99 cm")
print(f" 3DVPE (真实-自选姿态): 3.93 cm")

3. 消融实验:PMR的重要性

配置 MPJPE (cm) 3DVPE (cm) 说明
PressureNet (完整) 11.18 3.94 Mod1+Mod2+PMR
无 PMR 12.28 4.38 MPJPE↑1.1, 3DVPE↑0.44
仅 Mod1 14.52 5.87 无精细化
无性别输入 11.85 4.21 性别信息有助

IMS OOP 应用启示

1. 座椅压力垫 → OOP检测

2. OOP检测方案对比

方案 优势 劣势 成本 推荐度
摄像头3D姿态 精度高,信息丰富 隐私问题,遮挡 中 ★★★★
压力垫+PressureNet 无隐私问题,穿透毯子 精度中等,需加装传感器 低 ★★★★★
雷达3D感知 穿透力强 分辨率低 中高 ★★★
多传感器融合 最可靠 成本高,复杂 高 ★★★★★

3. 座椅压力垫硬件选型

参数 推荐值 说明
传感单元数 192×96 (18,432) 论文配置
物理尺寸 480mm × 240mm 标准座椅坐垫
单元尺寸 2.5mm × 2.5mm 足够分辨率
测力范围 0-100N 成人坐压范围
采样率 10-30Hz OOP不需要高频
通信接口 CAN-FD / LIN 车规级
工作温度 -40°C ~ +85°C 车规级
厂商 型号 参数 价格
Tekscan BPMS 2,064传感点, 汽车版 $3,000+ (研发)
XSENSOR PX100 10,000+传感点 $2,000+ (研发)
自研方案 压阻阵列 定制FPC 量产<$50/座

4. 座舱OOP检测代码

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
import numpy as np
from scipy.spatial.distance import cdist

class CabinOOPDetector:
"""
基于压力垫的座舱OOP检测器

使用PressureNet预测3D姿态后,
通过关节角度和躯干方向判断OOP状态
"""

# OOP状态定义 (基于Euro NCAP)
OOP_STATES = {
'normal': {'level': 0, 'description': '正常坐姿'},
'forward_lean': {'level': 1, 'description': '前倾 (安全带可能滑落)'},
'side_lean': {'level': 1, 'description': '侧倾 (碰撞保护降低)'},
'reclined': {'level': 1, 'description': '后仰过度 (安全带位置不当)'},
'feet_dashboard': {'level': 2, 'description': '脚放在仪表板 (严重OOP)'},
'out_of_position': {'level': 2, 'description': '严重异常姿态'},
}

def __init__(self, pressure_model):
self.model = pressure_model # 预训练PressureNet

def detect(self, pressure_img, gender):
"""
从压力图像检测OOP状态

Args:
pressure_img: (96, 192) 压力矩阵
gender: 'M'/'F'/'N'

Returns:
oop_state: str, OOP状态
confidence: float, 置信度
risk_level: int, 风险等级 0/1/2
"""
# 1. 预测3D姿态
vertices = self._predict_pose(pressure_img, gender)

# 2. 提取关键关节
joints = self._extract_joints(vertices)

# 3. 计算OOP指标
metrics = self._compute_oop_metrics(joints)

# 4. 分类
oop_state = self._classify(metrics)

return oop_state, metrics

def _predict_pose(self, pressure_img, gender):
"""运行PressureNet"""
# ... (使用上面的PressureNet模型)
pass

def _extract_joints(self, vertices):
"""从SMPL-X顶点提取关键关节"""
# 关键关节索引 (SMPL-X)
joint_indices = {
'head': 12, # 头部
'neck': 12,
'left_shoulder': 16,
'right_shoulder': 17,
'spine': 0,
'left_hip': 1,
'right_hip': 2,
'left_knee': 4,
'right_knee': 5,
}
return {name: vertices[idx] for name, idx in joint_indices.items()}

def _compute_oop_metrics(self, joints):
"""计算OOP判断指标"""
metrics = {}

# 躯干角度 (从脊柱方向)
spine_vec = joints['spine'] - joints['head']
metrics['torso_angle'] = np.arctan2(
spine_vec[0], spine_vec[2]
) # 与垂直方向的角度

# 前倾检测
metrics['forward_lean'] = joints['head'][2] > joints['spine'][2] + 0.1

# 侧倾检测
metrics['side_lean'] = abs(joints['left_shoulder'][0] -
joints['right_shoulder'][0]) > 0.3

# 压力分布不对称
left_pressure = np.sum(pressure_img[:, :96])
right_pressure = np.sum(pressure_img[:, 96:])
metrics['pressure_asymmetry'] = abs(
left_pressure - right_pressure
) / (left_pressure + right_pressure + 1e-6)

return metrics

def _classify(self, metrics):
"""分类OOP状态"""
if metrics['torso_angle'] > 0.5:
return 'forward_lean'
elif metrics['pressure_asymmetry'] > 0.4:
return 'side_lean'
elif metrics['torso_angle'] < -0.3:
return 'reclined'
else:
return 'normal'


if __name__ == "__main__":
# 模拟OOP检测
np.random.seed(42)

# 正常坐姿压力图 (居中分布)
normal_pressure = np.zeros((96, 192))
yy, xx = np.meshgrid(range(96), range(192), indexing='ij')
normal_pressure = np.exp(-((xx-96)**2 + (yy-48)**2) / (2*30**2)) * 50

# 前倾坐姿压力图 (前部集中)
forward_pressure = np.exp(-((xx-96)**2 + (yy-20)**2) / (2*20**2)) * 70

# 侧倾压力图 (左半部集中)
side_pressure = np.zeros((96, 192))
side_pressure[:, :120] = np.exp(-((xx[:120]-60)**2 + (yy-48)**2) / (2*25**2)) * 60

print("OOP检测模拟:")
for name, pressure in [("正常", normal_pressure),
("前倾", forward_pressure),
("侧倾", side_pressure)]:
left = np.sum(pressure[:, :96])
right = np.sum(pressure[:, 96:])
asym = abs(left - right) / (left + right + 1e-6)
centroid_y = np.sum(pressure * np.arange(96)[:, None]) / (np.sum(pressure) + 1e-6)

print(f"\n{name}:")
print(f" 压力不对称: {asym:.2f} (>0.4=侧倾)")
print(f" 压力中心Y: {centroid_y:.1f} (<40=前倾, >56=后仰)")

5. Euro NCAP OOP要求对照

Euro NCAP OOP场景 压力垫可检测 说明
OOP-01 前倾坐姿 ✅ 压力中心前移
OOP-02 侧倾坐姿 ✅ 左右压力不对称
OOP-03 后仰过度 ✅ 压力中心后移
OOP-04 脚放仪表板 ❌ 需摄像头补充
OOP-05 儿童座椅异常 ⚠️ 需要特定训练
OOP-06 跪姿 ✅ 压力分布异常

参考文献

  1. McDermott, M.E., Clever, H.M., Nasim, R.O. “Bodies at Rest: 3D Human Pose and Shape Estimation From a Pressure Image Using Synthetic Data.” CVPR 2020. DOI: 10.1109/cvpr42600.2020.00625
  2. PressurePose Dataset: 206K synthetic pressure images with 3D poses
  3. Euro NCAP 2026 OMS Protocol - OOP detection requirements

PressurePose的核心价值在于证明了”纯合成数据→真实域迁移”的可行性。对于IMS OOP检测,座椅压力垫方案成本低、无隐私问题、可穿透毯子,是摄像头方案的强力补充。建议采购Tekscan研发版进行验证,量产采用自研压阻阵列方案。