ARKit 101: Erkennen und Messen vertikaler Ebenen mit ARKit 1.5

0 Shares

In einem früheren Tutorial konnten wir horizontale Flächen wie Boden, Tische usw. mit ARKit messen. Mit ARKit 1.5 können wir jetzt vertikale Oberflächen wie Wände messen!

In diesem Tutorial erfahren Sie, wie Sie mithilfe von ARKit Ihre Augmented Reality-App für iPads und iPhones erstellen. Insbesondere werden wir untersuchen, wie wir vertikale Ebenen und ihre Abmessungen erkennen können.

Was wirst du lernen?

Wir werden lernen, wie man vertikale Ebenen erkennt und ihre Größe mit ARKit 1.5 genau bestimmt.

Mindestanforderungen

Mac mit MacOS 10.13.2 oder höher. Xcode 9.4 oder höher. Ein mobiles Gerät mit iOS 11+ auf einem A9 oder höher Prozessor. Grundsätzlich das iPhone 6S und höher, das iPad Pro (9,7 Zoll, 10,5 Zoll oder 12,9 Zoll; erste und zweite Generation) und das iPad 2017 oder höher. Swift 4.0. Obwohl Swift 3.2 unter Xcode 9.4 funktioniert, empfehle ich dringend, den neuesten Xcode herunterzuladen, um auf dem neuesten Stand zu bleiben. Ein Apple Developer-Konto. Es ist jedoch zu beachten, dass Sie kein kostenpflichtiges Apple Developer-Konto benötigen. Mit Apple können Sie Apps mit einem unbezahlten Apple Developer-Konto auf einem Testgerät bereitstellen. Sie benötigen jedoch ein kostenpflichtiges Entwicklerkonto, um Ihre App in den App Store zu stellen. (Informationen zur Funktionsweise des Programms finden Sie auf der Apple-Website, bevor Sie sich für Ihr kostenloses Apple Developer-Konto registrieren.)

Schritt 1: Laden Sie die Assets herunter, die Sie benötigen

Um das Befolgen dieses Tutorials zu vereinfachen, habe ich einen Ordner mit den erforderlichen 2D-Assets und der für das Projekt erforderlichen Swift-Datei erstellt. Diese Dateien stellen sicher, dass Sie sich in diesem Handbuch nicht verlaufen. Laden Sie daher den komprimierten Ordner mit den Assets herunter und entpacken Sie ihn.

Schritt 2: Richten Sie das AR-Projekt in Xcode ein

Wenn Sie sich nicht sicher sind, wie Sie dies tun sollen, befolgen Sie Schritt 2 in unserem Beitrag zum Steuern einer 3D-Ebene mit hitTest, um Ihr AR-Projekt in Xcode einzurichten. Geben Sie Ihrem Projekt einen anderen Namen, z NextReality_Tutorial7. Stellen Sie sicher, dass Sie einen kurzen Testlauf durchführen, bevor Sie mit dem folgenden Tutorial fortfahren.

Schritt 3: Importieren Sie Assets in Ihr Projekt

Klicken Sie im Projektnavigator auf den Ordner “Assets.xcassets”. Wir werden hier unsere 2D-Bilder hinzufügen. Klicken Sie dann mit der rechten Maustaste auf den linken Bereich des Bereichs auf der rechten Seite des Projektnavigators. Wählen Sie “Importieren” und fügen Sie die Datei “overlay_grid.png” aus dem entpackten Ordner “Assets” hinzu.

ARKit 101: Erkennen und Messen vertikaler Ebenen mit ARKit 1.5

Klicken Sie anschließend im Projektnavigator erneut mit der rechten Maustaste auf den gelben Ordner für “NextReality_Tutorial7” (oder wie auch immer Sie Ihr Projekt benannt haben). Wählen Sie die Option “Dateien zu ‘NextReality_Tutorial7’ hinzufügen”.

ARKit 101: Erkennen und Messen vertikaler Ebenen mit ARKit 1.5

Navigieren Sie zum entpackten Ordner “Assets” und wählen Sie die Datei “Grid.swift”. Stellen Sie sicher, dass Sie “Elemente bei Bedarf kopieren” aktivieren und alles andere unverändert lassen. Klicken Sie dann auf “Hinzufügen”.

