【IOS】ARAnchor到底是什麼?

2020-11-06 IOS

我正在嘗試瞭解和使用ARKit。但是有一件事我無法完全理解。

蘋果關於ARAnchor說:

A real-world position and orientation that can be used for placing objects in an AR scene.



但這還不夠。所以我的問題是:
  • 確切的ARAnchor是什麼?
  • anchor 和特徵點之間有什麼區別?
  • ARAnchor是特徵點的一部分嗎?
  • ARKit如何確定其 anchor ?
  • 解決辦法

    更新:2020年7月19日。
    TL; DR

    anchor ARAnchor是一個不可見的空物件,可以將3D模型保持在世界空間中 anchor 的位置。將ARAnchor視為模型的區域性軸transform node(可以對其進行平移,旋轉和縮放)。每個3D模型都有一個樞軸點,對不對?因此,此樞軸點必須滿足ARAnchor
    如果不在ARKit / RealityKit應用程式中使用 anchor ,則3D模型可能會從放置它們的位置移開,這會對使用者體驗產生影響。因此, anchor 是AR場景中的關鍵元素。
    根據ARKit文件2017:

    ARAnchor is a real-world position and orientation that can be used for placing objects in AR Scene. Adding an anchor to the session helps ARKit to optimize world-tracking accuracy in the area around that anchor, so that virtual objects appear to stay in place relative to the real world. If a virtual object moves, remove the corresponding anchor from the old position and add one at the new position.

    ARAnchor是ARKit框架中現有的所有其他 anchor 型別的父類,因此所有這些子類均繼承自ARAnchor類,但不能直接在您的程式碼中使用。我還必須說ARAnchorFeature Points沒有共同點。 Feature Points用於除錯。ARAnchor不會自動跟蹤真實目標。如果需要自動化,則必須使用rendered(...)session(...)例項方法,如果您分別符合協議(protocol)ARSCNViewDelegateARSessionDelegate,則可以呼叫這些方法。
    這是帶有平面 anchor 的可視表示的影象。但請記住:預設情況下,您既看不到檢測到的平面,也看不到其對應的ARPlaneAnchor。因此,如果您想在場景中看到任何 anchor ,則必須使用三個瘦SCNCylinder原語“視覺化”它。

    enter image description here

    在ARKit中,您可以使用不同的場景自動將ARAnchors新增到場景中:
  • ARPlaneAnchor
  • 如果水平和/或垂直 planeDetection 例項屬性為ON,則ARKit可以將ARPlaneAnchors新增到當前 session 。有時啟用的planeDetection會大大增加場景理解階段所需的時間。

  • ARImageAnchor (符合 ARTrackable 協議(protocol))
  • 這種型別的定位點包含有關在世界跟蹤 session 中檢測到的影象(定位點位於影象中心)的位置和方向的資訊。要進行啟用,請使用 detectionImages 例項屬性。在ARKit 2.0中,您總共可以跟蹤多達25張影象,在ARKit 3.0和ARKit 4.0中,分別可以跟蹤多達100張影象。但是,在兩種情況下均為not more than just 4 images simultaneously

  • ARBodyAnchor (符合ARTrackable協議(protocol))
  • 在最新版本的ARKit中,您可以通過使用 ARBodyTrackingConfiguration() 執行 session 來啟用 body 跟蹤。您將以CG Skeleton的 Root Joint 或在跟蹤角色的骨盆位置獲得ARBodyAnchor。

  • ARFaceAnchor (符合ARTrackable協議(protocol))
  • Face Anchor儲存有關可使用前置TrueDepth攝像頭或常規RGB攝像頭檢測到的拓撲和姿勢以及面部表情的資訊。當檢測到臉部時,“臉部固定點”將附加在 Nose 後面的臉部中央。在ARKit 2.0中,您只能跟蹤一張臉,而在ARKit 3.0中,最多可以同時跟蹤3張臉。在ARKit 4.0中,許多被跟蹤的面部取決於TrueDepth感測器和CPU:配備TrueDepth攝像頭的智慧手機最多可跟蹤3個面孔,帶有A12 +晶片組但不配備TrueDepth攝像頭的智慧手機也可以最多跟蹤3個面孔。

  • ARObjectAnchor
  • 此 anchor 的型別保留有關在世界跟蹤 session 中檢測到的真實3D物件的6個自由度(位置和方向)的資訊。請記住,您需要為 session 配置的ARReferenceObject屬性指定detectionObjects例項。

  • AREnvironmentProbeAnchor
  • 探針 anchor 可以在世界跟蹤 session 中為特定空間區域提供環境照明資訊。 ARKit的人工智慧使用它為反射著色器提供環境反射。

  • ARParticipantAnchor
  • 這是多使用者AR體驗必不可少的 anchor 型別。如果要使用它,請在true框架中將isCollaborationEnabled值用於MultipeerConnectivity例項屬性。

  • ARMesh anchor
  • ARKit 3.5+將使用者周圍的重建現實世界場景細分為網格 anchor 。隨著ARKit增強對現實世界的瞭解,網格 anchor 不斷更新其資料。儘管ARKit更新了網格以反映物理環境的變化,但是網格的後續變化並非旨在實時反映。

  • ARGeoAnchor (符合ARTrackable協議(protocol))
  • 在ARKit 4.0+中,有一個地理定位點(也稱為位置定位點),可使用GPS,Apple Maps和來自Apple伺服器的其他環境資料來跟蹤地理位置。這種定位標記可標識應用程式可以引用的世界中的特定區域。當用戶在場景中四處移動時, session 會根據座標和裝置的地理 anchor 指南針方向更新位置 anchor 的變換。


  • There are also other regular approaches to create anchors in AR session:


  • 命中測試方法
  • 在螢幕上點選,將一個點投影到一個不可見的檢測平面上,將ARAnchor放置在虛擬射線與該平面相交的位置。順便說一句,iOS 14中將棄用ARHitTestResult類及其對ARSCNView和ARSKView的命中測試方法,因此您必須習慣射線鑄造。

  • 射線鑄造方法
  • 如果您使用的是ray-casting,則在螢幕上輕按會在不可見的檢測平面上投影3D點。但是,您也可以在3D場景中的A和B位置之間執行射線投射。射線投射與命中測試的主要區別在於,當使用第一個ARKit時,它會在瞭解有關檢測到的表面的更多資訊時繼續完善射線投射,並且射線投射可以是2D到3D和3D到3D

  • 特徵點
  • ARKit在現實世界物件的高對比度邊緣上自動生成的特殊黃色點,可以為您提供放置ARAnchor的位置。

  • ARCamera的轉換
  • iPhone相機的位置和方向simd_float4x4可以輕鬆用作ARAnchor的位置。

  • 任何任意世界位置
  • 將自定義ARWorldAnchor放置在場景中的任何位置。您可以像在RealityKit中找到的world anchor一樣生成ARKit的AnchorEntity(.world(transform: mtx))版本。


  • 此程式碼段顯示瞭如何在委託(delegate)人的方法中使用ARPlaneAnchor:renderer(_:didAdd:for:):
    func renderer(_ renderer: SCNSceneRenderer, 
                 didAdd node: SCNNode, 
                  for anchor: ARAnchor) {
        
        guard let planeAnchor = anchor as? ARPlaneAnchor 
        else { return }
    
        let grid = Grid(anchor: planeAnchor)
        node.addChildNode(grid)
    }
    

    anchor 實體
    根據RealityKit文件2019:

    AnchorEntity is an anchor that tethers virtual content to a real-world object in an AR session.


    WWDC'19中釋出了 RealityKit 框架和 Reality Composer 應用程式。他們有一個名為AnchorEntity的新類。您可以將AnchorEntity用作任何實體層次結構的根點,並且必須將其新增到Scene anchors集合中。 AnchorEntity自動跟蹤現實世界的目標。在RealityKit和Reality Composer中,AnchorEntity在層次結構的頂部。該 anchor 能夠容納一百個模型,在這種情況下,與為每個模型使用100個個人 anchor 相比,它更穩定。
    讓我們看看它在程式碼中的外觀:
    func makeUIView(context: Context) -> ARView {
        
        let arView = ARView(frame: .zero)
        let modelAnchor = try! Experience.loadModel()
        arView.scene.anchors.append(modelAnchor)
        return arView
    }
    
    AnchorEntity 具有三個組成部分:
  • Anchoring元件
  • Transform元件
  • Synchronization元件

  • To find out the difference between ARAnchor and AnchorEntity look at THIS POST.


    以下是RealityKit 2.0 for iOS中提供的九種AnchorEntity案例:
    // Fixed position in the AR scene
    AnchorEntity(.world(transform: mtx)) 
    
    // For body tracking (a.k.a. Motion Capture)
    AnchorEntity(.body)
    
    // Pinned to the tracking camera
    AnchorEntity(.camera)
    
    // For face tracking (Selfie Camera config)
    AnchorEntity(.face)
    
    // For image tracking config
    AnchorEntity(.image(group: "Group", name: "model"))
    
    // For object tracking config
    AnchorEntity(.object(group: "Group", name: "object"))
    
    // For plane detection with surface classification
    AnchorEntity(.plane([.any], classification: [.seat], minimumBounds: [1.0, 1.0]))
    
    // When you use ray-casting
    AnchorEntity(raycastResult: myRaycastResult)     /* no dot notation */
    
    // When you use ARAnchor with a given identifier
    AnchorEntity(.anchor(identifier: uuid))
    
    // Creates anchor entity on a basis of ARAnchor
    AnchorEntity(anchor: arAnchor)                   /* no dot notation */
    
    這是RealityKit 2.0中適用於macOS的僅兩種AnchorEntity案例:
    // Fixed world position in VR scene
    AnchorEntity(.world(transform: mtx))
    
    // Camera transform
    AnchorEntity(.camera)
    

    Also it’s not superfluous to say that you can use any subclass of ARAnchor for AnchorEntity needs:

    func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
    
        guard let faceAnchor = anchors.first as? ARFaceAnchor 
        else { 
            return 
        }
        arView.session.add(anchor: faceAnchor)
    
        let anchor = AnchorEntity(anchor: faceAnchor)
        anchor.addChild(model)        
        arView.scene.anchors.append(anchor)
    }
    

    出處

    Have any Question?

    Let us answer it!