航空座舱疲劳监测技术全景:飞行员眼动追踪方法对DMS的跨界启示

研究背景

  • 核心论文: “Real-Time Cognitive State Monitoring via Physiological Signals in Commercial Aviation” (Brain Sciences, 2026)
  • 关联研究: “Multimodal Analysis of Eye Movements and Fatigue in a Simulated Glass Cockpit” (Aerospace, 2021)
  • 关键论文: “Fatigue Detection of Air Traffic Controllers Through Their Eye Movements” (Aerospace, 2024)
  • 产业参考: “Future Flight Safety Monitoring: Predicting Pilot Performance During Descent” (Springer, 2024)

航空疲劳监测方法体系

航空业已成熟的眼动指标

指标 定义 疲劳表现 汽车DMS可移植性
扫视频率 每秒扫视次数 疲劳时下降30-50% ✅ 高:现有DMS视线检测即可
注视稳定性 中心注视时长占比 疲劳时增加(凝视固定) ✅ 高:视线落点已有
眼动熵 扫视分布的Shannon熵 疲劳时降低(扫描范围缩小) ✅ 高:直接从视线序列计算
瞳孔直径 瞳孔大小变异 疲劳时收缩+变异降低 ⚠️ 中:需近红外+高帧率
眨眼间隔分布 IBI统计特性 疲劳时方差增大 ✅ 高:已有眨眼检测
PERCLOS 眼睑闭合比例 航空标准指标 ✅ 高:DMS已有
注视转移矩阵 仪表间扫描转移概率 疲劳时转移模式单一化 ⚠️ 中:需定义ROI

玻璃座舱眼动特征(Wang et al. 2024)

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
"""
飞行员眼动疲劳指标计算 - 可移植到汽车DMS

基于 Aerospace 2021 和 Springer 2024 论文方法
依赖: pip install numpy scipy

输入: 视线落点序列 + 眨眼事件
输出: 疲劳综合评分
"""

import numpy as np
from scipy.stats import entropy
from typing import List, Dict, Tuple

class AviationEyeMetrics:
"""
航空座舱眼动疲劳指标 - 移植到DMS

参考:
- Multimodal Analysis of Eye Movements and Fatigue (Aerospace, 2021)
- Fatigue Detection of ATC Through Eye Movements (Aerospace, 2024)
- Predicting Pilot Performance During Descent (Springer, 2024)
"""

def __init__(self, fps: int = 30, roi_grid: Tuple[int, int] = (4, 4)):
"""
Args:
fps: 眼动采样率
roi_grid: ROI网格划分(用于扫描熵计算)
"""
self.fps = fps
self.roi_grid = roi_grid

def calculate_gaze_entropy(self, gaze_points: np.ndarray) -> float:
"""
计算扫视分布熵

疲劳时扫描范围缩小→熵降低
正常值: 3.0-4.5 (4x4网格)
疲劳值: <2.5

Args:
gaze_points: 视线落点序列, shape=(N, 2), 归一化0-1

Returns:
entropy_value: Shannon熵 (bits)
"""
h, w = self.roi_grid

# 将视线落点分配到ROI网格
bins_x = np.clip((gaze_points[:, 0] * w).astype(int), 0, w-1)
bins_y = np.clip((gaze_points[:, 1] * h).astype(int), 0, h-1)
roi_indices = bins_y * w + bins_x

# 计算各ROI的访问频率
roi_counts = np.bincount(roi_indices, minlength=h*w)
roi_probs = roi_counts / len(roi_indices)

# Shannon熵
# 过滤零概率
roi_probs = roi_probs[roi_probs > 0]
return float(entropy(roi_probs, base=2))

def calculate_scan_path_diversity(self, gaze_points: np.ndarray,
window: int = 150) -> float:
"""
扫描路径多样性指标

滑动窗口内不同ROI的访问数量
疲劳时扫描路径更单调→多样性降低

Args:
gaze_points: shape=(N, 2)
window: 滑动窗口(帧数), 默认5秒@30fps

Returns:
diversity: 平均ROI覆盖数 (0到grid_size)
"""
h, w = self.roi_grid
n = len(gaze_points)