ARKit 101: Erkennen und Messen vertikaler Ebenen mit ARKit 1.5

“Grid.swift” sollte dann zu Ihrem Projekt hinzugefügt werden, und Ihr Projektnavigator sollte ungefähr so ​​aussehen:

ARKit 101: Erkennen und Messen vertikaler Ebenen mit ARKit 1.5

Diese Datei hilft beim Rendern eines Rasterbildes für jede vertikale Ebene, die ARKit erkennt.

Schritt 4: Platzieren Sie ein Raster, um erkannte vertikale Ebenen anzuzeigen

In unserem Tutorial zur Erkennung horizontaler Ebenen finden Sie einen kurzen Überblick über die Ebenenerkennungsfunktionen von ARKit. Obwohl dies die Erkennung horizontaler Ebenen abdeckt, sind die Strategien und die Logik zur Erkennung vertikaler Ebenen ziemlich ähnlich.

Öffnen Sie die Klasse “ViewController.swift”, indem Sie darauf doppelklicken. Wenn Sie dem endgültigen Code für Schritt 4 folgen möchten, öffnen Sie einfach diesen Link, um ihn auf GitHub anzuzeigen.

Ändern Sie in der Datei “ViewController.swift” die Zeile zum Erstellen von Szenen in der viewDidLoad () Methode. Ändern Sie es von:

let scene = SCNScene(named: "art.scnassets/ship.scn")!

Folgendes, um sicherzustellen, dass keine Szene mit dem Standardschiffmodell erstellt wird:

let scene = SCNScene()

Als nächstes finden Sie diese Zeile oben in der Datei:

@IBOutlet var sceneView: ARSCNView!

Fügen Sie unter dieser Linie diese Linie hinzu, um ein Array von “Gittern” für alle erkannten vertikalen Ebenen zu erstellen:

var grids = [Grid]()

Kopieren Sie die folgenden zwei Methoden und fügen Sie sie wie unten aufgeführt am Ende der Datei vor der letzten geschweiften Klammer ein ( }} ) in der Datei. Mit diesen Methoden können wir unser Raster in den von ARKit erkannten vertikalen Ebenen als visuellen Indikator hinzufügen.

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    guard let planeAnchor = anchor as? ARPlaneAnchor, planeAnchor.alignment == .vertical else { return }
    let grid = Grid(anchor: planeAnchor)
    self.grids.append(grid)
    node.addChildNode(grid)
}

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    guard let planeAnchor = anchor as? ARPlaneAnchor, planeAnchor.alignment == .vertical else { return }
    let grid = self.grids.filter { grid in
        return grid.anchor.identifier == planeAnchor.identifier
        }.first

    guard let foundGrid = grid else {
        return
    }

    foundGrid.update(anchor: planeAnchor)
}

Lassen Sie uns kurz durchgehen, was in diesen beiden Methoden passiert:

    Das didAdd () wird aufgerufen, wenn ein neuer Knoten zum hinzugefügt wird ARSCNView. Hier stellen wir die erkannten sicher ARPlaneAnchor entspricht einer vertikalen Ebene und fügt sie als unsere hinzu Gitter Objekt, das das von uns importierte Rasterbild zu jeder erkannten Ebene hinzufügt. Das didUpdate () wird immer dann aufgerufen, wenn neuer ARPlaneAnchor Knoten werden erkannt (wir stellen erneut sicher, dass sie vertikalen Ebenen entsprechen) oder wenn die Ebene erweitert wird. Im letzteren Fall möchten wir auch unser Raster aktualisieren und erweitern. Wir machen das hier, indem wir anrufen aktualisieren() auf diesem spezifischen Gitter.

Lassen Sie uns nun Feature-Punkte aktivieren. Unter dieser Zeile in viewDidLoad ()::

sceneView.showsStatistics = true

Hinzufügen:

sceneView.debugOptions = ARSCNDebugOptions.showFeaturePoints

