So erstellen Sie eine Augmented Reality-Anwendung mit ARCore

So erstellen Sie eine Augmented Reality-Anwendung mit ARCore


In diesem Handbuch erfahren Sie, wie Sie der realen Welt 3D-Modelle hinzufügen. Mit der ARCore-Bibliothek von Google können Sie einem 2D-Bild (Bild oder Video) vollständige 3D-Modelle hinzufügen.


Sie müssen dem System eine Art Referenzbild zur Verfügung stellen, nach dem ARCore in der realen Welt sucht, um dem darauf basierenden Bild ein 3D-Modell hinzuzufügen. Augmented Reality ist beispielsweise in Büchern, Zeitungen, Zeitschriften usw. bereits weit verbreitet.


Bevor Sie in dieses Tutorial eintauchen, sollten Sie sich mit den beiden vorherigen Artikeln zu diesem Thema vertraut machen, in denen Sie die grundlegenden AR-Begriffe kennenlernen:



Was sind Augmented Reality-Bilder?


Laut der Dokumentation für Entwickler können Sie mit Augmented Reality-Bildern in ARCore Augmented Reality-Anwendungen erstellen, mit denen 2D-Bilder wie Poster oder Produktverpackungen „animiert“ werden können.


Sie laden einige Referenzbilder in ARCore hoch und erfahren dann, wie sie während der AR-Sitzung erkannt werden, z. B. beim Aufnehmen eines Videos. Diese Informationen werden verwendet, um das 3D-Modell auf einem 2D-Bild zu positionieren.


Einschränkungen bei der Verwendung von Augmented Reality-Bildern


Im Folgenden sind einige der Einschränkungen aufgeführt, die bei der Verwendung von Augmented-Reality-Bildern auftreten können:


  • ARCore kann nur bis zu 20 Referenzbilder gleichzeitig verarbeiten.
  • Die physische Ebene in der realen Welt sollte flach sein und eine Fläche von mehr als 15 cm x 15 cm haben.
  • ARCore kann keine bewegten Bilder und Objekte verfolgen.

Auswahl des richtigen Referenzbildes


Hier einige Tipps zur Auswahl eines guten Referenzbilds für ARCore:


  • Augmented Reality-Bilder unterstützen die Formate PNG, JPEG und JPG.
  • Es spielt keine Rolle, ob das Bild farbig oder schwarzweiß ist. Hauptsache, es ist kontrastreich.
  • Die Bildauflösung muss mindestens 300 x 300 Pixel betragen.
  • Die Verwendung von hochauflösenden Bildern bedeutet keine Leistungsverbesserung.
  • Vermeiden Sie Bilder mit sich wiederholenden Mustern (z. B. Muster oder Tupfen).
  • Verwenden Sie das Arcoreimg- Tool, um zu bewerten, wie gut Ihr Bild funktioniert. Eine Bewertung von mindestens 75 Punkten wird empfohlen.

So verwenden Sie das Arcoreimg-Tool:


  • Laden Sie das ARCore SDK für Android von diesem Link herunter.
  • Entpacken Sie den Inhalt der Datei an einen beliebigen Ort.
  • Gehen Sie im extrahierten Ordner zu tools> arcoreimg> windows (auch wenn Sie Linux oder macOS haben).
  • Öffnen Sie eine Eingabeaufforderung in diesem Verzeichnis.
  • Und geben Sie diesen Befehl ein:

arcoreimg.exe eval-img --input_image_path=dog.png 

Ersetzen Sie dog.png durch den vollständigen Pfad zu Ihrem Bild.


Erste Schritte mit der Augmented Reality App


Nachdem Sie sich mit ARCore vertraut gemacht und ein gutes Bild mit einer Bewertung von 75+ ausgewählt haben, können Sie mit dem Schreiben des Anwendungscodes beginnen.


Fragmenterstellung


