简体   繁体   English

ARKit面部跟踪SceneKit对象移动不正确

[英]ARKit Face Tracking SceneKit Object Moves Incorrectly

I'm having trouble understanding SceneKit transforms and anchoring an object to a detected face. 我在理解SceneKit转换并将对象固定到检测到的面部时遇到了麻烦。 I have created a face detection app and have successfully applied masks, with and without texture. 我创建了一个面部检测应用程序,并成功应用了具有和不具有纹理的蒙版。 I also successfully applied "glasses" made from text ( "00" ) including an occlusion node. 我还成功地应用了由文本(“ 00”)制成的“眼镜”(包括遮挡节点)。

In both cases, the objects move with the face as expected. 在这两种情况下,对象均按预期的方式与面部一起移动。 However, when I create a simple hat made from two cylinders within ScendKit the behavior is totally unexpected. 但是,当我在ScendKit中创建由两个圆柱体制成的简单帽子时,其行为完全出乎意料。

First, I could not seem to anchor the hat to the face, but had to adjust the transforms which made the hat appear in a different place with almost every face. 首先,我似乎无法将帽子固定在脸上,而是不得不调整转换,使帽子几乎每张脸都出现在不同的位置。 Even worse, the hat moves in the opposite direction to the face. 更糟糕的是,帽子沿与面部相反的方向移动。 Rotate the user face to the left, the hat moves to the right. 向左旋转用户面部,帽子向右移动。 Rotate the face up, the hat moves down. 将脸向上旋转,帽子向下移动。

在此处输入图片说明 在此处输入图片说明

Clearly, I'm missing something important here about anchoring objects to the face. 显然,我在这里缺少有关将对象锚定到面部的重要信息。 Any guidance would be appreciated. 任何指导将不胜感激。

Xcode 10 beta 3, iOS 11.4.1 running on an iPhone X. Xcode 10 beta 3,在iPhone X上运行的iOS 11.4.1。

There is a separate class for hat, glasses, mask: 帽子,眼镜和口罩有一个单独的类别:

class Hat : SCNNode {

    init(geometry : ARSCNFaceGeometry) {

        geometry.firstMaterial?.colorBufferWriteMask = []
        super.init()
        self.geometry = geometry

        guard let url = Bundle.main.url(forResource: "hat", withExtension: "scn", subdirectory: "Models.scnassets") else {fatalError("missing hat resource")}
        let node = SCNReferenceNode(url: url)!
        node.load()

        addChildNode(node)

    }//init

    func update(withFaceAnchor anchor : ARFaceAnchor) {
        let faceGeometry = geometry as! ARSCNFaceGeometry
        faceGeometry.update(from: anchor.geometry)
    }//upadate


    required init?(coder aDecoder: NSCoder) {
        fatalError("(#function) has not been implemented")
    }//r init

}//class

A couple of the functions in the ViewController: ViewController中的几个功能:

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

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

    updateMessage(text: "Tracking your face")

    switch contentTypeSelected {
    case .none:
        break
    case .mask:
        mask?.update(withFaceAnchor: faceAnchor)
    case .glasses:
        glasses?.update(withFaceAnchor: faceAnchor)
    case .hat:
        hat?.update(withFaceAnchor: faceAnchor)
    }//switch

}//didUpdate

func createFaceGeometry() {
    updateMessage(text: "Creating face geometry")

    let device = sceneView.device!

    let maskGeometry = ARSCNFaceGeometry(device: device)!
    mask = Mask(geometry: maskGeometry, maskType : maskType)

    let glassesGeometry = ARSCNFaceGeometry(device: device)!
    glasses = Glasses(geometry: glassesGeometry)

    let hatGeometry = ARSCNFaceGeometry(device: device)!
    hat = Hat(geometry: hatGeometry)

}//createFaceGeometry

The verisimilitude of a hat is going to depend on how well it can be position in relation to the face and how well it can appear situated in the scene (ie features that would be in front of the hat should occlude the hat itself). 帽子的逼真度将取决于它相对于面部的位置好坏以及它在场景中的显示效果(即,在帽子前面的特征应该遮盖帽子本身)。 With that in mind, you'll want the face to occlude the hat. 考虑到这一点,您将希望面部遮住帽子。 So your init for Hat should setup an occlusion node using the face geometry: 因此,您的Hat init应使用面部几何形状设置遮挡节点:

let occlusionNode: SCNNode

 init(geometry: ARSCNFaceGeometry) {

    /*
     Taken directly from Apple's sample code https://developer.apple.com/documentation/arkit/creating_face_based_ar_experiences
     */
    geometry.firstMaterial!.colorBufferWriteMask = []
    occlusionNode = SCNNode(geometry: geometry)
    occlusionNode.renderingOrder = -1

    super.init()

    addChildNode(occlusionNode)

    guard let url = Bundle.main.url(forResource: "hat", withExtension: "scn", subdirectory: "Models.scnassets") else {fatalError("missing hat resource")}
    let node = SCNReferenceNode(url: url)!
    node.load()

    addChildNode(node)
}

This will allow the face to appear in front of any virtual objects that have az depth greater than the face mesh. 这将允许面部出现在z深度大于面部网格的任何虚拟对象的前面。

You will also want change let hatGeometry = ARSCNFaceGeometry(device: device)! 您还将需要更改let hatGeometry = ARSCNFaceGeometry(device: device)! to let hatGeometry = ARSCNFaceGeometry(device: device, fillMesh: true)! let hatGeometry = ARSCNFaceGeometry(device: device, fillMesh: true)! otherwise the hat will be visible through the eyes giving an uncanny, undesirable effect. 否则,通过眼睛可以看到帽子,从而产生不可思议的不良影响。

The next issue is to position the hat so that it appears believably in the scene. 下一个问题是放置帽子的位置,使其看起来像在场景中一样可信。

Because we want the face to occlude a large part of the hat, it is best to position it in the y direct at the top of the face geometry. 因为我们希望面部遮盖帽子的大部分,所以最好将其放置在面部几何形状顶部的y方向上。 To do that successfully, you'll likely want your hat to have pivot point at the bottom center of the hat geometry and located at x = 0, y = 0 in your .scn file. 为了成功做到这一点,您可能希望帽子的枢轴点位于帽子几何图形的底部中心,并且在.scn文件中位于x = 0,y = 0处。 For example the scene editor and node inspector might look something like: 例如,场景编辑器和节点检查器可能类似于:

场景编辑器设置 节点检查器设置

Then in your func update(withFaceAnchor anchor : ARFaceAnchor) you can say 然后在您的func update(withFaceAnchor anchor : ARFaceAnchor)您可以说

func update(withFaceAnchor anchor : ARFaceAnchor) {
    let faceGeometry = geometry as! ARSCNFaceGeometry
    faceGeometry.update(from: anchor.geometry)
    hat.position.y = faceGeometry.boundingSphere.radius
} 

Finally for the z position of the hat you'll like want a slightly negative value as the bulk of a hat is behind one's face. 最后,对于帽子的z位置,您想要一个稍微为负的值,因为帽子的大部分位于人的脸后面。 -0.089 worked well for me. -0.089对我来说效果很好。

AR帽子直上 AR帽子略有轮廓

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM