我试图根据 2D 图像找到人脸的三个角度。
我正在使用带有 HaarCascade 的 OpenCV 来查找脸部、眼睛、鼻子和嘴巴。但我没有找到任何几何方法可以帮助我找到角度 X、Y 和 Z(Roll、Pitch 和 Yaw)。
有人可以帮我展示一些在 c++ 或 java 中有效的方法吗?
我试图根据 2D 图像找到人脸的三个角度。
我正在使用带有 HaarCascade 的 OpenCV 来查找脸部、眼睛、鼻子和嘴巴。但我没有找到任何几何方法可以帮助我找到角度 X、Y 和 Z(Roll、Pitch 和 Yaw)。
有人可以帮我展示一些在 c++ 或 java 中有效的方法吗?
给定一个图像而没有其他信息,角度没有单一的解决方案。考虑只是 Yaw 的情况。投影到 2d 平面上,可以看到眼睛之间的投影距离和眼睛相对于鼻子/嘴巴的位置的微小变化。然而,这个距离在人与人之间并不是一个常数。
解决此问题的一种典型方法是要求用户通过直视相机的标称“0”角度来“校准”他们的脸。此时,您现在有了可以比较后续图像的参考长度。
然而,长度仍然不是足够的信息,因为表观投影距离的变化量取决于光学元件和面部与相机的距离。您通常手动配置的光学器件;您可以通过假设“平均”面部尺寸并假设“标称”图像与这些尺寸完美匹配来估计的距离。如果您发现它高估或低估了特定面的旋转,您可以调整它。
一旦你有了所有这些假设,它就是相当简单的几何图形。您可以估计从眼睛到鼻子到嘴巴的线的滚动。您可以测量眼睛之间的间距以估计偏航。最后,您可以使用眼睛/嘴巴或眼睛/鼻子之间的间距来估算音高。请记住,当面部仍然非常接近名义时,这些假设效果最好。
如果您使用级联分类器检测右眼、左眼和鼻子,计算每个特征的质心(特征 x/2,特征 y/2),这将在图像上给出三个 xy 点。
您可以通过查看每只眼睛的 Y 值来检测滚动,如果一只眼睛高于另一只,则表示头部朝最低 Y 值的方向倾斜(一只眼睛向上移动,另一只眼睛向下移动)
您可以通过查看鼻子的X值来检测偏航,如果用户向左看,他们的鼻子的X值将更接近他们左眼的X值,与向右看右眼的X值相同价值。
您可以通过查看鼻子的 Y 值来检测俯仰,如果用户向上看,Y 值将更接近双眼 Y 值,如果他们向下看,Y 值将更远离眼睛值。
现在这当然不是非常准确并且不会为您提供确切的角度,但是您可以使用此信息尝试对某些组中的每个值进行分类,即(向前看、向左看、向左看)
我唯一能看到影响您在一张图像中计算所有三个可能是如果滚动相当剧烈,计算偏航可能会很麻烦,因为 X 轴不再平坦。
您可以通过 2D 旋转校正图像来解决此问题。您将需要找到图像需要旋转多少
Value = (right eye Y / 2) - (left eye Y / 2)
使用此信息,您可以校正图像并继续处理(旋转图像查找创建 2D 旋转矩阵并使用变形仿射)
抱歉,如果这有点死,但我发现上述方法非常成功,希望对某人有所帮助
因此,您希望根据鼻子、眼睛和嘴巴的位置来确定人脸的方向(以 RPY 角度表示)。假设所有三个(四 - 两只眼睛)都是可见的,我会使用面部的对称特征来确定头部的方向,例如:
眼睛之间的一条线可以用作其中一个轴(例如 Pitch)的参考。然后,我们可以假设 Roll 轴指向鼻子的方向——这可以通过鼻子到眼睛中点的位置位移来测量。最后,可以通过眼睛中点、鼻子位置和嘴巴位置之间的距离关系来测量偏航角。
我不知道这四个兴趣点之间的距离关系,他们可能在性别、年龄和出身方面有所不同。然而,如果你能找到这样的关系,角度的推导在数学上应该是相当直接的。
顺便说一句有趣的应用程序!