Wir werden ein Fragment erstellen und es unserer Aktivität hinzufügen. Erstellen Sie eine Klasse namens CustomArFragment und erben Sie sie von ArFragment . Hier ist der Code für CustomArFragment :


 package com.ayusch.augmentedimages; import android.util.Log; import com.google.ar.core.Config; import com.google.ar.core.Session; import com.google.ar.sceneform.ux.ArFragment; public class CustomArFragment extends ArFragment { @Override protected Config getSessionConfiguration(Session session) { getPlaneDiscoveryController().setInstructionView(null); Config config = new Config(session); config.setUpdateMode(Config.UpdateMode.LATEST_CAMERA_IMAGE); session.configure(config); getArSceneView().setupSession(session); return config; } } 

Zunächst schalten wir die Ebenenerkennung aus. Auf diese Weise entfernen wir das Handsymbol vom Bildschirm, das unmittelbar nach der Initialisierung des Fragments angezeigt wird, und informieren den Benutzer über die Notwendigkeit, sein Smartphone zu bewegen, um das Flugzeug zu finden. Wir brauchen das nicht mehr, weil wir keine zufälligen Ebenen finden, sondern ein konkretes Bild.


Dann legen wir den Aktualisierungsmodus für die Sitzung LATEST_CAMERA_IMAGE . Dies stellt sicher, dass wir über Bildaktualisierungen informiert werden, wenn der Kamerarahmen aktualisiert wird.


Einrichtung der Bilddatenbank


Fügen Sie das ausgewählte Referenzbild (das Sie in der physischen Welt finden möchten) zum Ordner " Assets" hinzu (erstellen Sie es, falls dies noch nicht geschehen ist). Jetzt können wir Bilder zu unserer Datenbank hinzufügen.


Wir werden diese Datenbank erstellen, sobald das Fragment erstellt wurde. In den Protokollen zeigen wir das Ergebnis dieser Operation an:


 if ((((MainActivity) getActivity()).setupAugmentedImagesDb(config, session))) { Log.d("SetupAugImgDb", "Success"); } else { Log.e("SetupAugImgDb","Faliure setting up db"); } 

So CustomArFragment aus:


 package com.ayusch.augmentedimages; import android.util.Log; import com.google.ar.core.Config; import com.google.ar.core.Session; import com.google.ar.sceneform.ux.ArFragment; public class CustomArFragment extends ArFragment { @Override protected Config getSessionConfiguration(Session session) { getPlaneDiscoveryController().setInstructionView(null); Config config = new Config(session); config.setUpdateMode(Config.UpdateMode.LATEST_CAMERA_IMAGE); session.configure(config); getArSceneView().setupSession(session); if ((((MainActivity) getActivity()).setupAugmentedImagesDb(config, session))) { Log.d("SetupAugImgDb", "Success"); } else { Log.e("SetupAugImgDb","Faliure setting up db"); } return config; } } 

In setupAugmentedImagesDb werden wir setupAugmentedImagesDb Methode MainActivity . CustomArFragment wir nun CustomArFragment zu unserer activity_main.xml :


 <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <fragment android:id="@+id/sceneform_fragment" android:name="com.ayusch.augmentedimages.CustomArFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.constraint.ConstraintLayout> 

Hinzufügen eines Bildes zur Datenbank


Jetzt richten wir unsere Bilddatenbank ein, finden das Referenzbild in der realen Welt und fügen dem Bild ein 3D-Modell hinzu.


Beginnen wir mit der Einrichtung unserer Datenbank. Erstellen Sie eine öffentliche setupAugmentedImagesDb Methode in der MainActivity Klasse:


 public boolean setupAugmentedImagesDb(Config config, Session session) { AugmentedImageDatabase augmentedImageDatabase; Bitmap bitmap = loadAugmentedImage(); if (bitmap == null) { return false; } augmentedImageDatabase = new AugmentedImageDatabase(session); augmentedImageDatabase.addImage("tiger", bitmap); config.setAugmentedImageDatabase(augmentedImageDatabase); return true; } private Bitmap loadAugmentedImage() { try (InputStream is = getAssets().open("blanket.jpeg")) { return BitmapFactory.decodeStream(is); } catch (IOException e) { Log.e("ImageLoad", "IO Exception", e); } return null; } 

