手把手教你用Python实现简易视线追踪系统(基于MPIIGaze数据集)

张开发
2026/4/16 17:41:07 15 分钟阅读

分享文章

手把手教你用Python实现简易视线追踪系统(基于MPIIGaze数据集)
手把手教你用Python实现简易视线追踪系统基于MPIIGaze数据集视线追踪技术正在从实验室走向日常生活成为人机交互领域的重要研究方向。想象一下当你浏览网页时屏幕能自动滚动到你正在注视的区域或者玩游戏时角色能跟随你的视线移动——这些场景的实现都离不开视线追踪技术。本文将带你从零开始用Python构建一个简易的视线追踪系统特别适合想要快速实现demo效果的开发者。我们将使用MPIIGaze这个真实世界数据集它包含了超过21万张在不同光照条件下采集的眼部图像。与学术论文不同本文聚焦于可落地的代码实践通过OpenCV和Dlib等基础库实现核心功能。即使你刚接触计算机视觉也能跟随教程完成这个有趣的项目。1. 环境准备与数据加载在开始编码前我们需要搭建开发环境。推荐使用Python 3.8和以下库pip install opencv-python dlib numpy matplotlib scikit-learn tensorflowMPIIGaze数据集需要从官网申请下载包含以下关键文件MPIIGaze.h5存储所有图像和标注Evaluation Subset.h5测试集Preprocessed Data.h5预处理后的数据加载数据的Python代码如下import h5py def load_data(data_path): with h5py.File(data_path, r) as f: images f[Data][image][:] labels f[Data][gaze][:] landmarks f[Data][landmarks][:] return images, labels, landmarks注意MPIIGaze数据集的标注格式为(pitch, yaw)角度值单位为弧度。在可视化时需要转换为度数。2. 数据预处理与特征提取原始图像需要经过标准化处理才能输入模型。关键步骤包括人脸检测与对齐使用Dlib的68点人脸特征检测器眼部区域裁剪根据特征点定位眼睛位置图像归一化调整大小、灰度化和直方图均衡化import cv2 import dlib def preprocess_image(image, detector, predictor): gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) faces detector(gray) if len(faces) 0: return None landmarks predictor(gray, faces[0]) left_eye get_eye_region(landmarks, 36, 42) # 左眼特征点索引 right_eye get_eye_region(landmarks, 42, 48) # 右眼特征点索引 # 合并双眼图像 eyes cv2.hconcat([left_eye, right_eye]) return cv2.equalizeHist(eyes)预处理后的眼部图像尺寸建议统一为64×32像素。我们可以将处理后的数据保存为Numpy数组加速后续训练np.savez(preprocessed_data.npz, XX_processed, yy_labels)3. 构建视线估计模型我们将实现一个轻量级的CNN模型适合在普通CPU上运行from tensorflow.keras import layers, models def build_gaze_model(input_shape(32, 64, 1)): model models.Sequential([ layers.Conv2D(32, (3,3), activationrelu, input_shapeinput_shape), layers.MaxPooling2D((2,2)), layers.Conv2D(64, (3,3), activationrelu), layers.MaxPooling2D((2,2)), layers.Flatten(), layers.Dense(128, activationrelu), layers.Dense(2) # 输出pitch和yaw角度 ]) model.compile(optimizeradam, lossmse, metrics[mae]) return model模型训练时需要注意以下几点使用20%数据作为验证集添加Early Stopping防止过拟合学习率采用余弦衰减策略from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau callbacks [ EarlyStopping(patience10, restore_best_weightsTrue), ReduceLROnPlateau(factor0.5, patience3) ] history model.fit( X_train, y_train, validation_split0.2, epochs50, batch_size32, callbackscallbacks )4. 实时视线追踪实现将训练好的模型应用到实时视频流中完整流程如下初始化摄像头逐帧检测人脸和眼睛预处理眼部图像使用模型预测视线方向可视化结果def realtime_gaze_tracking(model, camera_id0): cap cv2.VideoCapture(camera_id) detector dlib.get_frontal_face_detector() predictor dlib.shape_predictor(shape_predictor_68_face_landmarks.dat) while True: ret, frame cap.read() if not ret: break processed preprocess_image(frame, detector, predictor) if processed is not None: prediction model.predict(processed[np.newaxis, ..., np.newaxis]) pitch, yaw prediction[0] draw_gaze(frame, pitch, yaw) # 绘制视线方向 cv2.imshow(Gaze Tracking, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()实现视线方向可视化时可以在屏幕上绘制一个动态变化的箭头def draw_gaze(image, pitch, yaw, length100): height, width image.shape[:2] center (width//2, height//2) # 将角度转换为2D向量 x -length * np.sin(yaw) * np.cos(pitch) y -length * np.sin(pitch) end_point (int(center[0] x), int(center[1] y)) cv2.arrowedLine(image, center, end_point, (0,255,0), 2)5. 性能优化与实用技巧提升系统实时性和准确性的几个关键方法模型轻量化使用TensorFlow Lite转换模型采用量化技术减小模型体积尝试MobileNet等轻量架构converter tf.lite.TFLiteConverter.from_keras_model(model) tflite_model converter.convert() with open(gaze_model.tflite, wb) as f: f.write(tflite_model)数据处理优化使用多线程预处理视频帧实现帧缓冲机制避免卡顿采用ONNX Runtime加速推理import threading from queue import Queue frame_queue Queue(maxsize3) def capture_thread(cap, queue): while True: ret, frame cap.read() if ret: queue.put(frame)精度提升技巧添加头部姿态补偿实现个性化校准使用滑动窗口平滑预测结果实际部署时我发现最影响用户体验的是预测结果的抖动问题。通过实现一个简单的指数移动平均滤波器可以显著提升视觉体验class GazeSmoother: def __init__(self, alpha0.3): self.alpha alpha self.prev_pitch 0 self.prev_yaw 0 def smooth(self, pitch, yaw): smooth_pitch self.alpha * pitch (1-self.alpha) * self.prev_pitch smooth_yaw self.alpha * yaw (1-self.alpha) * self.prev_yaw self.prev_pitch, self.prev_yaw smooth_pitch, smooth_yaw return smooth_pitch, smooth_yaw这个简易系统在普通笔记本摄像头下的运行效果能达到约5度的平均误差对于demo展示和初步研究已经足够。如果需要更高精度可以考虑使用更深的网络结构或引入注意力机制。

更多文章