低光环境疲劳检测:双注意力机制 + 可解释AI,Nature Scientific Reports 2026

低光环境疲劳检测:双注意力机制 + 可解释AI,Nature Scientific Reports 2026

核心创新

Nature Scientific Reports 2026 发表的低光疲劳检测研究:

指标 传统方法 双注意力方法 提升
低光场景准确率 78% 94% +16%
实时性 25 FPS 30 FPS +20%
模型大小 120MB 45MB -62%

研究背景

低光环境挑战

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
夜间驾驶疲劳检测挑战:

┌─────────────────────────────────────────────────────┐
│ 光照不足导致的问题 │
├─────────────────────────────────────────────────────┤
│ │
│ 1. 面部特征丢失 │
│ - 眼部区域暗淡 │
│ - 嘴部轮廓模糊 │
│ - 面部纹理信息缺失 │
│ │
│ 2. 噪声干扰增加 │
│ - 高 ISO 噪声 │
│ - 运动模糊 │
│ - 红外补光不均匀 │
│ │
│ 3. 误检率上升 │
│ - 闭眼误判 │
│ - 疲劳漏检 │
│ │
│ 解决方案: │
│ ✅ 低光图像增强 │
│ ✅ 双注意力机制 │
│ ✅ 可解释AI验证 │
│ │
└─────────────────────────────────────────────────────┘

方法详解

1. 低光图像增强

研究使用多种低光增强技术对比:

方法 原理 效果
CLAHE 对比度受限直方图均衡 基础增强
EnlightenGAN GAN 无监督增强 显著改善
Zero-DCE 零参考深度曲线估计 轻量级
ILR-Net Retinex 迭代学习 最佳效果

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
"""
双注意力机制疲劳检测

InceptionV3 + 空间注意力 + 通道注意力
"""

import torch
import torch.nn as nn
import torch.nn.functional as F

class SpatialAttention(nn.Module):
"""
空间注意力模块

聚焦面部关键区域(眼部、嘴部)
"""

def __init__(self, kernel_size: int = 7):
super().__init__()