Wir haben auch eine loadAugmentedImage Methode erstellt, die ein Bild aus einem Ressourcenordner lädt und eine Bitmap zurückgibt.


In setupAugmentedImagesDb initialisieren wir zuerst unsere Datenbank für die aktuelle Sitzung und fügen dann das Image dieser Datenbank hinzu. Wir haben unseren Bildtiger genannt . Dann installieren wir diese Datenbank in der Konfiguration und geben true , was darauf hinweist, dass das Image erfolgreich hinzugefügt wurde.


Reale Referenzbilderkennung


Jetzt werden wir beginnen, unsere Referenzbilder in der realen Welt zu entdecken. Zu diesem Zweck erstellen wir einen Listener, der jedes Mal aufgerufen wird, wenn der Videorahmen aktualisiert wird, und dieser Rahmen wird auf das Vorhandensein eines Referenzbilds dort analysiert.


Fügen Sie diese Zeile der onCreate() -Methode in MainActivity :


 arFragment.getArSceneView().getScene().addOnUpdateListener(this::onUpdateFrame); 

onUpdateFrame nun die onUpdateFrame Methode zu MainActivity :


 @RequiresApi(api = Build.VERSION_CODES.N) private void onUpdateFrame(FrameTime frameTime) { Frame frame = arFragment.getArSceneView().getArFrame(); Collection<AugmentedImage> augmentedImages = frame.getUpdatedTrackables(AugmentedImage.class); for (AugmentedImage augmentedImage : augmentedImages) { if (augmentedImage.getTrackingState() == TrackingState.TRACKING) { if (augmentedImage.getName().equals("tiger") && shouldAddModel) { placeObject(arFragment, augmentedImage.createAnchor(augmentedImage.getCenterPose()), Uri.parse("Mesh_BengalTiger.sfb")); shouldAddModel = false; } } } } 

In der ersten Zeile erhalten wir den Rahmen selbst. Ein Frame kann als normaler Screenshot eines Videos vorgestellt werden. Wenn Sie mit der Funktionsweise des Videos vertraut sind, wissen Sie, dass es sich nur um eine Sammlung von Bildern handelt, die sich sehr schnell ändern und den Eindruck erwecken, dass sich etwas bewegt. Wir machen nur eines dieser Bilder.


Nachdem wir den Rahmen erhalten haben, analysieren wir ihn auf das Vorhandensein unseres Referenzbildes. Wir erstellen eine Liste aller von ARCore mithilfe von frame.getUpdatedTrackables verfolgten frame.getUpdatedTrackables . Dann iterieren wir darüber und prüfen, ob unser Tigerbild im Rahmen vorhanden ist.


Wenn eine Übereinstimmung gefunden wird, nehmen wir einfach das 3D-Modell und platzieren es auf dem erkannten Bild.


Hinweis Das Flag shouldAddModel verwendet, sodass das 3D-Modell nur einmal shouldAddModel .

Platzieren eines 3D-Modells über einem Referenzbild


Nachdem wir unser Referenzbild in der realen Welt gefunden haben, können wir ein 3D-Modell hinzufügen. Fügen Sie die addNodeToScene placeObject und addNodeToScene :


  • placeObject : Mit dieser Methode wird ein gerendertes Objekt mit einem bestimmten Uri . Sobald das Rendern abgeschlossen ist, wird das Objekt an die Methode addNodeToScene , wo das Objekt an den Knoten angehängt und dieser Knoten in der Szene platziert wird.
  • addNodeToScene : Diese Methode erstellt einen Knoten aus dem resultierenden Anker, erstellt einen weiteren Knoten, mit dem das visualisierte Objekt verbunden wird, fügt diesen Knoten dann dem addNodeToScene hinzu und platziert ihn auf der Bühne.

