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

基于ARKit与TrueDepth相机的真人活体检测实现问题咨询

法向量计算逻辑校验与真假人脸区分方案

一、当前法向量计算逻辑的问题

你当前的实现存在两个核心错误,无法得到正确的人脸网格法向量:

  • 顶点取值逻辑错误:ARFaceAnchor.geometry.vertices 存储的是单个人脸网格顶点的有序集合,并非按三角面分组的三元组。你直接连续取3个顶点拼接三角面,得到的不是真实的人脸拓扑结构,计算结果无参考意义。
  • 叉乘方向无统一规则:你使用 vector1 = vertex2 - vertex1、vector2 = vertex2 - vertex3 计算叉乘,得到的法向量朝向是随机的,无法进行后续的分布统计。

正确的计算逻辑需要基于官方提供的三角面索引取值,示例代码如下:

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    guard let faceAnchor = anchor as? ARFaceAnchor else { return }
    let faceGeometry = faceAnchor.geometry
    let vertices = faceGeometry.vertices
    let triangleIndices = faceGeometry.triangleIndices // 官方提供的三角面顶点索引
    var normals = [simd_float3]()
    
    for i in stride(from: 0, to: triangleIndices.count, by: 3) {
        let idx1 = Int(triangleIndices[i])
        let idx2 = Int(triangleIndices[i+1])
        let idx3 = Int(triangleIndices[i+2])
        
        let v1 = vertices[idx1]
        let v2 = vertices[idx2]
        let v3 = vertices[idx3]
        
        // 统一逆时针顺序计算,保证法向量朝人脸外侧
        let vector1 = v2 - v1
        let vector2 = v3 - v1
        let normal = simd_normalize(simd_cross(vector1, vector2))
        normals.append(normal)
    }
}

二、基于法向量区分真假人脸的方案

核心判断逻辑基于三维结构和二维平面的法向量分布差异:

  • 真人是立体3D结构,不同面部区域的法向量朝向差异极大:额头区域法向量基本朝向相机,脸颊区域法向量朝向左右两侧,下巴区域法向量朝向斜下方,整体法向量在X、Y、Z三个轴上的分布方差很高。
  • 照片、视频中的人脸是2D平面结构,所有检测到的顶点实际都在同一个平面上,几乎所有法向量的朝向都和平面垂直(基本正对相机),三个轴上的法向量分布方差极低。

具体落地步骤:

  1. 计算所有法向量在X、Y、Z三个分量上的方差值,求和得到总方差
  2. 提前测试不同场景下真人、照片/视频人脸的总方差区间,设置合适的判定阈值,低于阈值即可判定为虚假人脸
  3. 可结合TrueDepth相机的深度数据交叉验证:真人脸不同区域的深度值差异大,2D假脸的深度值几乎均匀,二者结合可以将准确率提升到95%以上

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 08:24:03