这篇文章主要介绍MPIIGaze: Real-World Dataset and Deep Appearance-Based Gaze Estimation这篇论文实现3d gaze vector的细节。
主要贡献
- 我觉得这篇论文最大贡献就是公开了Gaze数据集, 这个数据集包含213,659 张图片, 这些图片是从15个笔记本摄像头上采集下来的, 整个采集周期跨了好几个月, 包含了各种光照场景,作者手工标注了37,667 张人脸6点landmark和瞳孔数据。
- 作者对比了MPII gaze数据集与EYEDIAP和 UT Multiview 公开数据集的差别, 验证了数据集gaze 区间,光照和人员自身差别可以对结果有很大影响。
- 最后一点是基于VGG提出了GazeNet这种网络结构。
MPII Gaze 网络结构
这个网络的输入是眼睛图片和headpose(图中的h), 注意图片经过13层卷积操作后flatten后与headpose数据concate,然后回归成gaze vector, 这里使用的headpose是归一化坐标系下的pitch和yaw, 输出的gaze vector本来应该是一个3维向量, 这里用极坐标表示只剩下两个值pitch和yaw。
数据采集
- 在自愿者电脑上安装数据采集软件, 每隔10分钟程序弹出界面,并随机绘制20个点, 当这个点快消失时自愿者就要按下空格键,保存此时摄像头拍摄的图片,注意,为了保证志愿者按下按键的时候的确在看这些点,采集软件只会捕获点消失前500ms时间窗口的按键信息, 也就是说,点消失前500ms内如果没有按键,那么这次采集就要重新来过,只有这样才能保障数据的正确性。
- 采集步骤1只能捕获人眼的图片,但是从前面的网络结构可以看出,网络的输入是眼睛图片+headpose+gaze vector。如果想获取一个ground truth 的gaze vector, 先要知道你看的目标点的3d坐标p1, 你眼睛坐标p2, 那么p1-p2就是你视线的方向。那么对于志愿者在看屏幕点时,怎么知道此时此刻这个人眼睛坐标呢?注视目标的坐标呢?怎么知道此时人头的headpose呢?作者是这么解决的:
a. 注释目标3d位置确认
首先标定笔记本电脑的内参K, 然后通过镜子反射的方法(参考论文Camera pose estimation using images of planar mirror reflections )标定相机坐标系与屏幕坐标系的转换矩阵T, 注意,由于笔记本电脑的摄像头是拍不到笔记本自己的屏幕的,所以只能用镜子将屏幕上的点反射到相机的视野中,曲线救国。。。有了上面的矩阵T就可以知道笔记本屏幕每个点(前面说的p1点)在相机坐标系下的坐标了。
b. 人眼3d坐标和headpose的确定
接下来,用双目相机将这些自愿者的3d人脸模型录制下来,再将他们的人脸模型平均yi下,建立一个标准3d人脸。每张图片用landmark detector来检测下,做个预标记,再人肉修正下检测错误的点。这里手上就有了3d 标准人脸模型和2d的6点 face landmark, 这时就可以使用SolvePnP方法来计算此时人脸这6点landmark在相机坐标系下的位置了。
这里先看下OpenCV的solvePnP函数:
输入objectPoints就是3d 标准人脸, imagePoints就是自动+人肉标注的2d landmark, cameraMatrix是相机的内参矩阵,distCoeffs是相机的畸变参数, 这两位在前面的相机标定步骤就可以获取, 返回的rvec和tvec就是标准人脸坐标系到相机坐标系转换时需要的旋转矩阵和平移向量,经过旋转和平移,就能得到相机坐标系下人脸6点landmark对应的3d坐标。那么把两眼的内外眼角坐标平均下就能得到视线的起始位置p2. solvePnP返回的rvec就是此时的headpose。另外一点需要注意的是,作者定义的3d face原点在右眼。
经过不懈的努力,最终采集到了带有标注信息的图片。
按照采集日期,图像intensity和灰度值差异分:
与其他数据集gaze和headpose的角度分布对比:
好了,现在数据集有了,是不是可以开始训练网络了呢?当然不是,在训练之前还要对数据做归一化操作。
数据归一化
注意,我们现在讨论的是如何解决头部无约束情况下的3d gaze vector问题,头部无约束是指你的人头可以在相机任意位置,近点,远点,偏左,偏右。。人头有6个自由度[tx, ty, tz, rx, ry, rz], 3个平移,3个旋转自由度。这么多自由度对于网络是个挑战,所以作者提出了将图像和标签(gaze vector, headpose)进行归一化的操作。
- 首先原相机坐标系经过旋转操作使x轴与人头坐标系的x轴平行并且z轴指向人眼中心(下图ab),然后通过缩放矩阵S将相机拉到离人眼ds距离,最后通过透视变换将眼睛拉正抠出来。此时可以获取一个正视人眼的图片, 同时gaze vector, headpose也同样经过旋转矩阵R的变换,转换到归一化坐标系下。
模型验证
有了上面归一化坐标系下的眼睛图片+headpose+gaze vector,就可以开始网络训练了。数据集内leave one person out的训练结果差不多5度左右。
最后各种对比的结果大致如下:
- headpose作为网络的一个输入能提高gaze vector时输出精度
- cross dataset的验证效果比数据集内结果差
- 双眼比单眼效果好
- 瞳孔中心信息的输入对结果影响不大
欢迎关注公众号:OpenCV图像处理