So sieht MainActivity :


 package com.ayusch.augmentedimages; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Build; import android.support.annotation.RequiresApi; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.widget.Toast; import com.google.ar.core.Anchor; import com.google.ar.core.AugmentedImage; import com.google.ar.core.AugmentedImageDatabase; import com.google.ar.core.Config; import com.google.ar.core.Frame; import com.google.ar.core.Session; import com.google.ar.core.TrackingState; import com.google.ar.sceneform.AnchorNode; import com.google.ar.sceneform.FrameTime; import com.google.ar.sceneform.rendering.ModelRenderable; import com.google.ar.sceneform.rendering.Renderable; import com.google.ar.sceneform.ux.ArFragment; import com.google.ar.sceneform.ux.TransformableNode; import java.io.IOException; import java.io.InputStream; import java.util.Collection; public class MainActivity extends AppCompatActivity { ArFragment arFragment; boolean shouldAddModel = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); arFragment = (CustomArFragment) getSupportFragmentManager().findFragmentById(R.id.sceneform_fragment); arFragment.getPlaneDiscoveryController().hide(); arFragment.getArSceneView().getScene().addOnUpdateListener(this::onUpdateFrame); } @RequiresApi(api = Build.VERSION_CODES.N) private void placeObject(ArFragment arFragment, Anchor anchor, Uri uri) { ModelRenderable.builder() .setSource(arFragment.getContext(), uri) .build() .thenAccept(modelRenderable -> addNodeToScene(arFragment, anchor, modelRenderable)) .exceptionally(throwable -> { Toast.makeText(arFragment.getContext(), "Error:" + throwable.getMessage(), Toast.LENGTH_LONG).show(); return null; } ); } @RequiresApi(api = Build.VERSION_CODES.N) private void onUpdateFrame(FrameTime frameTime) { Frame frame = arFragment.getArSceneView().getArFrame(); Collection<AugmentedImage> augmentedImages = frame.getUpdatedTrackables(AugmentedImage.class); for (AugmentedImage augmentedImage : augmentedImages) { if (augmentedImage.getTrackingState() == TrackingState.TRACKING) { if (augmentedImage.getName().equals("tiger") && shouldAddModel) { placeObject(arFragment, augmentedImage.createAnchor(augmentedImage.getCenterPose()), Uri.parse("Mesh_BengalTiger.sfb")); shouldAddModel = false; } } } } public boolean setupAugmentedImagesDb(Config config, Session session) { AugmentedImageDatabase augmentedImageDatabase; Bitmap bitmap = loadAugmentedImage(); if (bitmap == null) { return false; } augmentedImageDatabase = new AugmentedImageDatabase(session); augmentedImageDatabase.addImage("tiger", bitmap); config.setAugmentedImageDatabase(augmentedImageDatabase); return true; } private Bitmap loadAugmentedImage() { try (InputStream is = getAssets().open("blanket.jpeg")) { return BitmapFactory.decodeStream(is); } catch (IOException e) { Log.e("ImageLoad", "IO Exception", e); } return null; } private void addNodeToScene(ArFragment arFragment, Anchor anchor, Renderable renderable) { AnchorNode anchorNode = new AnchorNode(anchor); TransformableNode node = new TransformableNode(arFragment.getTransformationSystem()); node.setRenderable(renderable); node.setParent(anchorNode); arFragment.getArSceneView().getScene().addChild(anchorNode); node.select(); } } 

Führen Sie nun Ihre Anwendung aus. Sie sollten den Bildschirm wie unten gezeigt sehen. Bewegen Sie das Telefon leicht über das Referenzobjekt. Sobald ARCore das Referenzbild in der realen Welt erkennt, fügt es Ihr 3D-Modell hinzu.


Ergebnis


Lesen Sie auch: Erstellen Ihrer ersten ARCore-Anwendung

Source: https://habr.com/ru/post/de439190/


All Articles