diversities = []
for i in range(0, n - window, window // 2):
segment = gaze_points[i:i+window]
bins_x = np.clip((segment[:, 0] * w).astype(int), 0, w-1)
bins_y = np.clip((segment[:, 1] * h).astype(int), 0, h-1)
roi_set = set(zip(bins_y, bins_x))
diversities.append(len(roi_set))

return float(np.mean(diversities)) if diversities else 0.0

def calculate_transition_matrix_entropy(self, gaze_points: np.ndarray) -> float:
"""
注视转移矩阵熵

衡量扫描模式复杂性:
- 高熵=扫描模式多样化(正常)
- 低熵=扫描模式固定(疲劳)

Args:
gaze_points: shape=(N, 2)

Returns:
transition_entropy: 转移熵 (bits)
"""
h, w = self.roi_grid
n_rois = h * w

# 量化到ROI
bins_x = np.clip((gaze_points[:, 0] * w).astype(int), 0, w-1)
bins_y = np.clip((gaze_points[:, 1] * h).astype(int), 0, h-1)
roi_seq = bins_y * w + bins_x

# 转移矩阵
trans = np.zeros((n_rois, n_rois))
for i in range(len(roi_seq) - 1):
trans[roi_seq[i], roi_seq[i+1]] += 1

# 行归一化
row_sums = trans.sum(axis=1, keepdims=True)
trans_norm = np.where(row_sums > 0, trans / row_sums, 0)

# 转移熵 = 各行熵的平均
entropies = []
for row in trans_norm:
row = row[row > 0]
if len(row) > 0:
entropies.append(entropy(row, base=2))

return float(np.mean(entropies)) if entropies else 0.0

def calculate_blink_interval_variability(self, blink_times: List[float]) -> float:
"""
眨眼间隔变异系数

疲劳时眨眼间隔方差增大
正常值: CV ≈ 0.3-0.5
疲劳值: CV > 0.6

Args:
blink_times: 眨眼时间戳列表(秒)

Returns:
cv: 变异系数
"""
if len(blink_times) < 5:
return 0.0

intervals = np.diff(sorted(blink_times))
mean_ibi = np.mean(intervals)
std_ibi = np.std(intervals)

if mean_ibi == 0:
return 0.0

return float(std_ibi / mean_ibi)

def compute_fatigue_score(self, gaze_points: np.ndarray,
blink_times: List[float],
perclos: float) -> Dict[str, float]:
"""
综合疲劳评分

基于航空座舱多指标融合方法
移植到汽车DMS场景

Args:
gaze_points: 视线落点, shape=(N, 2), 归一化
blink_times: 眨眼时间戳列表(秒)
perclos: PERCLOS值 (0-1)

Returns:
{
'fatigue_score': 综合评分 0-100,
'gaze_entropy': 扫视熵,
'scan_diversity': 扫描多样性,
'transition_entropy': 转移熵,
'blink_cv': 眨眼变异,
'perclos': PERCLOS,
'level': 疲劳等级
}
"""
# 各指标计算
g_entropy = self.calculate_gaze_entropy(gaze_points)
s_diversity = self.calculate_scan_path_diversity(gaze_points)
t_entropy = self.calculate_transition_matrix_entropy(gaze_points)
b_cv = self.calculate_blink_interval_variability(blink_times)

# 归一化到0-1(1=疲劳)
norm_entropy = 1.0 - min(g_entropy / 4.0, 1.0) # 4.0 = 满熵参考
norm_diversity = 1.0 - min(s_diversity / 16.0, 1.0) # 16 = 全覆盖
norm_trans = 1.0 - min(t_entropy / 4.0, 1.0)
norm_blink = min(b_cv / 1.0, 1.0) # CV>1.0为极度疲劳

# 加权融合(权重来自航空研究经验)
weights = {
'perclos': 0.30,
'gaze_entropy': 0.25,
'scan_diversity': 0.15,
'transition_entropy': 0.15,
'blink_cv': 0.15,
}

score = (
weights['perclos'] * perclos +
weights['gaze_entropy'] * norm_entropy +
weights['scan_diversity'] * norm_diversity +
weights['transition_entropy'] * norm_trans +
weights['blink_cv'] * norm_blink
)

fatigue_score = score * 100 # 0-100

# 疲劳等级
if fatigue_score < 25:
level = 'normal'
elif fatigue_score < 50:
level = 'mild'
elif fatigue_score < 75:
level = 'moderate'
else:
level = 'severe'

return {
'fatigue_score': round(fatigue_score, 1),
'gaze_entropy': round(g_entropy, 2),
'scan_diversity': round(s_diversity, 1),
'transition_entropy': round(t_entropy, 2),
'blink_cv': round(b_cv, 3),
'perclos': round(perclos, 3),
'level': level,
}


# 测试代码
if __name__ == "__main__":
np.random.seed(42)
metrics = AviationEyeMetrics(fps=30, roi_grid=(4, 4))

# 模拟正常驾驶(多区域扫描)
n_normal = 900 # 30秒@30fps
normal_gaze = np.column_stack([
np.clip(np.random.normal(0.5, 0.25, n_normal), 0, 1),
np.clip(np.random.normal(0.5, 0.2, n_normal), 0, 1),
])

# 模拟疲劳驾驶(凝视固定)
n_fatigue = 900
fatigue_gaze = np.column_stack([
np.clip(np.random.normal(0.5, 0.08, n_fatigue), 0, 1), # 扫描范围小
np.clip(np.random.normal(0.5, 0.06, n_fatigue), 0, 1),
])

# 模拟眨眼
normal_blinks = list(np.sort(np.random.uniform(0, 30, 15))) # 0.5Hz
fatigue_blinks = list(np.sort(np.random.uniform(0, 30, 8))) # 不规律

# 评估
print("=== 正常驾驶 ===")
result_normal = metrics.compute_fatigue_score(
normal_gaze, normal_blinks, perclos=0.08
)
for k, v in result_normal.items():
print(f" {k}: {v}")

print("\n=== 疲劳驾驶 ===")
result_fatigue = metrics.compute_fatigue_score(
fatigue_gaze, fatigue_blinks, perclos=0.25
)
for k, v in result_fatigue.items():
print(f" {k}: {v}")

print(f"\n=== 关键差异 ===")
print(f"扫视熵: 正常={result_normal['gaze_entropy']}, "
f"疲劳={result_fatigue['gaze_entropy']} "
f"(下降{(1-result_fatigue['gaze_entropy']/result_normal['gaze_entropy'])*100:.0f}%)")
print(f"扫描多样性: 正常={result_normal['scan_diversity']}, "
f"疲劳={result_fatigue['scan_diversity']}")
print(f"综合评分: 正常={result_normal['fatigue_score']}, "
f"疲劳={result_fatigue['fatigue_score']}")

航空→汽车技术迁移分析

眼动熵在DMS中的实现路径

graph LR
    A[DMS摄像头] --> B[人脸关键点检测]
    B --> C[视线方向估计]
    C --> D[视线落点映射]
    D --> E[ROI网格量化]
    E --> F[Shannon熵计算]
    E --> G[转移矩阵熵]
    E --> H[扫描多样性]
    F --> I[疲劳融合评分]
    G --> I
    H --> I
    I --> J[疲劳等级输出]

航空vs汽车场景差异

维度 航空座舱 汽车座舱 迁移调整
ROI数量 8-15个仪表 4-6个(路面/后视/仪表/中控) 简化网格
扫描模式 周期性仪表扫描 路面为主+周期扫视 不同基线
驾驶员位置 固定座椅 可调座椅+身高差 视线标定
光照 控制光照 日夜变化大 红外补充
振动 平稳 路面振动大 滤波增强
可用帧率 60-120fps 25-30fps 算法适应低帧率

商业化参考:Bitbrain × Nissan B2V的启示

Bitbrain为Nissan B2V开发的干电极EEG头环:

  • 部署时间:<2分钟
  • 续航:8小时
  • 无线:蓝牙
  • 传感器:最小化干电极

对IMS的启示: BCI在车辆中的短期商业化路径不是”脑控驾驶”,而是”认知状态监测”——作为DMS的补充信号源。但5年内EEG头环不太可能被消费者接受,因此非接触式雷达/摄像头的认知负荷间接估计是更现实的路线。

IMS开发启示

1. 眼动熵(P0,2人月,立即可做)

  • 输入: 已有DMS视线落点序列
  • 计算: 4×4 ROI网格 Shannon熵
  • 输出: 疲劳补充指标
  • 精度目标: 与PERCLOS相关性 >0.7
  • 部署: 高通8255,<5ms

2. 转移矩阵熵(P1,3人月)

  • 输入: 视线ROI转移序列
  • 计算: 一阶Markov转移矩阵熵
  • 输出: 扫描模式单一化指标
  • 精度目标: 区分疲劳/正常 AUC>0.85

3. 眨眼间隔变异(P1,1人月)

  • 输入: 已有眨眼检测
  • 计算: IBI变异系数
  • 输出: 不规律眨眼指标
  • 精度目标: CV>0.6对应疲劳

4. 多指标融合评分(P2,6人月)

  • 输入: PERCLOS + 眼动熵 + 转移熵 + 眨眼CV
  • 模型: 逻辑回归/LSTM
  • 输出: 综合疲劳分数(0-100)
  • 验证: 与驾驶模拟器疲劳评定对比

参考文献

  1. “Real-Time Cognitive State Monitoring via Physiological Signals in Commercial Aviation”, Brain Sciences, 2026
  2. “Multimodal Analysis of Eye Movements and Fatigue in a Simulated Glass Cockpit”, Aerospace, 2021
  3. “Fatigue Detection of Air Traffic Controllers Through Their Eye Movements”, Aerospace, 2024
  4. Wang et al., “Future Flight Safety Monitoring: Predicting Pilot Performance”, Springer, 2024
  5. “Eye-Tracking Measures in Aviation: A Selective Literature Review”, Ergonomics in Design, 2018
  6. “Fatigue Monitoring Using Wearables and AI”, arXiv:2412.16847, 2024

https://dapalm.com/2026/10/02/2026-10-02-06-aviation-cockpit-eye-tracking-fatigue-dms-cross-domain-ims/
作者
Mars
发布于
2026年10月2日
许可协议