self.conv = nn.Conv2d(2, 1, kernel_size, padding=kernel_size//2)
self.sigmoid = nn.Sigmoid()

def forward(self, x):
"""
Args:
x: (B, C, H, W)

Returns:
attention: (B, 1, H, W)
"""
# 沿通道维度计算最大值和平均值
max_pool = torch.max(x, dim=1, keepdim=True)[0] # (B, 1, H, W)
avg_pool = torch.mean(x, dim=1, keepdim=True) # (B, 1, H, W)

# 拼接
concat = torch.cat([max_pool, avg_pool], dim=1) # (B, 2, H, W)

# 卷积生成注意力图
attention = self.sigmoid(self.conv(concat))

return x * attention


class ChannelAttention(nn.Module):
"""
通道注意力模块

强调疲劳相关特征通道
"""

def __init__(self, channels: int, reduction: int = 16):
super().__init__()

self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.max_pool = nn.AdaptiveMaxPool2d(1)

self.fc = nn.Sequential(
nn.Linear(channels, channels // reduction, bias=False),
nn.ReLU(),
nn.Linear(channels // reduction, channels, bias=False),
)
self.sigmoid = nn.Sigmoid()

def forward(self, x):
B, C, H, W = x.shape

# 全局池化
avg_out = self.fc(self.avg_pool(x).view(B, C))
max_out = self.fc(self.max_pool(x).view(B, C))

# 注意力权重
attention = self.sigmoid(avg_out + max_out).view(B, C, 1, 1)

return x * attention


class DualAttentionFatigueNet(nn.Module):
"""
双注意力疲劳检测网络

InceptionV3 骨干 + 空间注意力 + 通道注意力
"""

def __init__(self, num_classes: int = 3):
"""
Args:
num_classes: 0=清醒, 1=轻度疲劳, 2=重度疲劳
"""
super().__init__()

# InceptionV3 骨干(预训练)
from torchvision.models import inception_v3
inception = inception_v3(pretrained=True)

# 提取特征
self.features = nn.Sequential(
inception.Conv2d_1a_3x3,
inception.Conv2d_2a_3x3,
inception.Conv2d_2b_3x3,
nn.MaxPool2d(3, 2),
inception.Conv2d_3b_1x1,
inception.Conv2d_4a_3x3,
nn.MaxPool2d(3, 2),
)

# 双注意力
self.spatial_attention = SpatialAttention()
self.channel_attention = ChannelAttention(192) # InceptionV3 输出通道

# 分类头
self.classifier = nn.Sequential(
nn.AdaptiveAvgPool2d(1),
nn.Flatten(),
nn.Dropout(0.5),
nn.Linear(192, 128),
nn.ReLU(),
nn.Linear(128, num_classes)
)

def forward(self, x):
"""
Args:
x: (B, 3, 299, 299) 低光增强后的图像

Returns:
logits: (B, num_classes)
"""
# 特征提取
features = self.features(x)

# 双注意力
features = self.channel_attention(features)
features = self.spatial_attention(features)

# 分类
logits = self.classifier(features)

return logits


# 低光增强模块
class LowLightEnhancer(nn.Module):
"""
低光图像增强

使用 Zero-DCE 轻量级方法
"""

def __init__(self, num_iterations: int = 8):
super().__init__()

self.num_iterations = num_iterations

# 曲线参数估计网络
self.curve_net = nn.Sequential(
nn.Conv2d(3, 32, 3, 1, 1),
nn.ReLU(),
nn.Conv2d(32, 32, 3, 1, 1),
nn.ReLU(),
nn.Conv2d(32, 3 * num_iterations, 3, 1, 1),
nn.Tanh()
)

def forward(self, x):
"""
Args:
x: (B, 3, H, W) 低光图像

Returns:
enhanced: (B, 3, H, W) 增强图像
"""
# 估计曲线参数
curves = self.curve_net(x) # (B, 3*num_iterations, H, W)

# 迭代增强
enhanced = x
for i in range(self.num_iterations):
curve = curves[:, 3*i:3*(i+1), :, :]
enhanced = enhanced + curve * enhanced * (1 - enhanced)

return enhanced


# 完整流水线
class LowLightFatigueDetector(nn.Module):
"""
低光疲劳检测完整流水线

低光增强 + 疲劳分类
"""

def __init__(self):
super().__init__()

self.enhancer = LowLightEnhancer()
self.detector = DualAttentionFatigueNet()

def forward(self, low_light_image):
"""
Args:
low_light_image: (B, 3, H, W)

Returns:
fatigue_level: (B,) 疲劳等级
enhanced_image: (B, 3, H, W) 增强图像(用于可解释性)
"""
# 1. 低光增强
enhanced = self.enhancer(low_light_image)

# 2. 疲劳检测
logits = self.detector(enhanced)
fatigue_level = torch.argmax(logits, dim=1)

return fatigue_level, enhanced


# 使用示例
if __name__ == "__main__":
model = LowLightFatigueDetector()

# 模拟低光图像
low_light = torch.randn(1, 3, 299, 299) * 0.3 + 0.2 # 暗淡图像

# 检测
fatigue_level, enhanced = model(low_light)

print(f"疲劳等级: {fatigue_level.item()}")
print(f"增强图像亮度: {enhanced.mean().item():.3f}")

3. 可解释AI (XAI)

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
"""
可解释AI模块

使用 Grad-CAM 可视化疲劳检测依据
"""

class GradCAM:
"""
Grad-CAM 可视化

验证模型关注的是疲劳相关区域
"""

def __init__(self, model, target_layer):
self.model = model
self.target_layer = target_layer

# 注册钩子
self.gradients = None
self.activations = None

target_layer.register_forward_hook(self._save_activation)
target_layer.register_backward_hook(self._save_gradient)

def _save_activation(self, module, input, output):
self.activations = output

def _save_gradient(self, module, grad_input, grad_output):
self.gradients = grad_output[0]

def __call__(self, x, class_idx=None):
"""
生成 Grad-CAM 热力图

Args:
x: (B, 3, H, W)
class_idx: 目标类别索引

Returns:
cam: (B, H, W) 热力图
"""
# 前向传播
logits = self.model(x)

if class_idx is None:
class_idx = logits.argmax(dim=1)

# 反向传播
self.model.zero_grad()
logits[0, class_idx].backward(retain_graph=True)

# 计算 Grad-CAM
weights = self.gradients.mean(dim=(2, 3), keepdim=True)
cam = (weights * self.activations).sum(dim=1, keepdim=True)
cam = F.relu(cam)
cam = F.interpolate(cam, size=x.shape[2:], mode='bilinear')
cam = cam / cam.max()

return cam.squeeze(1)


# 验证示例
def verify_fatigue_detection():
"""
验证疲劳检测依据

确保模型关注:
1. 眼部区域(PERCLOS)
2. 嘴部区域(打哈欠)
3. 头部姿态
"""
model = DualAttentionFatigueNet()
grad_cam = GradCAM(model, model.features[-1])

# 加载测试图像
image = torch.randn(1, 3, 299, 299)

# 生成热力图
cam = grad_cam(image)

# 检查关键区域激活
# 眼部区域 (y: 100-150, x: 100-200)
eye_activation = cam[0, 100:150, 100:200].mean()

# 嘴部区域 (y: 180-220, x: 120-180)
mouth_activation = cam[0, 180:220, 120:180].mean()

print(f"眼部区域激活: {eye_activation:.3f}")
print(f"嘴部区域激活: {mouth_activation:.3f}")

# 合理的疲劳检测应该关注这些区域
assert eye_activation > 0.3, "模型未充分关注眼部区域"

实验结果

数据集

数据集 场景 样本数
自采集 夜间驾驶 5,000+
DDD 疲劳检测基准 22,000+
NTHU-DDD 动态疲劳 600+ 视频

性能对比

方法 白天准确率 低光准确率 FPS
ResNet-50 95% 72% 28
EfficientNet 94% 75% 25
双注意力(本文) 96% 94% 30

消融实验

组件 低光准确率 提升
Baseline (InceptionV3) 78% -
+ 低光增强 85% +7%
+ 空间注意力 89% +4%
+ 通道注意力 92% +3%
+ XAI 优化 94% +2%

Euro NCAP 合规

夜间疲劳检测要求

Euro NCAP 要求 本文方法 合规
夜间检测能力 低光增强
PERCLOS 检测 眼部注意力
时延 ≤ 3s 30 FPS
可解释性 Grad-CAM

测试场景

1
2
3
4
5
6
7
8
9
10
11
12
13
Euro NCAP 夜间疲劳测试:

FT-01 夜间疲劳检测
├─ 光照条件:< 5 lux(无路灯)
├─ 红外补光:940nm
├─ 检测指标:PERCLOS ≥ 30%
└─ 时延要求:≤ 3

本文方法:
✅ 低光增强恢复眼部特征
✅ 空间注意力聚焦眼部
✅ Grad-CAM 验证检测依据
30 FPS 满足实时性

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
66
67
68
69
70
71
72
73
74
75
"""
IMS 夜间疲劳检测流程

集成低光增强和双注意力机制
"""

class IMSNighttimeFatigueDetector:
"""
IMS 夜间疲劳检测器
"""

def __init__(self):
# 低光增强
self.enhancer = LowLightEnhancer()

# 疲劳检测
self.detector = DualAttentionFatigueNet()

# 可解释性
self.explainer = GradCAM(self.detector, self.detector.features[-1])

# PERCLOS 计算
self.perclos_window = [] # 60秒窗口

def process_frame(self, frame, timestamp):
"""
处理单帧

Args:
frame: (H, W, 3) BGR 图像
timestamp: 时间戳

Returns:
{
'is_fatigue': bool,
'fatigue_level': int,
'perclos': float,
'attention_map': np.ndarray
}
"""
# 1. 检测光照条件
brightness = frame.mean()

# 2. 低光增强(如果需要)
if brightness < 50: # 低光阈值
enhanced = self.enhancer(frame)
else:
enhanced = frame

# 3. 疲劳检测
fatigue_level = self.detector(enhanced)

# 4. 更新 PERCLOS
# 假设疲劳检测器输出眼睛开度
eye_openness = self._extract_eye_openness(enhanced)
self.perclos_window.append((timestamp, eye_openness))

# 保留 60 秒窗口
cutoff = timestamp - 60
self.perclos_window = [
(t, e) for t, e in self.perclos_window if t > cutoff
]

# 计算 PERCLOS
perclos = sum(1 for _, e in self.perclos_window if e < 0.2) / len(self.perclos_window)

# 5. 生成可解释性热力图
attention_map = self.explainer(enhanced)

return {
'is_fatigue': fatigue_level >= 1,
'fatigue_level': fatigue_level.item(),
'perclos': perclos,
'attention_map': attention_map.numpy()
}

2. 部署建议

平台 配置 预期帧率
Jetson Orin NX TensorRT FP16 30 FPS
Qualcomm QCS8255 SNPE INT8 20 FPS
TI TDA4VM TIDL INT8 15 FPS

总结

低光疲劳检测关键创新:

  1. 低光增强 - Zero-DCE 轻量级增强
  2. 双注意力 - 空间 + 通道注意力
  3. 可解释AI - Grad-CAM 验证检测依据
  4. 性能提升 - 低光准确率 94%

对 IMS 开发的启示:

  • 夜间驾驶疲劳检测需要专门的低光处理
  • 注意力机制确保模型关注关键区域
  • 可解释性是 Euro NCAP 验证的重要依据

参考资源

资源 链接
论文 Nature Scientific Reports s41598-026-44442-3
Zero-DCE arxiv.org/abs/2001.06826
Euro NCAP euroncap.com/protocols

低光环境疲劳检测:双注意力机制 + 可解释AI,Nature Scientific Reports 2026
https://dapalm.com/2026/04/26/2026-04-26-low-light-drowsiness-dual-attention/
作者
Mars
发布于
2026年4月26日
许可协议