Als nächstes aktivieren wir die vertikale Ebenenerkennung. Unter dieser Zeile in viewWillAppear ()::

let configuration = ARWorldTrackingConfiguration()

Hinzufügen:

configuration.planeDetection = .vertical

Dieser Teil ist sehr wichtig! Dadurch wird sichergestellt, dass ARKit vertikale Ebenen in der realen Welt erkennen kann. Mit den Feature-Punkten können wir alle 3D-Punkte anzeigen, die ARKit erkennen kann.

Führen Sie jetzt Ihre App auf Ihrem Telefon aus und gehen Sie herum. Konzentrieren Sie sich auf eine gut beleuchtete Wand oder eine flache, vertikale Oberfläche. Sie sollten in der Lage sein, blaue Gitter zu sehen, wenn eine vertikale Ebene erkannt wird, ähnlich wie in der Abbildung unten.

ARKit 101: Erkennen und Messen vertikaler Ebenen mit ARKit 1.5

Kontrollpunkt: Ihr gesamtes Projekt am Ende dieses Schritts sollte wie der endgültige Schritt 4-Code auf meinem GitHub aussehen.

Schritt 5: Messen Sie die erkannten vertikalen Ebenen

Jetzt verwenden wir die Eigenschaft “Ausdehnung” der erkannten Ebenen, um ihre Abmessungen zu erfassen und sie mithilfe von SceneKit auszudrucken. Alle folgenden Codeänderungen werden in der Datei “Grid.swift” vorgenommen. Öffnen Sie das unbedingt und befolgen Sie die nachstehenden Schritte. Fühlen Sie sich frei, der fertigen Version zu folgen, wenn Sie diese Schritte ausführen.

Öffnen Sie die Klasse “Grid.swift” und unter dieser Zeile:

var planeGeometry: SCNPlane!

Fügen Sie eine neue Geometrie für den Text hinzu, in der die Abmessungen der erkannten Ebenen angezeigt werden:

var textGeometry: SCNText!

Suchen Sie als Nächstes die Zeile, die importiert wird ARKit::

import ARKit

Fügen Sie unter dieser Zeile und über der Zeile, in der die Grid-Klasse erstellt wird, den folgenden Code hinzu:

extension ARPlaneAnchor {
    // Inches
    var width: Float { return self.extent.x * 39.3701}
    var length: Float { return self.extent.z * 39.3701}
}

Hier erweitern wir die Funktionalität von ARPlaneAnchor. Standardmäßig wird die Größe in Metern zurückgegeben. Daher werden wir zwei Eigenschaften erstellen: “Breite” und “Länge”, die die Meter in Zoll umrechnen. Wir werden auch die “Extent” -Eigenschaft von verwenden ARPlaneAnchor und erhalten Sie die Werte “x” und “z”.

Als nächstes finden Sie die Konfiguration() Methode. Löschen Sie diese Methode und ersetzen Sie sie durch eine aktualisierte Version der Methode, wie unten gezeigt:

private func setup() {
    planeGeometry = SCNPlane(width: CGFloat(anchor.width), height: CGFloat(anchor.length))

    let material = SCNMaterial()
    material.diffuse.contents = UIImage(named:"overlay_grid.png")

    planeGeometry.materials = [material]
    let planeNode = SCNNode(geometry: self.planeGeometry)
    planeNode.physicsBody = SCNPhysicsBody(type: .static, shape: SCNPhysicsShape(geometry: planeGeometry, options: nil))
    planeNode.physicsBody?.categoryBitMask = 2

    planeNode.position = SCNVector3Make(anchor.center.x, 0, anchor.center.z);
    planeNode.transform = SCNMatrix4MakeRotation(Float(-Double.pi / 2.0), 1.0, 0.0, 0.0);

    // 1.
    let textNodeMaterial = SCNMaterial()
    textNodeMaterial.diffuse.contents = UIColor.black

    // Set up text geometry
    textGeometry = SCNText(string: String(format: "%.1f"", anchor.width) + " x " + String(format: "%.1f"", anchor.length), extrusionDepth: 1)
    textGeometry.font = UIFont.systemFont(ofSize: 10)
    textGeometry.materials = [textNodeMaterial]

    // Integrate text node with text geometry
    // 2.
    let textNode = SCNNode(geometry: textGeometry)
    textNode.name = "textNode"
    textNode.position = SCNVector3Make(anchor.center.x, 0, anchor.center.z);
    textNode.transform = SCNMatrix4MakeRotation(Float(-Double.pi / 2.0), 1.0, 0.0, 0.0);
    textNode.scale = SCNVector3Make(0.005, 0.005, 0.005)

    addChildNode(textNode)
    addChildNode(planeNode)
}

