6.7.2023

ARKit - Augmented Reality für iOS

ARKit 5 ist Apples Bibliothek zum Erstellen von Augmented Reality Anwendungen. ARKit ist in Swift geschrieben und ist auf allen Geräten mit iOS 11 oder neuer und einem A9 Prozessor oder neuer verfügbar.

Features

Zu den Features von ARKit gehören unter anderem Bilderkennung, Face Tracking, Depth API, Motion Capture, Simultaneous front and back camera, People Occlusion und Location Anchors. Über die Bilderkennung ist ARKit wie ARCore in der Lage Bilder zu erkennen und deren Position im Vergleich zu der Position des Smartphones zu verfolgen. ARKit kann außerdem die reale Größe der Bilder abschätzen. Die Bibliothek ist in der Lage bis zu 100 Bilder gleichzeitig zu erkennen und sich deren Position zu merken. Mit Face Tracking kann ARKit Gesichter erkennen und diese wie in den Anwendungsgebieten beschrieben mit AR-Elementen versehen. Mit der Depth API realisiert ARKit die Tiefenerkennung. Dafür verwendet ARKit mit neueren Modellen einen LiDAR-Scanner. Dieser Scanner wird bisher nur in dem iPhone 12 Pro und iPhone 12 Pro Max, sowie dem iPad Pro 11“ (2nd Gen.) und iPad Pro 12,9“ (4th Gen.) verbaut. Der LiDAR-Scanner wird verwendet, um die physikalische Umgebung in sehr kurzer Zeit digital zu modellieren, so dass Abstände zu Gegenständen schnell erkannt werden und auch, ob Gegenstände zwischen dem Smartphone und dem verfolgten Inhalt stehen. ARKit bildet zudem die Tiefe im Raum in einem „mesh“ ab. Mit Motion Capture ermöglicht ARKit Bewegungen von Personen zu erkennen und diese Bewegungen für AR Features zu nutzen. ARKit bietet die Möglichkeit über das gleichzeitige Nutzen von Vorder- und Rückkamera z.B. AR-Inhalte mit Gesichtsbewegungen zu steuern. Mit People Occlusion wird eine Art der Tiefenerkennung bezeichnet, mit der es möglich ist, Personen zu erkennen und AR-Inhalte so hinter diese zu setzen, damit das Erlebnis realistischer ist. ARKit bietet mit Location Anchors noch die Möglichkeit in ausgewählten Städten Objekte zu platzieren, die anschließend von mehreren Seiten betrachtet werden können. Die bisherigen Städte beschränken sich auf die USA und Großbritannien.

Beispiel Geschichte Unterwegs

Bei Geschichte Unterwegs war die Anforderung, dass beliebige Bilder verwendet werden können, um darauf die alten Bilder eines besonderen Standortes in Hannover anzuzeigen. Für die Referenzbilder haben wir die Fassade der Gebäude genutzt oder etwas, was einer Fassade ähnlich war. Bei dem Anlegen von Referenzbildern wird eine Größenangabe des realen Bildes gefordert (in cm / m). Dabei haben wir festgestellt, dass je ungenauer diese Angabe ist, desto schlechter funktioniert das Tracking.

Bilderkennung

Zur Bilderkennung wird eine Scene benötigt, die man mit der ARSCNView erstellt. Der UIViewController, der für das Anzeigen der kompletten iOS-Ansicht ist, muss dafür das protocol ARSCNViewDelegate implementieren (protocol's sind wie Interfaces). Das protocol erzwingt die Implementierung der renderer Methode, welche dafür da ist, die AR Inhalte zu rendern.

Beispiel Code
class ARViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!
    var session: ARSession {
        return sceneView.session
    }
    let configuration = ARWorldTrackingConfiguration()

    override func viewDidLoad() {
        super.viewDidLoad()

        sceneView.delegate = self
        referenceConfig = loadJson(fileName: "data")!
        guard let referenceImages = ARReferenceImage.referenceImages(inGroupNamed: "Reference Images", bundle: nil) else {
            fatalError("Missing reference images")
        }
        configuration.detectionImages = referenceImages
        session.run(configuration)
    }

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        guard let imageAnchor = anchor as? ARImageAnchor else { return }

        self.referenceImage = imageAnchor.referenceImage
        updateQueue.async {

            guard let reference = self.referenceConfig.filter({ ref in
                ref.referenceImage == self.referenceImage?.name
            }).first else {
                return
            }

            switch reference.type {
            case "image":
                if (reference.sight != nil) {
                    self.currentSight = self.sights.firstIndex(where: {$0 == reference.sight})!
                } else {
                    DispatchQueue.main.async {
                        self.pickerButton.isHidden = false
                    }
                }
                self.handleImage(node: node, config: reference)
            case "video":
                self.handleVideo(node: node, config: reference)
            default: return
            }
        }
}

Anzeigen von AR Bildern

Die Anzeige von Bildern wird in der zuvor beschriebenen renderer Methode ausgeführt, sobald ein Bild erkannt wurde. Für die Anzeige wichtig sind die SCNNode und der ARAnchor, welche beide als Parameter in die Renderer Methode von ARKit hereingegeben werden. Die SCNNode ist ein Objekt, mit der es möglich ist, Objekte innerhalb der ARSCNView anzuzeigen. Der ARAnchor ist ein Objekt, welches eine Referenz zur Position des erkannten Bildes enthält.

Beispiel Code handleImage
    func handleImage(node: SCNNode, config: Reference) {
        let imageNames = self.imagePaths.filter({ path in
            return path.contains(self.sights[self.currentSight])
        }).sorted { (a, b) -> Bool in
            a.split(separator: "/").last! < b.split(separator: "/").last!
        }

        self.images = imageNames.map { obj in
            let image = UIImage.init(contentsOfFile: "\(self.staticPath)/\(obj)")
            return image!
        }

        self.images = stride(from: 0, to: self.images.count, by: 6).map {
            Array(self.images[$0 ..< Swift.min($0 + 6, self.images.count)])
        }
        .map {arr in
            return arr.max(by: { (a, b) -> Bool in
                return a.size.width < b.size.width
            })!
        }

        let image = self.images[self.currentImage]
        let planeNode = SCNNode(geometry: self.createGeometry(image: image))

        planeNode.eulerAngles.x = -.pi / 2

        if(config.transform != nil) {

            var transform = planeNode.transform

            if config.transform?.scale != nil {
                transform = SCNMatrix4Scale(transform, config.transform!.scale!, config.transform!.scale!, 1)
            }

            if(config.transform?.translateVertical != nil) {
                transform = SCNMatrix4Translate(transform, 0, 0, -1 * config.transform!.translateVertical! * Float((referenceImage?.physicalSize.height)!))
            }

            planeNode.transform = transform
        }

        node.addChildNode(planeNode)
    }
Jonathan

Dualer Student

Zur Übersicht

Standort Hannover

newcubator GmbH
Bödekerstraße 22
30161 Hannover

Standort Dortmund

newcubator GmbH
Westenhellweg 85-89
44137 Dortmund