CATransform3D能够用于在面部网格中获取眼睛尺寸吗?

6

我正在尝试使用ARKit的3D面部网格获取眼睛的宽度和两只眼睛之间的距离。

我已经使用了ARAnchorCATransform3D

 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个回答

5
所以我的问题是,这些值是否指定任何尺寸或大小测量? 不。你得到的数字是无意义的,因为你获取它们的方式可能不太对,或者说非常接近无意义。 在ARFaceAnchor上,blendShapes字典被记录为具有NSNumber类型的值,其中NSNumber的基础数值是介于0.0和1.0之间的浮点数。 NSNumber是许多标量数值的对象包装器。它有一些方法可以将其基础值作为各种类型进行提取(通过转换为相同数字的不同表示)。但是,考虑到这些特定数字被记录为介于0和1之间的浮点值,获取intValue或boolValue等并没有太多意义。

NSNumberNSValue的子类,它是许多不可用对象表示的类型(例如范围、大小、指针和3D变换矩阵)的对象包装器。这些类型无法像数字一样相互转换,因此从NSValue中提取的唯一有意义的类型是创建它的类型。任何其他类型都会给您带来无意义的结果。

回到blendShapes - 进一步说明每个字典中的混合形状值不仅仅是一个数字,而是告诉您动画参数进度的数字。eyeBlinkLeft并不会告诉您左眼在哪里或有多大 - 它告诉您左眼睑“闭合”的程度。

你的方向错了,但如果查看你使用的类和属性的文档,以后就能更好地做出有根据的猜测。

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

更新:在"ARKit 2"中,即iOS 12中的ARKit中,leftEyeTransformrightEyeTransform提供了每个眼球中心的3D位置(相对于面部锚点)。 (还包括每只眼睛的方向。)这可能有助于您的用例,但如果您真正需要的与瞳孔或眼睛开口的位置/大小有关,则没有API可以为您完成此操作。

ARFaceGeometry提供了一个三角网格,其在会话期间以拓扑稳定的方式映射了脸部的几百个点左右。也就是说,例如假设网格中的第57个顶点是鼻子的尖端,即使脸部起皱或伸展并且该点相对于其他点的位置发生变化,它仍将保持在鼻子的尖端。

问题:

  • API没有告诉你哪些顶点(网格中的点)是哪些(按照面部标志如眼角、鼻尖等来说)。
  • 网格的拓扑结构在会话期间是稳定的,但苹果不保证它不会在iOS版本、设备等之间发生改变。

因此,通过一些实验,您可能能够确定哪些顶点是左眼内角、左眼外角等。一旦您这样做了,就可以查看它们的位置来估计有用的量,例如眼睛宽度、瞳孔间距等。然而,这些测量基于可能不总是成立的网格假设,因此您不知道它何时会对您的应用程序用户失效。


谢谢回复。是的,我明白了你的意思,“API无法告诉您哪些顶点(网格中的点)是哪些(就面部标志而言,例如眼角,鼻尖等)。”那么,有没有其他方法可以实现这一点?我们能否通过其他方式获得眼睛大小、眼距、面部大小等信息? - Rohan
1
@Rohan 更新了回答:iOS 12 中有一些新的东西可能会有所帮助。 - rickster
使用ARFaceGeometry能否获取地标的特定顶点? - Anjali jariwala
想知道ARKit是否有任何更新,可以识别网格中的特定点或提供其他方式来绘制瞳孔的周长? - Alex Rothberg

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