可以使用CATransform3D来获取Face Mesh中的眼睛尺寸吗?

时间:2018-05-11 06:38:28

标签: ios swift scenekit arkit face

我正在尝试使用ARKit的3D Face Mesh获得眼睛的宽度和2只眼睛的距离。

我使用了 ARAnchor CATransform3D ;

 struct CATransform3D
{
  CGFloat m11, m12, m13, m14;
  CGFloat m21, m22, m23, m24;
  CGFloat m31, m32, m33, m34;
  CGFloat m41, m42, m43, m44;
};

以下是我的代码;

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {

guard let faceAnchor = anchor as? ARFaceAnchor else { return }

let leftcaTransform3DValue : CATransform3D = (faceAnchor.blendShapes[.eyeBlinkLeft]?.caTransform3DValue)!

let rightcaTransform3DValue : CATransform3D = (faceAnchor.blendShapes[.eyeBlinkRight]?.caTransform3DValue)!

print("  m11 : \(String(describing:leftcaTransform3DValue.m11)) m12 : \(String(describing:leftcaTransform3DValue.m12)) m13 : \(String(describing:leftcaTransform3DValue.m13)) m14 : \(String(describing:leftcaTransform3DValue.m14)) m21 : \(String(describing:leftcaTransform3DValue.m21)) m22 : \(String(describing:leftcaTransform3DValue.m22)) m23 : \(String(describing:leftcaTransform3DValue.m23)) m24 : \(String(describing:leftcaTransform3DValue.m24)) m31 : \(String(describing:leftcaTransform3DValue.m31)) m32 : \(String(describing:leftcaTransform3DValue.m32)) m33 : \(String(describing:leftcaTransform3DValue.m33)) m34 : \(String(describing:leftcaTransform3DValue.m34)) m41 : \(String(describing:leftcaTransform3DValue.m41)) m42 : \(String(describing:leftcaTransform3DValue.m42)) m43 : \(String(describing:leftcaTransform3DValue.m43)) m44 : \(String(describing:leftcaTransform3DValue.m44)) " )
}

由于 leftcaTransform3DValue ,我得到了类似的值;

m11 =  -5.22553711590422e-315
...
...
...
m44 =   2.13285635582599e-314

rightcaTransform3DValue 相同。

所以我的问题是这些值是否指定任何尺寸或尺寸测量?

我可以计算眼睛的宽度和两只眼睛之间的距离吗?

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:5)

  

所以我的问题是这些值是否指定任何尺寸或尺寸测量?

没有。你得到的数字是无稽之谈,因为你得到它们的方式是......也许不是废话,但非常接近。

ARFaceAnchor上的blendShapes字典被记录为具有NSNumber类型的值,其中NSNumber的基础数值是介于0.0和1.0之间的浮点数。

NSNumber是许多可能类型的标量数值的对象包装器。它具有将其基础值作为各种类型获取的方法(通过转换为相同数字的不同表示)。但鉴于这些特定数字被记录为介于0和1之间的浮点值,因此获取intValueboolValue等没有太大意义。

NSNumberNSValue的子类,它是许多类型的对象包装器,无法以其他方式表示为对象 - 范围,大小,指针和3D转换矩阵等等。这些类型不能像数字一样在彼此之间进行转换,因此从NSValue中获取的唯一有意义的类型就是它创建的类型。任何其他类型都会让你胡说八道。

回到blendShapes - 进一步记录了字典中的每个混合形状值不仅仅是一个数字,而是一个告诉你动画参数进度的数字。 eyeBlinkLeft并没有声称告诉你任何关于左眼的位置或大小的信息 - 它告诉你左眼睑是如何“眨眼”(闭合)的。

你正在咆哮错误的树,但如果你查看你正在使用的类和属性的文档,你将能够更好地在以后做出有根据的猜测。

  

我可以计算眼睛的宽度和两只眼睛之间的距离吗?

更新:在" ARKit 2",又称iOS 12中的ARKit,leftEyeTransformrightEyeTransform提供3D位置(相对于脸部)每个眼球中心的锚点。 (也是每只眼睛的方向。)这可能对你的用例有所帮助,但如果你实际使用的是与瞳孔的位置/大小或眼睛开口有关...

没有API会为你做这件事。 ARKit确实提供了您可以用来自己查找的信息,但不能保证始终有效。

ARFaceGeometry为您提供一个三角形网格,以一种在会话中拓扑稳定的方式映射面部上的几百个点。也就是说,例如,假设网格中的第57个顶点是鼻尖,即使面部皱折和伸展,该点​​也会停留在鼻尖上,并且该点相对于其他点的位置会发生变化。

问题:

  • API不会告诉您哪些顶点(网格中的点)是哪个(就像眼角,鼻尖等面部标记而言)。
  • 网格的拓扑在会话中是稳定的,但Apple并不保证它不会在iOS版本,设备等之间发生变化。

所以,虽然进行了一些实验,但你可能能够找出哪个顶点是左眼的内角,左眼的外角等等。一旦你这样做,你可以看看他们的位置来估计有用的数量,如眼睛宽度,瞳孔间距等。但是,这些测量是基于可能并不总是保持的网格假设,因此您不知道什么时候它会为您的应用程序的用户打破。