ARKit 101: So platzieren Sie 2D-Bilder wie ein Gemälde oder Foto in Augmented Reality an einer Wand

0 Shares

In einem früheren Tutorial konnten wir vertikale Oberflächen wie Wände, Bücher und Monitore mit ARKit 1.5 messen. Mit dem Aufkommen vertikaler ebener Anker können wir nun auch Objekte an diesen vertikalen Wänden befestigen.

In diesem Tutorial erfahren Sie, wie Sie mithilfe von ARKit Ihre Augmented Reality-App für iPads und iPhones erstellen. Insbesondere werden wir darüber nachdenken, wie wir virtuelle Gemälde wie die Mona Lisa an unseren Wänden platzieren können.

Was wirst du lernen?

Wir werden lernen, wie Sie mit ARKit 1.5 Objekte wie 2D-Bilder mit SceneKit an vertikalen Wänden platzieren.

Mindestanforderungen

Mac mit MacOS 10.13.2 oder höher. Xcode 9.4 oder höher. Ein 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_Tutorial8. 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 Dateien “overlay_grid.png” und “mona-lisa.jpg” aus dem entpackten Ordner “Assets” hinzu.

ARKit 101: So platzieren Sie 2D-Bilder wie ein Gemälde oder Foto in Augmented Reality an einer Wand

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

ARKit 101: So platzieren Sie 2D-Bilder wie ein Gemälde oder Foto in Augmented Reality an einer Wand

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: So platzieren Sie 2D-Bilder wie ein Gemälde oder Foto in Augmented Reality an einer Wand

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

ARKit 101: So platzieren Sie 2D-Bilder wie ein Gemälde oder Foto in Augmented Reality an einer Wand

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.

Hinweis: Dieser Schritt ähnelt Schritt 4 aus dem vorherigen Artikel über vertikale Ebenen.

Ö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")!

Zu Folgendem (wodurch sichergestellt wird, 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 sicher, dass die erkannt werden 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. In diesem 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

Dies 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:

ARKit 101: So platzieren Sie 2D-Bilder wie ein Gemälde oder Foto in Augmented Reality an einer Wand

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

Schritt 5: Platzieren Sie die Mona Lisa mit hitTest an einer Wand

Schon mal die Mona Lisa im wirklichen Leben gesehen? Es ist ein Wunder zu sehen, obwohl es persönlich sehr klein ist. Seit Jahrhunderten spricht die ganze Welt viel darüber, und jetzt können Sie es in Ihrem Zuhause an die Wand hängen.

Wir werden unseren alten Freund, den hitTest, verwenden, um das Gemälde von Mona Lisa an einer erkannten vertikalen Wand zu platzieren.

Fügen wir zunächst Gestenerkenner zu unserer Szenenansicht hinzu. Öffnen Sie die Klasse “ViewController.swift” (alle Arbeiten von nun an beziehen diese Datei mit ein) und am Ende der viewDidLoad () Methode, fügen Sie diese Zeilen hinzu:

let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapped))
sceneView.addGestureRecognizer(gestureRecognizer)

Als nächstes fügen wir die hinzu tippte () Methode, die aufgerufen werden soll, wenn eine Tippgeste am Telefon registriert ist. Fügen Sie den folgenden Code am Ende der Datei hinzu, jedoch vor der letzten geschweiften Klammer ( }} ):

@objc func tapped(gesture: UITapGestureRecognizer) {
    // Get 2D position of touch event on screen
    let touchPosition = gesture.location(in: sceneView)

    // Translate those 2D points to 3D points using hitTest (existing plane)
    let hitTestResults = sceneView.hitTest(touchPosition, types: .existingPlaneUsingExtent)

    // Get hitTest results and ensure that the hitTest corresponds to a grid that has been placed on a wall
    guard let hitTest = hitTestResults.first, let anchor = hitTest.anchor as? ARPlaneAnchor, let gridIndex = grids.index(where: { $0.anchor == anchor }) else {
        return
    }
    addPainting(hitTest, grids[gridIndex])
}

