使用OpenCV、C++和2D图像进行头部姿态估计 - 几何方法 - 滚动、偏航和俯仰。

8
我正在尝试基于2D图像2D image找到一个人脸的三个角度,使用OpenCV和HaarCascade来查找脸部、眼睛、鼻子和嘴巴。但我没有找到可以帮助我找到X、Y和Z(横滚、俯仰和偏航)角度的任何几何方法。请问是否有人可以提供一些在C++或Java中有效的方法?

这不是一个C++问题,所以我删除了那个标签。 - Mark B
3个回答

5
给定一张图片和没有其他信息,没有单一的角度解决方案。考虑只有偏航的情况。在2d平面上投影,这可见为眼睛与鼻子/嘴巴位置之间的投影距离的微小变化。然而,这个距离在人与人之间并不是恒定的。
一种典型的解决方法是要求用户通过直视相机来“校准”他们的脸以获取名义“0”角度。此时,您现在可以参考长度来比较后续图像。
然而,这些长度信息仍不足够,因为显然的投影距离变化量取决于光学和面部与相机的距离。通常手动配置光学;您可以通过假设“平均”面部尺寸并假设“标称”图像完美匹配这些尺寸来估计距离。如果发现对于特定的面部它正在过高或者过低地估计旋转,则可以进行调整。
一旦您制定了所有这些假设,就可以使用相当简单的几何方法。您可以通过从眼睛到鼻子到嘴巴的线来估计翻滚。您可以测量眼睛之间的间距来估计偏航。最后,您可以使用眼睛/嘴巴或眼睛/鼻子之间的间距来估计俯仰。请记住,当面部仍相对接近标称时,这些假设效果最佳。

但我想知道在C++中实现这个的一些方法。 - John Smith

0

所以,您想根据鼻子、眼睛和嘴的位置来确定面部的方向(用RPY角度表示)。假设这三个(四个-两只眼睛)都是可见的,我会使用脸部的对称特征来确定头部的方向,例如:

可以使用眼睛之间的一条线作为一个轴的参考(例如俯仰角)。然后,我们可以假设滚转轴指向鼻子的方向-可以通过鼻子到眼睛中点的位置位移来测量。最后,偏航角可以通过眼睛中点、鼻子位置和嘴巴位置之间的距离关系来测量。

我不知道这四个感兴趣的点之间的距离关系,它们可能因性别、年龄和出生地而异。但是,如果您能找到这样的关系,那么角度的推导在数学上应该相当简单。

顺便说一下,这是一个有趣的应用!


0
如果您使用级联分类器来检测右眼、左眼和鼻子,计算每个特征的质心(特征x/2,特征y/2),这将在图像上给您三个x-y点。
您可以通过查看每只眼睛的Y值来检测滚动,如果一只眼睛的Y值比另一只高,这意味着头部向最低Y值的方向倾斜(因为一只眼睛向上移动,另一只眼睛向下移动)。
您可以通过查看鼻子的X值来检测偏航,如果用户向左看,鼻子的X值将更接近其左眼的X值,向右看时与右眼的X值相同。
您可以通过查看鼻子的Y值来检测俯仰,如果用户向上看,Y值将更接近两只眼睛的Y值,如果他们向下看,Y值将远离眼睛的值。
现在,这当然不是非常准确的,也不会给您精确的角度,但是您可以使用此信息尝试将每个值分类到某些组中,即(向前看,向左看,向真正左看)。
我唯一能看到影响你在一张图片中计算所有三个角度的事情可能是,如果旋转相当大,计算偏航角可能会有困难,因为X轴不再平坦。
你可以通过进行2D旋转来解决这个问题。 你需要找出需要旋转图像的程度。
Value = (right eye Y / 2) - (left eye Y / 2)

有了这些信息,您可以纠正图像并继续处理(要旋转图像,请查找创建2D旋转矩阵并使用warp affine的方法)

如果这有点过时,我很抱歉,但我发现上述方法非常成功,希望能帮助到某些人


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接