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

Roh*_*han 5 ios scenekit swift face arkit

我正在尝试使用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;
};
Run Code Online (Sandbox Code Playgroud)

以下是我的代码;

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)) " )
}
Run Code Online (Sandbox Code Playgroud)

而作为leftcaTransform3DValue的结果,我得到的值就像;

m11 =  -5.22553711590422e-315
...
...
...
m44 =   2.13285635582599e-314
Run Code Online (Sandbox Code Playgroud)

对于rightcaTransform3DValue也是如此.

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

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

任何帮助都非常感谢.

ric*_*ter 5

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

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

blendShapes字典上ARFaceAnchor被记录为具有类型的值NSNumber,其中的底层数值NSNumber是0.0和1.0之间的浮动.

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

NSNumber是一个子类NSValue,它是多种类型的对象包装器,不能表示为对象 - 范围,大小,指针和3D转换矩阵等.这些类型不能像数字一样在彼此之间进行转换,因此唯一有意义NSValue的类型是从它创建的类型.任何其他类型给你废话.

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

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

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

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

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

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

问题:

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

所以,尽管你可以通过一些实验来确定哪个顶点是左眼的内角,左眼的外角等等.一旦你这样做,你可以看看它们的位置来估计有用的数量,如眼睛宽度,瞳孔间距等等.但是,这些测量是基于可能并不总是保持的网格假设,因此您不知道应用程序的用户什么时候会中断.