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
| import numpy as np from dataclasses import dataclass from typing import List
@dataclass class FatigueEvolutionPhase: """疲劳演化的眼动阶段模型""" name: str duration_min: int saccade_freq: float fixation_duration: float blink_rate: float pupil_var: float
class AviationFatigueEvolutionModel: """ 航空管制员疲劳演化模型 基于Nature Scientific Reports 2026研究: 疲劳在眼动指标中分4个阶段演化 跨行业启示:汽车驾驶疲劳演化模式类似 """ PHASES = [ FatigueEvolutionPhase( name="清醒期 (Alert)", duration_min=30, saccade_freq=2.5, fixation_duration=0.3, blink_rate=15, pupil_var=0.1, ), FatigueEvolutionPhase( name="适应期 (Adaptation)", duration_min=60, saccade_freq=2.0, fixation_duration=0.4, blink_rate=18, pupil_var=0.15, ), FatigueEvolutionPhase( name="疲劳早期 (Early Fatigue)", duration_min=45, saccade_freq=1.3, fixation_duration=0.6, blink_rate=25, pupil_var=0.25, ), FatigueEvolutionPhase( name="疲劳晚期 (Late Fatigue)", duration_min=30, saccade_freq=0.8, fixation_duration=0.9, blink_rate=35, pupil_var=0.35, ), ] def detect_phase(self, saccade_freq: float, fixation_dur: float, blink_rate: float, pupil_var: float) -> str: """ 基于实时眼动指标检测疲劳阶段 Args: saccade_freq: 扫视频率(次/秒) fixation_dur: 平均注视时间(秒) blink_rate: 眨眼频率(次/分) pupil_var: 瞳孔直径变异 Returns: phase_name: 疲劳阶段名称 """ scores = [] for phase in self.PHASES: dist = (abs(saccade_freq - phase.saccade_freq) / 3.0 + abs(fixation_dur - phase.fixation_duration) / 1.0 + abs(blink_rate - phase.blink_rate) / 30.0 + abs(pupil_var - phase.pupil_var) / 0.5) scores.append((phase.name, dist)) scores.sort(key=lambda x: x[1]) return scores[0][0] def get_automotive_mapping(self): """ 航空→汽车映射 航空管制员的疲劳演化模式 在汽车驾驶中的对应表现 """ return { "清醒期": "正常驾驶:活跃扫视,注意力集中", "适应期": "长途驾驶30-60分钟后:扫视略减,开始习惯化", "疲劳早期": "连续驾驶1-2小时:注视延长,眨眼增多 ← IMS应在此阶段触发一级警告", "疲劳晚期": "连续驾驶2小时+:凝视固定,PERCLOS上升 ← IMS应触发二级警告" }
class MultiModalFatigueDetector: """ 多模态疲劳检测器 航空研究结论:EEG+ECG融合达88.42%准确率 汽车改造:眼动(非接触) + rPPG(非接触心率) rPPG = 远程光电容积脉搏波 通过摄像头非接触提取心率,替代ECG """ def __init__(self): self.weights = { 'eye_tracking': 0.35, 'rppg_hrv': 0.25, 'behavior': 0.20, 'context': 0.20, } def detect_fatigue(self, eye_features: dict, rppg_features: dict, behavior_features: dict, context_features: dict) -> dict: """ 多模态融合疲劳检测 Args: eye_features: 眼动特征(扫视/注视/眨眼/瞳孔) rppg_features: rPPG心率变异性特征 behavior_features: 驾驶行为特征(方向盘/车道偏离) context_features: 上下文(驾驶时长/时间段/路况) Returns: result: dict with fatigue score, level, recommendation """ eye_score = self._eye_fatigue_score(eye_features) hrv_score = self._hrv_fatigue_score(rppg_features) behav_score = self._behavior_fatigue_score(behavior_features) ctx_score = self._context_fatigue_score(context_features) total = (self.weights['eye_tracking'] * eye_score + self.weights['rppg_hrv'] * hrv_score + self.weights['behavior'] * behav_score + self.weights['context'] * ctx_score) if total < 0.3: level = 'normal' action = 'continue' elif total < 0.5: level = 'mild_fatigue' action = 'suggest_break' elif total < 0.7: level = 'moderate_fatigue' action = 'warning_level_1' else: level = 'severe_fatigue' action = 'warning_level_2' return { 'fatigue_score': round(total, 3), 'fatigue_level': level, 'action': action, 'sub_scores': { 'eye_tracking': round(eye_score, 3), 'rppg_hrv': round(hrv_score, 3), 'behavior': round(behav_score, 3), 'context': round(ctx_score, 3), } } def _eye_fatigue_score(self, feat: dict) -> float: score = 0 score += min(feat.get('perclos', 0) / 0.3, 1) * 0.4 blink = feat.get('blink_rate', 15) score += min(abs(blink - 15) / 25, 1) * 0.2 score += min(max(0, feat.get('fixation_dur', 0.3) - 0.3) / 0.6, 1) * 0.2 sacc = feat.get('saccade_freq', 2.0) score += min(max(0, 2.0 - sacc) / 1.5, 1) * 0.2 return min(score, 1.0) def _hrv_fatigue_score(self, feat: dict) -> float: hrv_norm = feat.get('rmssd_normalized', 1.0) return max(0, 1 - hrv_norm) def _behavior_fatigue_score(self, feat: dict) -> float: score = 0 score += min(feat.get('lane_deviation_rate', 0) / 10, 1) * 0.5 score += min(feat.get('steering_correction_rate', 0) / 20, 1) * 0.5 return score def _context_fatigue_score(self, feat: dict) -> float: score = 0 hours = feat.get('driving_hours', 0) score += min(hours / 4, 1) * 0.5 hour = feat.get('clock_hour', 12) if hour < 6 or hour > 22: score += 0.5 return min(score, 1.0)
if __name__ == "__main__": model = AviationFatigueEvolutionModel() print("疲劳演化阶段:") for phase in model.PHASES: print(f" {phase.name} ({phase.duration_min}min): " f"扫视={phase.saccade_freq}/s, " f"注视={phase.fixation_duration}s, " f"眨眼={phase.blink_rate}/min") print("\n汽车映射:") for k, v in model.get_automotive_mapping().items(): print(f" {k} → {v}") print("\n实时检测测试:") phase = model.detect_phase( saccade_freq=1.0, fixation_dur=0.8, blink_rate=30, pupil_var=0.3 ) print(f" 输入: 扫视1.0/s, 注视0.8s, 眨眼30/min, 瞳孔变异0.3") print(f" 检测阶段: {phase}") detector = MultiModalFatigueDetector() result = detector.detect_fatigue( eye_features={'perclos': 0.25, 'blink_rate': 28, 'fixation_dur': 0.6, 'saccade_freq': 1.2}, rppg_features={'rmssd_normalized': 0.4}, behavior_features={'lane_deviation_rate': 5, 'steering_correction_rate': 12}, context_features={'driving_hours': 2.5, 'clock_hour': 14} ) print(f"\n多模态融合检测结果:") print(f" 疲劳评分: {result['fatigue_score']}") print(f" 等级: {result['fatigue_level']}") print(f" 建议: {result['action']}") print(f" 子评分: {result['sub_scores']}")
|