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
| """ 上下文感知疲劳检测框架
论文 Section 4.3: Safety and Security
核心思想: 疲劳检测不应只依赖面部特征, 应融合驾驶行为、环境条件和历史模式 """
import numpy as np from dataclasses import dataclass from typing import Optional, List
@dataclass class DrivingContext: """驾驶上下文""" speed: float acceleration: float steering_angle: float road_type: str time_of_day: str weather: str driving_duration: float
@dataclass class OccupantContext: """乘员上下文""" face_detected: bool eye_openness: float blink_rate: float head_pose: tuple gaze_direction: tuple body_posture: str
@dataclass class VehicleContext: """车辆上下文""" adas_level: int lane_departure: bool fcw_alert: bool autopilot_active: bool
class ContextAwareFatigueDetector: """ 上下文感知疲劳检测器 融合三层上下文: 1. 驾驶上下文: 行为特征反映疲劳 2. 乘员上下文: 面部特征直接测量 3. 车辆上下文: ADAS 状态影响判定 """ CONTEXT_WEIGHTS = { 'highway_night': { 'face': 0.5, 'driving': 0.3, 'vehicle': 0.2 }, 'urban_day': { 'face': 0.7, 'driving': 0.2, 'vehicle': 0.1 }, 'autopilot_active': { 'face': 0.8, 'driving': 0.0, 'vehicle': 0.2 } } def __init__(self): self.fatigue_history = [] self.context_history = [] def detect(self, driving: DrivingContext, occupant: OccupantContext, vehicle: VehicleContext) -> dict: """ 上下文感知疲劳检测 Returns: dict with fatigue_level, confidence, recommendation """ context_mode = self._get_context_mode(driving, vehicle) weights = self.CONTEXT_WEIGHTS.get(context_mode, self.CONTEXT_WEIGHTS['urban_day']) face_score = self._face_fatigue_score(occupant) driving_score = self._driving_fatigue_score(driving) vehicle_score = self._vehicle_fatigue_score(vehicle, driving) total_score = ( weights['face'] * face_score + weights['driving'] * driving_score + weights['vehicle'] * vehicle_score ) self.fatigue_history.append(total_score) if len(self.fatigue_history) > 30: self.fatigue_history.pop(0) smoothed_score = np.mean(self.fatigue_history[-10:]) level = self._score_to_level(smoothed_score, context_mode) return { 'fatigue_level': level, 'confidence': min(smoothed_score, 1 - smoothed_score), 'context_mode': context_mode, 'face_score': face_score, 'driving_score': driving_score, 'vehicle_score': vehicle_score, 'recommendation': self._get_recommendation(level, context_mode), } def _get_context_mode(self, driving: DrivingContext, vehicle: VehicleContext) -> str: """确定当前上下文模式""" if vehicle.autopilot_active: return 'autopilot_active' if driving.road_type == 'highway' and 'night' in driving.time_of_day: return 'highway_night' return 'urban_day' def _face_fatigue_score(self, occ: OccupantContext) -> float: """面部疲劳评分 (0-1)""" score = 0.0 if occ.eye_openness < 0.3: score += 0.4 if occ.blink_rate > 25 or occ.blink_rate < 8: score += 0.3 if occ.head_pose[0] > 15: score += 0.3 return min(score, 1.0) def _driving_fatigue_score(self, driving: DrivingContext) -> float: """驾驶行为疲劳评分""" score = 0.0 steering_var = abs(driving.steering_angle) if steering_var > 3: score += 0.3 if driving.driving_duration > 2.0: score += 0.3 if driving.driving_duration > 4.0: score += 0.2 if abs(driving.acceleration) > 0.5: score += 0.2 return min(score, 1.0) def _vehicle_fatigue_score(self, vehicle: VehicleContext, driving: DrivingContext) -> float: """车辆状态疲劳评分""" score = 0.0 if vehicle.lane_departure: score += 0.4 if vehicle.fcw_alert: score += 0.3 if driving.speed < 50 and driving.road_type == 'highway': score += 0.3 return min(score, 1.0) def _score_to_level(self, score: float, mode: str) -> str: """上下文感知的等级判定""" if mode == 'highway_night': thresholds = [0.3, 0.5, 0.7] else: thresholds = [0.4, 0.6, 0.8] if score < thresholds[0]: return 'awake' elif score < thresholds[1]: return 'mild_fatigue' elif score < thresholds[2]: return 'moderate_fatigue' else: return 'severe_fatigue' def _get_recommendation(self, level: str, mode: str) -> str: """上下文感知的建议""" if level == 'severe_fatigue': if mode == 'highway_night': return 'CRITICAL: 立即靠边停车休息' return 'WARNING: 建议休息' elif level == 'moderate_fatigue': return 'ALERT: 二级警告+空调冷风' elif level == 'mild_fatigue': return 'INFO: 一级警告+音乐' return 'OK: 正常驾驶'
if __name__ == "__main__": detector = ContextAwareFatigueDetector() print("=" * 60) print("场景1: 高速公路夜间疲劳驾驶") print("=" * 60) driving1 = DrivingContext( speed=120, acceleration=0.1, steering_angle=2.5, road_type='highway', time_of_day='night', weather='clear', driving_duration=3.5 ) occupant1 = OccupantContext( face_detected=True, eye_openness=0.25, blink_rate=28, head_pose=(18, 5, 2), gaze_direction=(0.1, -0.2, 1), body_posture='slouching' ) vehicle1 = VehicleContext( adas_level=2, lane_departure=True, fcw_alert=False, autopilot_active=False ) result1 = detector.detect(driving1, occupant1, vehicle1) print(f"疲劳等级: {result1['fatigue_level']}") print(f"置信度: {result1['confidence']:.2f}") print(f"上下文模式: {result1['context_mode']}") print(f"面部评分: {result1['face_score']:.2f}") print(f"驾驶评分: {result1['driving_score']:.2f}") print(f"建议: {result1['recommendation']}") print("\n" + "=" * 60) print("场景2: 城市白天轻微疲劳") print("=" * 60) detector2 = ContextAwareFatigueDetector() driving2 = DrivingContext( speed=45, acceleration=0.2, steering_angle=1.0, road_type='urban', time_of_day='day', weather='clear', driving_duration=1.5 ) occupant2 = OccupantContext( face_detected=True, eye_openness=0.45, blink_rate=22, head_pose=(8, 3, 1), gaze_direction=(0, 0, 1), body_posture='upright' ) vehicle2 = VehicleContext( adas_level=1, lane_departure=False, fcw_alert=False, autopilot_active=False ) result2 = detector2.detect(driving2, occupant2, vehicle2) print(f"疲劳等级: {result2['fatigue_level']}") print(f"建议: {result2['recommendation']}") print("\n" + "=" * 60) print("场景3: 自动驾驶模式下的乘员监控") print("=" * 60) detector3 = ContextAwareFatigueDetector() driving3 = DrivingContext( speed=100, acceleration=0, steering_angle=0, road_type='highway', time_of_day='day', weather='clear', driving_duration=2.0 ) occupant3 = OccupantContext( face_detected=True, eye_openness=0.15, blink_rate=15, head_pose=(25, 10, 5), gaze_direction=(0.2, -0.3, 0.5), body_posture='leaning' ) vehicle3 = VehicleContext( adas_level=4, lane_departure=False, fcw_alert=False, autopilot_active=True ) result3 = detector3.detect(driving3, occupant3, vehicle3) print(f"疲劳等级: {result3['fatigue_level']}") print(f"上下文模式: {result3['context_mode']}") print(f"面部权重: {detector3.CONTEXT_WEIGHTS['autopilot_active']['face']}") print(f"建议: {result3['recommendation']}") print("💡 自动驾驶时面部特征权重提升至0.8(驾驶行为不再可靠)")
|