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
| """ IMS 认知分心检测模块 基于AutomotiveUI 2025研究成果
核心算法: 1. PRC周期性检测(集中-分散交替) 2. VD动态变化检测 3. 与视觉分心区分
Euro NCAP 2026要求: - 检测认知分心(KSS > 7等效) - 与疲劳区分 - 与视觉分心区分 """
import numpy as np from typing import List, Tuple, Optional from dataclasses import dataclass from enum import Enum
class DistractionType(Enum): """分心类型""" NONE = "正常" VISUAL = "视觉分心" COGNITIVE = "认知分心" COMBINED = "混合分心"
@dataclass class CognitiveDistractionState: """认知分心状态""" distraction_type: DistractionType prc_value: float vd_value: float hd_value: float cycle_detected: bool confidence: float
class CognitiveDistractionDetector: """ 认知分心检测器 基于眼动指标的动态分析: 1. PRC周期性:集中-分散交替 → 认知分心 2. VD增加:垂直分散 → 认知分心间隙 3. HD正常:水平扫描未减少 → 区分视觉分心 """ def __init__( self, prc_threshold_high: float = 80.0, prc_threshold_low: float = 60.0, vd_threshold_high: float = 7.0, hd_threshold_low: float = 6.0, window_seconds: int = 30, fps: int = 30 ): """ Args: prc_threshold_high: PRC高阈值(过度集中) prc_threshold_low: PRC低阈值(分散) vd_threshold_high: VD高阈值(垂直分散) hd_threshold_low: HD低阈值(水平集中) window_seconds: 分析窗口秒数 fps: 采样帧率 """ self.prc_high = prc_threshold_high self.prc_low = prc_threshold_low self.vd_high = vd_threshold_high self.hd_low = hd_threshold_low self.window_size = window_seconds * fps def detect_cognitive_cycle( self, prc_sequence: np.ndarray, vd_sequence: np.ndarray ) -> Tuple[bool, float]: """ 检测认知分心的周期性特征 Args: prc_sequence: PRC时间序列 vd_sequence: VD时间序列 Returns: cycle_detected: 是否检测到周期 cycle_strength: 周期强度(0-1) 方法: 1. 计算PRC和VD的变化频率 2. 检测集中-分散交替模式 3. 计算周期强度 """ if len(prc_sequence) < self.window_size: return False, 0.0 prc_changes = np.diff(prc_sequence) concentration_events = np.sum(prc_changes > 5) dispersion_events = np.sum(prc_changes < -5) if concentration_events > 0 and dispersion_events > 0: alternation_ratio = min( concentration_events, dispersion_events ) / max(concentration_events, dispersion_events) cycle_strength = alternation_ratio cycle_detected = alternation_ratio > 0.5 return cycle_detected, cycle_strength return False, 0.0 def classify_distraction( self, prc_value: float, vd_value: float, hd_value: float, cycle_detected: bool ) -> DistractionType: """ 分类分心类型 Args: prc_value: 当前PRC值 vd_value: 当前VD值 hd_value: 当前HD值 cycle_detected: 是否检测到周期 Returns: distraction_type: 分心类型 分类逻辑: 1. PRC<60% + HD↑ → 视觉分心 2. 周期性 + VD↑ → 认知分心 3. 两者都有 → 混合分心 """ visual_indicators = ( prc_value < self.prc_low and hd_value > 8.0 ) cognitive_indicators = ( cycle_detected and vd_value > self.vd_high ) if visual_indicators and cognitive_indicators: return DistractionType.COMBINED elif visual_indicators: return DistractionType.VISUAL elif cognitive_indicators: return DistractionType.COGNITIVE else: return DistractionType.NONE def detect( self, gaze_angles: np.ndarray ) -> CognitiveDistractionState: """ 完整检测流程 Args: gaze_angles: 视线角度序列 Returns: state: 认知分心状态 """ road_center = determine_road_center(gaze_angles) window_size = min(self.window_size, len(gaze_angles)) prc_values = [] vd_values = [] hd_values = [] for i in range(0, len(gaze_angles) - window_size, window_size // 10): window = gaze_angles[i:i+window_size] prc = calculate_prc(window, road_center) hd, vd = calculate_gaze_dispersion(window) prc_values.append(prc) vd_values.append(vd) hd_values.append(hd) prc_sequence = np.array(prc_values) vd_sequence = np.array(vd_values) hd_sequence = np.array(hd_values) current_prc = np.mean(prc_sequence[-5:]) current_vd = np.mean(vd_sequence[-5:]) current_hd = np.mean(hd_sequence[-5:]) cycle_detected, cycle_strength = self.detect_cognitive_cycle( prc_sequence, vd_sequence ) distraction_type = self.classify_distraction( current_prc, current_vd, current_hd, cycle_detected ) confidence = cycle_strength if cycle_detected else 0.5 return CognitiveDistractionState( distraction_type=distraction_type, prc_value=current_prc, vd_value=current_vd, hd_value=current_hd, cycle_detected=cycle_detected, confidence=confidence )
if __name__ == "__main__": detector = CognitiveDistractionDetector() np.random.seed(42) gaze_sequence = [] for cycle in range(10): concentrated = np.random.randn(90, 2) * 3 gaze_sequence.extend(concentrated.tolist()) dispersed = np.random.randn(150, 2) * 6 dispersed[:, 1] *= 1.5 gaze_sequence.extend(dispersed.tolist()) gaze_angles = np.array(gaze_sequence) state = detector.detect(gaze_angles) print(f"分心类型: {state.distraction_type.value}") print(f"PRC: {state.prc_value:.1f}%") print(f"VD: {state.vd_value:.2f}°") print(f"HD: {state.hd_value:.2f}°") print(f"周期检测: {state.cycle_detected}") print(f"置信度: {state.confidence:.2f}")
|