Der zusätzliche Code, der dem hinzugefügt wurde Konfiguration() Mit dieser Methode kann 3D-Text mit den Abmessungen der Ebene über dem Raster hinzugefügt werden. Lassen Sie uns nun das, was wir hier eingerichtet haben, herunterfahren.

    Wir richten eine Geometrie für den Text mit dem ein SCNText Klasse. Anschließend legen wir den Text auf die Breite und Höhe der Ebene fest, die mit unserer benutzerdefinierten Erweiterung berechnet wird.
    Wir haben eine neue erstellt SCNNode mit dem SCNText Geometrie aus dem obigen Schritt und aktualisiert seine Position und Skalierung entsprechend. Wir haben auch sichergestellt, dass der Textknoten in dieselbe Richtung gedreht wird, in die das Raster aktualisiert wird, indem wir seine Transformationseigenschaft geändert haben.

Auf diese Weise können wir die Größe des Flugzeugs beim ersten Einrichten anzeigen. Außerdem sollten wir die Größe des Flugzeugs ständig aktualisieren, da es immer größer wird. Lassen Sie uns das in den nächsten Codeänderungen tun.

Finden Sie die Update (Anker: ARPlaneAnchor) Methode. Am Ende der Methode vor der letzten geschweiften Klammer (}}), fügen Sie den folgenden Code hinzu:

if let textGeometry = self.childNode(withName: "textNode", recursively: true)?.geometry as? SCNText {
    // Update text to new size
    textGeometry.string = String(format: "%.1f"", anchor.width) + " x " + String(format: "%.1f"", anchor.length)
}

Dadurch wird sichergestellt, dass die Abmessungen der Ebene dynamisch geändert werden, wenn sich die Ebene ausdehnt.

Speichern Sie nun die App und führen Sie sie aus. Gehen Sie herum und finden Sie eine gut beleuchtete, strukturierte vertikale flache Oberfläche wie eine Wand. Hinweis: Bei einer Wand müssen Sie möglicherweise ganz nah heran, da den meisten weißen Wänden die Textur fehlt, die ARKit zum Erkennen vertikaler Ebenen benötigt. Ich würde vorschlagen, ein Fenster oder eine andere farbige vertikale Oberfläche zu finden, damit ARKit die Ebenen erkennen kann. Sie sollten so etwas sehen:

Kontrollpunkt: Ihr gesamtes Projekt am Ende dieses Schritts sollte wie der endgültige Schritt 5-Code auf meinem GitHub aussehen.

Was wir erreicht haben

Gut gemacht! Vorausgesetzt, Sie haben die Anweisungen korrekt befolgt, können Sie jetzt mit ARKit 1.5 erfolgreich Wände oder andere vertikale flache Oberflächen erkennen! Vor dem Aufkommen der vertikalen Ebenenerkennung war es sehr kompliziert – fast unmöglich -, vertikale Ebenen genau zu erkennen. Es ist erstaunlich zu sehen, wie ARKit es uns ermöglicht hat, dies ohne zusätzliche Hardware zu tun.

Wenn Sie den vollständigen Code für dieses Projekt benötigen, finden Sie ihn in meinem GitHub-Repo. Ich hoffe, Ihnen hat dieses Tutorial auf ARKit gefallen. Wenn Sie Kommentare oder Feedback haben, können Sie diese gerne im Kommentarbereich hinterlassen. Viel Spaß beim Codieren!

Verpassen Sie nicht: So platzieren Sie eine Gruppe von Luftballons um Sie herum und lassen sie zufällig in den Himmel schweben

0 Shares