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
| """ Inverted-U Alpha 模型复现
论文提出Alpha功率与走神呈倒U型关系: - 低Alpha(睁眼典型) → Alpha增加 = 走神增加 - 高Alpha(闭眼典型) → Alpha增加 = 走神减少
对IMS的启示: 1. 不能用单一Alpha阈值判断走神 2. 必须先检测眼睛状态,再解读Alpha含义 3. DMS摄像头可以检测眼睛开闭 → 为EEG替代方案提供可能 """
import numpy as np
class EyeStateAwareDistractionDetector: """ 基于眼状态的认知分心检测器 核心原理: - 眼睛开闭状态决定Alpha波含义 - 睁眼+高Alpha → 走神(需警告) - 闭眼+高Alpha → 专注(不需警告) IMS替代方案: - 无EEG时用眨眼率+PERCLOS+扫视熵组合 - 眼动模式可间接反映Alpha状态 """ def __init__(self): self.alpha_threshold_open = 0.6 self.alpha_threshold_closed = 0.8 self.eye_openness_threshold = 0.3 self.blink_rate_baseline = 15 self.blink_rate_distraction = 25 self.saccade_entropy_normal = 2.0 self.saccade_entropy_low = 1.2 def detect_cognitive_distraction(self, eye_data: np.ndarray) -> dict: """ 基于眼状态感知的认知分心检测 Args: eye_data: shape=(N, 4), 列=[eye_openness, gaze_x, gaze_y, pupil_diameter] N = 30fps * 60s = 1800 Returns: result: { 'eye_state': 'open'/'closed'/'blinking', 'distraction_level': 0-3, 'distraction_type': str, 'confidence': float, 'indicators': dict } """ eye_openness = eye_data[:, 0] gaze_x, gaze_y = eye_data[:, 1], eye_data[:, 2] pupil_d = eye_data[:, 3] avg_openness = np.mean(eye_openness) if avg_openness < self.eye_openness_threshold: eye_state = 'closed' elif avg_openness > 0.7: eye_state = 'open' else: eye_state = 'blinking' blink_events = np.diff((eye_openness < self.eye_openness_threshold).astype(int)) blink_count = np.sum(blink_events == -1) blink_rate = blink_count / (len(eye_openness) / 30 / 60) hist, _, _ = np.histogram2d(gaze_x, gaze_y, bins=10, range=[[-1,1],[-1,1]]) hist = hist / (hist.sum() + 1e-8) saccade_entropy = -np.sum(hist * np.log(hist + 1e-8)) pupil_var = np.std(pupil_d) gaze_offset = np.sqrt(gaze_x**2 + gaze_y**2) gaze_offset_ratio = np.mean(gaze_offset > 0.5) if eye_state == 'open': distraction_score = 0.0 if blink_rate > self.blink_rate_distraction: distraction_score += 0.3 * min((blink_rate - self.blink_rate_distraction) / 20, 1.0) if saccade_entropy < self.saccade_entropy_low: distraction_score += 0.4 * (1 - saccade_entropy / self.saccade_entropy_normal) distraction_score += 0.3 * gaze_offset_ratio distraction_type = "视觉分心" if gaze_offset_ratio > 0.3 else "认知走神" elif eye_state == 'closed': closure_duration = np.sum(eye_openness < self.eye_openness_threshold) / 30 if closure_duration > 3: distraction_score = min(closure_duration / 10, 1.0) distraction_type = "微睡眠/疲劳" else: distraction_score = 0.1 distraction_type = "内部思考(不需干预)" else: distraction_score = 0.3 distraction_type = "过渡状态(频繁眨眼)" if distraction_score < 0.3: level = 0 elif distraction_score < 0.5: level = 1 elif distraction_score < 0.7: level = 2 else: level = 3 return { 'eye_state': eye_state, 'distraction_level': level, 'distraction_type': distraction_type, 'confidence': round(distraction_score, 3), 'indicators': { 'blink_rate': round(blink_rate, 1), 'saccade_entropy': round(saccade_entropy, 3), 'pupil_var': round(float(pupil_var), 3), 'gaze_offset_ratio': round(float(gaze_offset_ratio), 3), 'avg_openness': round(float(avg_openness), 3) } }
if __name__ == "__main__": np.random.seed(42) det = EyeStateAwareDistractionDetector() eye_open = np.column_stack([ np.random.normal(0.85, 0.05, 1800), np.random.normal(0, 0.1, 1800), np.random.normal(0, 0.1, 1800), np.random.normal(3.5, 0.15, 1800) ]) for i in range(0, 1800, 20): eye_open[i:i+3, 0] = 0.1 r1 = det.detect_cognitive_distraction(eye_open) print(f"睁眼走神: Level {r1['distraction_level']} - {r1['distraction_type']} (conf={r1['confidence']})") print(f" 眨眼率={r1['indicators']['blink_rate']}, 扫视熵={r1['indicators']['saccade_entropy']}") eye_closed = np.column_stack([ np.random.normal(0.15, 0.02, 1800), np.zeros(1800), np.zeros(1800), np.random.normal(2.5, 0.1, 1800) ]) r2 = det.detect_cognitive_distraction(eye_closed) print(f"\n闭眼专注: Level {r2['distraction_level']} - {r2['distraction_type']} (conf={r2['confidence']})") eye_microsleep = eye_closed.copy() eye_microsleep[:, 0] = 0.05 r3 = det.detect_cognitive_distraction(eye_microsleep) print(f"\n微睡眠: Level {r3['distraction_level']} - {r3['distraction_type']} (conf={r3['confidence']})")
|