5 分钟跑通 eyetracker 开源眼动追踪
当你需要让一位无法移动手臂的用户只用眼睛完成网页浏览时,缺的往往不是鼠标替代方案,而是一个能把"注视位置"算出来的人机接口。eyetracker 就是干这件事的开源项目:它从摄像头拍摄的"眼睛 + 屏幕反光"图像里,实时计算你在屏幕上正盯着哪个点,并把这个点输出成可控制的光标。项目基于 openFrameworks 和 OpenCV,核心代码只有两个 C++ 文件,方便你读完整个视线追踪链路后,替换成自己的应用逻辑。
五分钟跑通
先说清环境:项目约 2012 年开发,依赖 OpenCV 2.x(约 2.3)和 openFrameworks 0.7,代码直接调用 OpenCV 2 时代的 cv.h 接口。系统要求 macOS 10.14+(Xcode 工程)或 Ubuntu 18.04+(用 openFrameworks 源码构建),硬件要求 720p 以上摄像头,代码按 640×480、60fps 采集设计。
- 克隆仓库:
git clone https://gitcode.com/gh_mirrors/ey/eyetracker,并把目录放到 openFrameworks 的examples/下 - 确认你的 openFrameworks 已启用
ofxOpenCv插件,OpenCV 版本为 2.x;在Project.xcconfig中把OF_PATH指向你本机的 openFrameworks 根目录 - 用 Xcode 打开
eyetracker.xcodeproj,选择 Debug 编译运行 - 首次运行时摄像头以 640×480 启动,窗口里先出现眼睛图像和瞳孔椭圆等调试层;按
m开启视线光标,屏幕上会出现由视线驱动的光标点
如果你机器上只有 OpenCV 4,cvCreateMat、CvSeq 这类接口在 4.x 已移除,需要按 2.x 版本重新编译 OpenCV 再链接,否则无法编译通过。
瞳孔检测与注视点计算是怎么算出来的
算法走的是瞳孔-角膜反射法(pupil-Perkins,Perkins 点指屏幕光在角膜上的镜面反光斑)。流程像"先找瞳孔中心,再看反光点偏了多远,两者一比就知道你往哪看":
- 在每帧图像里用直方图找灰度峰谷(
calcHistPeak)自动算二值化阈值,把暗区提取出来; - 对暗区做椭圆拟合得到瞳孔质心(
findPupil); - 在瞳孔周围固定半径内寻找最亮的反光点(
findPerkinje),并做排序平均以抗抖动; - 瞳孔中心与反光点的相对向量代表眼球转动量,先用相机-LED 透视映射(
calcPerspectiveMap)把反光点换算成"屏幕上的 LED 位置",再乘上校准阶段算出的透视矩阵,落成最终屏幕坐标。
为了应对头部移动,屏幕被切成了 3×3 的校准网格,每个格子对应一块独立的透视变换矩阵(calibration_datum 中的 mat 数组),而不是用一张全屏幕映射,这样局部误差不会扩散到整个画面。
关键文件速览
src/cvEyeTracker.h:主类cvEyeTracker的声明,以及校准数据(calibration_datum)、查找表(fLUT)等数据结构src/cvEyeTracker.cpp:约 2200 行,实现瞳孔检测、反光点查找、直方图阈值、透视映射与校准矩阵计算src/main.cpp:openFrameworks 入口,仅负责创建窗口并挂上主类Project.xcconfig:Xcode 构建配置,定义OF_PATH与 OpenCV 库的搜索路径eyetracker.xcodeproj:macOS 工程文件
九点校准流程与精度调优
校准交互直接由键盘驱动(见 cvEyeTracker.cpp 的 keyPressed):
- 启动后屏幕按 3×3 网格高亮,用方向键选中第一个校准点
- 注视该点并保持稳定,按回车记录当前平均注视坐标
- 移动到下一个校准点,重复步骤 1-2,直到九点全部记录
- 每记录一点,程序即重算该区域的透视矩阵(
calcCalibrationMap) - 按
m打开视线光标,在屏幕上移动视线验证校准效果
两条实操建议:
- 摄像头与眼睛保持 50-70 厘米、基本正对,不要斜对屏幕,否则反光点位置会系统性偏移
- 校准前先用开发层确认瞳孔椭圆稳定(按
a、e切换眼睛图像与椭圆显示),晃动剧烈时不要记录
Q:瞳孔识别不出来或频繁丢失? 多半是环境光太亮或摄像头没对准,先加强屏幕反光(靠近红外补光)再降低 h_manual_threshold。
Q:校准后光标在中心区域还是漂? 重新做一次九点校准,重点保证四角和中心五点各自停留时视线不移动。
能拿它做什么
- 无障碍视线控制:把输出的屏幕坐标喂给辅助功能框架,实现无手操作浏览;关键依赖是校准稳定性和抗抖动滤波
- 注视轨迹研究:录制 PoR(注视点)序列做界面热力图;依赖你自己在
bToggleRec相关代码上扩展日志格式 - 眼控创意装置:接入 openFrameworks 的图形/音频模块做交互作品;难度最低,改
main.cpp入口即可
局限与后续方向
项目自 2012 年后基本停更,README 也自述"work in progress",接口停留在 OpenCV 2.x,且没有现成的校准存储/加载逻辑,每次运行都要重做校准,头部大幅移动时精度会明显下降。后续演进方向大概率是:把校准结果持久化、用现代 OpenCV(或替换为直接视频流)重编译,以及在注视点输出上加一层平滑滤波。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



