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
| import numpy as np from typing import Tuple, List
class SmartEyeTracker: """ Smart Eye 眼动追踪核心算法 基于深度学习的眼动特征提取 """ def __init__(self, model_path: str): self.face_detector = self._load_model('mtcnn.onnx') self.landmark_model = self._load_model('landmark_68.onnx') self.gaze_estimator = self._load_model('gaze_net.onnx') self.LEFT_EYE_INDICES = list(range(36, 42)) self.RIGHT_EYE_INDICES = list(range(42, 48)) def extract_features( self, frame_sequence: np.ndarray, features: List[str] ) -> dict: """ 提取眼动特征 Args: frame_sequence: 帧序列,shape=(N, H, W, 3) features: 需要提取的特征列表 Returns: feature_dict: 特征字典 """ feature_dict = {} gaze_vectors = [] blink_patterns = [] for frame in frame_sequence: face_box = self._detect_face(frame) if face_box is None: continue landmarks = self._get_landmarks(frame, face_box) left_eye = self._extract_eye_region(frame, landmarks, 'left') right_eye = self._extract_eye_region(frame, landmarks, 'right') gaze_vector = self._estimate_gaze(left_eye, right_eye) gaze_vectors.append(gaze_vector) blink = self._detect_blink(landmarks) blink_patterns.append(blink) gaze_vectors = np.array(gaze_vectors) blink_patterns = np.array(blink_patterns) if 'gaze_direction' in features: feature_dict['gaze_direction'] = np.mean(gaze_vectors, axis=0) feature_dict['gaze_variance'] = np.std(gaze_vectors, axis=0) if 'eye_nystagmus' in features: feature_dict['nystagmus_score'] = self._detect_nystagmus(gaze_vectors) if 'blink_pattern' in features: feature_dict['blink_rate'] = np.sum(blink_patterns) / len(blink_patterns) feature_dict['blink_interval_var'] = self._calc_blink_interval_var(blink_patterns) return feature_dict def _detect_nystagmus(self, gaze_vectors: np.ndarray) -> float: """ 检测眼球震颤(酒精中毒典型症状) 眼球震颤特征: 1. 快速、不自主的眼球运动 2. 水平方向震颤频率增加 3. 运动幅度异常 Args: gaze_vectors: 凝视向量序列 Returns: nystagmus_score: 震颤评分(0-1) """ gaze_delta = np.diff(gaze_vectors, axis=0) horizontal_amp = np.abs(gaze_delta[:, 0]) freq_spectrum = np.fft.fft(horizontal_amp) freqs = np.fft.fftfreq(len(horizontal_amp), d=1/30) mask = (np.abs(freqs) >= 2) & (np.abs(freqs) <= 10) nystagmus_energy = np.sum(np.abs(freq_spectrum[mask])) nystagmus_score = min(nystagmus_energy / 100.0, 1.0) return nystagmus_score
|