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
| """ 反扫视任务 (Antisaccade Task) → 驾驶员认知分心检测
ADHD研究发现:反扫视错误率高 = 抑制控制差 = 注意力网络功能降低
迁移到驾驶场景: 正常驾驶:出现路边刺激 → 自动看向(prosaccade) 分心驾驶:出现路边刺激 → 应抑制但无法抑制 → 反扫视错误
认知分心 = 抑制能力下降 = 扫视控制异常 """
import numpy as np
class CognitiveDistractionEyeMetrics: """ 基于眼动神经科学的认知分心检测 核心假设: 认知分心 → 注意力网络功能降低 → 眼动控制指标变化 指标: 1. 凝视稳定性(微扫视频率/幅度) 2. 扫视抑制(非目标方向扫视次数) 3. 追踪增益(平滑追踪精度) 4. 扫视潜伏期(反应时间) """ def __init__(self, fps: int = 30): self.fps = fps def compute_gaze_stability( self, gaze_x: np.ndarray, gaze_y: np.ndarray, fixation_threshold: float = 50 ) -> dict: """ 凝视稳定性分析 正常:微扫视幅度小、频率稳定 认知分心:微扫视增多、幅度增大、稳定性下降 """ dx = np.diff(gaze_x) dy = np.diff(gaze_y) speed = np.sqrt(dx**2 + dy**2) microsaccades = np.sum((speed > 5) & (speed < fixation_threshold)) fixation_stability = np.std(gaze_x) + np.std(gaze_y) fixation_periods = self._detect_fixations(gaze_x, gaze_y, fixation_threshold) mean_fixation_duration = np.mean(fixation_periods) if fixation_periods else 0 return { 'microsaccade_count': microsaccades, 'microsaccade_rate': microsaccades / (len(gaze_x) / self.fps / 60), 'fixation_stability': fixation_stability, 'mean_fixation_duration_ms': mean_fixation_duration * 1000 / self.fps, 'gaze_entropy': self._compute_entropy(gaze_x, gaze_y) } def compute_saccade_inhibition( self, gaze_x: np.ndarray, gaze_y: np.ndarray, road_center: tuple = (0, 0) ) -> dict: """ 扫视抑制分析 正常驾驶:偶尔看向后视镜/仪表盘(自主扫视) 认知分心:非目标方向扫视增多(抑制能力下降) 类比反扫视任务: 刺激出现 → 应保持注视道路 → 但无法抑制 → 扫向刺激 """ dist_from_road = np.sqrt( (gaze_x - road_center[0])**2 + (gaze_y - road_center[1])**2 ) off_road_threshold = 100 off_road_count = np.sum(dist_from_road > off_road_threshold) saccade_latencies = self._compute_saccade_latencies( gaze_x, gaze_y, road_center ) return { 'off_road_count': off_road_count, 'off_road_ratio': off_road_count / len(gaze_x), 'mean_saccade_latency_ms': np.mean(saccade_latencies) if saccade_latencies else 0, 'inhibition_failure_rate': off_road_count / (len(gaze_x) / self.fps / 60) } def compute_pursuit_gain( self, gaze_x: np.ndarray, target_x: np.ndarray ) -> dict: """ 平滑追踪增益 正常:追踪增益~1.0(眼睛跟随目标) 认知分心:追踪增益下降(眼睛跟不上目标) 驾驶场景:跟随前方车辆/弯道 """ eye_vel = np.diff(gaze_x) * self.fps target_vel = np.diff(target_x) * self.fps moving = np.abs(target_vel) > 10 if np.sum(moving) == 0: return {'pursuit_gain': 1.0, 'pursuit_error': 0} gain = np.mean(eye_vel[moving] / (target_vel[moving] + 1e-8)) error = np.mean(np.abs(gaze_x[1:][moving] - target_x[1:][moving])) return { 'pursuit_gain': gain, 'pursuit_error': error, 'cognitive_load_indicator': 1.0 - min(gain, 1.0) } def _detect_fixations(self, x, y, threshold): """检测注视期""" fixations = [] start = 0 for i in range(1, len(x)): dist = np.sqrt((x[i]-x[start])**2 + (y[i]-y[start])**2) if dist > threshold: fixations.append(i - start) start = i return fixations def _compute_entropy(self, x, y, n_bins=10): """二维熵""" hist, _, _ = np.histogram2d(x, y, bins=n_bins) hist = hist / hist.sum() hist = hist[hist > 0] return -np.sum(hist * np.log2(hist)) def _compute_saccade_latencies(self, x, y, center): """计算扫视潜伏期""" latencies = [] dist = np.sqrt((x - center[0])**2 + (y - center[1])**2) off_road = dist > 100 for i in range(1, len(off_road)): if off_road[i] and not off_road[i-1]: start = i for j in range(i, min(i+150, len(off_road))): if not off_road[j]: latencies.append((j - start) * 1000 / self.fps) break return latencies
if __name__ == "__main__": np.random.seed(42) n_frames = 30 * 60 detector = CognitiveDistractionEyeMetrics(fps=30) alert_x = np.random.normal(0, 10, n_frames) alert_y = np.random.normal(0, 8, n_frames) distracted_x = np.random.normal(0, 25, n_frames) distracted_y = np.random.normal(0, 20, n_frames) for _ in range(15): idx = np.random.randint(0, n_frames) distracted_x[idx:idx+10] += np.random.uniform(-80, 80) print("=== 正常驾驶 ===") stability = detector.compute_gaze_stability(alert_x, alert_y) inhibition = detector.compute_saccade_inhibition(alert_x, alert_y) for k, v in {**stability, **inhibition}.items(): print(f" {k}: {v:.2f}") print("\n=== 认知分心 ===") stability_d = detector.compute_gaze_stability(distracted_x, distracted_y) inhibition_d = detector.compute_saccade_inhibition(distracted_x, distracted_y) for k, v in {**stability_d, **inhibition_d}.items(): print(f" {k}: {v:.2f}")
|