You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否借助CATransform3D通过ARKit人脸网格获取眼部尺寸?

问题分析与解决方案

Hey there! Let's clear up what's going on here and get you on the right track to calculate eye width and interocular distance with ARKit.

First: Why Your Current Values Are Useless

The data you're getting right now is uninitialized garbage values—here's why:

  • ARFaceAnchor.blendShapes[.eyeBlinkLeft] returns a Float (a weight between 0 and 1) that represents how closed the left eye is, not a transform.
  • Calling caTransform3DValue on this float is a mistake—this property isn't meant for blend shape weights, so you're just reading random memory values that don't relate to any actual facial measurements.

How to Actually Calculate Eye Width & Interocular Distance

To get real facial dimensions, you need to use the 3D face mesh vertices from ARFaceAnchor or ARFaceGeometry. Here's how to do it:

Step 1: Understand the Data You Need

  • ARFaceAnchor.geometry gives you the full 3D mesh of the face, with vertices in the anchor's local coordinate space.
  • You can also use pre-defined facial feature locations from ARFaceAnchor, like leftEye and rightEye (these are SIMD3<Float> positions), or reference specific vertex indices for eye edges (ARKit has standard vertex indices for facial features—you can test by logging vertex positions to identify which correspond to eye edges).

Step 2: Convert Vertices to World Space & Calculate Distances

If you want measurements in real-world units (meters), convert the local vertices to world space using the face node's transform, then compute the distance between relevant points:

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    guard let faceAnchor = anchor as? ARFaceAnchor else { return }
    
    // Calculate interocular distance (distance between eye centers)
    let leftEyeLocalPos = faceAnchor.leftEye
    let rightEyeLocalPos = faceAnchor.rightEye
    
    // Convert local positions to world space
    let leftEyeWorldPos = simd_mul(node.simdTransform, simd_float4(leftEyeLocalPos, 1)).xyz
    let rightEyeWorldPos = simd_mul(node.simdTransform, simd_float4(rightEyeLocalPos, 1)).xyz
    
    let interocularDistance = simd_distance(leftEyeWorldPos, rightEyeWorldPos)
    print("Interocular distance: \(interocularDistance) meters")
    
    // Calculate left eye width (using mesh vertices)
    guard let device = MTLCreateSystemDefaultDevice() else { return }
    let faceGeometry = ARFaceGeometry(device: device)!
    faceGeometry.update(from: faceAnchor.geometry)
    
    // Replace with actual vertex indices for left eye outer/inner edges
    let leftEyeOuterVertex = faceGeometry.vertices[123] 
    let leftEyeInnerVertex = faceGeometry.vertices[456]
    
    let leftEyeOuterWorld = simd_mul(node.simdTransform, simd_float4(leftEyeOuterVertex, 1)).xyz
    let leftEyeInnerWorld = simd_mul(node.simdTransform, simd_float4(leftEyeInnerVertex, 1)).xyz
    
    let leftEyeWidth = simd_distance(leftEyeOuterWorld, leftEyeInnerWorld)
    print("Left eye width: \(leftEyeWidth) meters")
}

Step 3: Notes on Vertex Indices

ARKit's ARFaceGeometry uses consistent vertex indices for key facial features. You can find the exact indices by testing: log a range of vertex positions, then move your eye to see which coordinates shift to match the eye edges.

Key Takeaways

  • Forget the caTransform3DValue from blend shapes—it's completely irrelevant to facial measurements.
  • Use ARFaceAnchor's face mesh vertices or pre-defined feature positions to calculate real-world distances.
  • All measurements will be in meters (since ARKit uses a real-world coordinate system).

内容的提问来源于stack exchange,提问作者Rohan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:14:22