Hier übersetzen wir im Grunde genommen die 2D-Punkte, auf die sich die Tippgeste auf dem iPhone-Bildschirm bezieht, mithilfe des hitTest in reale 3D-Punkte. Wir stellen sicher, dass Sie die verwenden existierendesPlaneUsingExtent Der Typ hitTest ermöglicht, dass die Ergebnisse nur von Ebenen stammen, die anhand ihrer Abmessungen (Ausdehnung) erkannt wurden (indem unsere Gitter angezeigt werden). Wir stellen dann sicher, dass der vom hitTest erkannte Anker ein ist ARPlaneAnchor und nicht irgendein Merkmalspunkt, und dass der Anker selbst mit einem Gitter korreliert, das bereits erkannt wurde und angezeigt wird. Schließlich nennen wir die addPainting () Methode, um das Gemälde tatsächlich an der Wand zu platzieren.

Fügen wir das hinzu addPainting () unter dem tippte () Methode, aber vor der letzten geschweiften Klammer ( }} ) in der Datei:

func addPainting(_ hitResult: ARHitTestResult, _ grid: Grid) {
    // 1.
    let planeGeometry = SCNPlane(width: 0.2, height: 0.35)
    let material = SCNMaterial()
    material.diffuse.contents = UIImage(named: "mona-lisa")
    planeGeometry.materials = [material]

    // 2.
    let paintingNode = SCNNode(geometry: planeGeometry)
    paintingNode.transform = SCNMatrix4(hitResult.anchor!.transform)
    paintingNode.eulerAngles = SCNVector3(paintingNode.eulerAngles.x + (-Float.pi / 2), paintingNode.eulerAngles.y, paintingNode.eulerAngles.z)
    paintingNode.position = SCNVector3(hitResult.worldTransform.columns.3.x, hitResult.worldTransform.columns.3.y, hitResult.worldTransform.columns.3.z)

    sceneView.scene.rootNode.addChildNode(paintingNode)
    grid.removeFromParentNode()
}

Hier passieren einige Dinge:

    Wir haben eine 2D-Ebenengeometrie erstellt. SCNPlaneund gab es die Mona Lisa Bild, das wir zuvor als Hintergrundmaterial heruntergeladen haben. Wir setzen dann die Geometrie auf eine neue SCNNode, namens paintNode. Wir haben dafür gesorgt, dass der Transformationswert dieses Knotens (dies ist die Kombination der Rotations-, Positions- und Skalierungseigenschaften des Knotens) auf den Wert festgelegt wird, der dem entspricht hitResultDer Transformationswert des Ankers ist. Dann setzen wir dementsprechend die Eulerwinkel (dies definiert den Winkel und die Drehung des Knotens basierend auf der x-, y- und z-Achse). Schließlich setzen wir die Position des Knotens (des Gemäldes) auf die Stelle, an der die Klopfgeste ausgeführt wurde, basierend auf dem hitTest-Ergebnis.

Nach dem Hinzufügen der paintNode In der Szene entfernen wir das Gitter, auf dem es sich befindet, damit wir die Mona Lisa ohne blaue Gitterlinien bewundern können!

Speichern Sie 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 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. Nachdem Sie eine Wand durch das blaue Gitter erkannt haben, tippen Sie auf einen Bereich im Gitter, um die Mona Lisa an der Wand zu platzieren. 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! Mit ARKit 1.5 konnten Sie erfolgreich eine Wand erkennen und ein tatsächliches Objekt darauf platzieren! Ist es nicht wunderbar, wozu ARKit in der Lage ist? Dank des Apple-Updates konnten wir dank ARKit die Schwierigkeiten beim Umgang mit der komplizierten Mathematik- und Computer-Vision-Logik nicht mehr verbergen. Mit diesem Tutorial konnten wir ein detailliertes Bild der Mona Lisa in unserem eigenen Haus an unsere Wand hängen. Ist das nicht ordentlich? Spielen Sie einfach herum, indem Sie verschiedene Bilder platzieren und ihre Größe ändern.

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: Messen von Wänden mit ARKit 1.5

0 Shares