Comment créer une application de réalité augmentée à l'aide d'ARCore

Comment créer une application de réalité augmentée à l'aide d'ARCore


Dans ce guide, vous apprendrez à ajouter des modÚles 3D au monde réel. La bibliothÚque ARCore de Google vous permet d'ajouter des modÚles 3D complets à une image 2D (photo ou vidéo).


Vous devez fournir au systÚme une sorte d'image de référence qu'ARCore recherchera dans le monde réel afin d'ajouter un modÚle 3D à l'image sur sa base. La réalité augmentée est déjà largement utilisée, par exemple dans les livres, les journaux, les magazines, etc.


Avant de plonger dans ce didacticiel, vous devez vous familiariser avec les deux articles précédents sur ce sujet qui vous présenteront les termes AR de base:



Que sont les images de réalité augmentée?


Selon la documentation destinée aux développeurs , les images de réalité augmentée ARCore vous permettent de créer des applications de réalité augmentée qui peuvent «animer» des images 2D, telles que des affiches ou des emballages de produits.


Vous téléchargez des images de référence sur ARCore, puis il vous informe de leur détection pendant la session AR, par exemple, lors de la prise d'une vidéo. Et ces informations sont utilisées pour positionner le modÚle 3D sur une image 2D.


Limites de l'utilisation d'images de réalité augmentée


Voici quelques-unes des limitations que vous pouvez rencontrer lors de l'utilisation d'images de réalité augmentée:


  • ARCore ne peut traiter que jusqu'Ă  20 images de rĂ©fĂ©rence Ă  la fois.
  • Le plan physique dans le monde rĂ©el doit ĂȘtre plat et sa surface doit ĂȘtre supĂ©rieure Ă  15 cm x 15 cm.
  • ARCore ne peut pas suivre les images et les objets en mouvement.

Choisir la bonne image de référence


Voici quelques conseils pour choisir une bonne image de référence pour ARCore:


  • Les images de rĂ©alitĂ© augmentĂ©e prennent en charge les formats PNG, JPEG et JPG.
  • Peu importe que l'image soit en couleur ou en noir et blanc, l'essentiel est qu'elle soit en contraste Ă©levĂ©.
  • La rĂ©solution de l'image doit ĂȘtre d'au moins 300 x 300 pixels.
  • L'utilisation d'images Ă  haute rĂ©solution ne signifie pas une amĂ©lioration des performances.
  • Les images avec des motifs rĂ©pĂ©titifs (tels que des motifs ou des pois) doivent ĂȘtre Ă©vitĂ©es.
  • Utilisez l'outil arcoreimg pour Ă©valuer le fonctionnement de votre image. Une note d'au moins 75 points est recommandĂ©e.

Comment utiliser l'outil arcoreimg:


  • TĂ©lĂ©chargez le SDK ARCore pour Android Ă  partir de ce lien .
  • DĂ©compressez le contenu du fichier Ă  n'importe quel emplacement.
  • Dans le dossier extrait, allez dans tools> arcoreimg> windows (mĂȘme si vous avez Linux ou macOS).
  • Ouvrez une invite de commande dans ce rĂ©pertoire.
  • Et entrez cette commande:

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

Remplacez dog.png par le chemin d'accĂšs complet Ă  votre image.


Premiers pas avec l'application de réalité augmentée


Maintenant que vous vous ĂȘtes familiarisĂ© avec ARCore et avez sĂ©lectionnĂ© une bonne image avec une note de 75+, il est temps de commencer Ă  Ă©crire le code d'application.


Création de fragments


Nous allons créer un fragment et l'ajouter à notre activité. Créez une classe appelée CustomArFragment et CustomArFragment -la d' ArFragment . Voici le code de 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; } } 

Tout d'abord, nous désactivons la détection des avions. Ce faisant, nous supprimons l'icÎne de la main de l'écran qui apparaßt immédiatement aprÚs l'initialisation du fragment et informe l'utilisateur de la nécessité de déplacer son smartphone pour trouver l'avion. Nous n'en avons plus besoin, car nous ne trouvons pas d'avions aléatoires, mais une image concrÚte.


Ensuite, nous définissons le mode de mise à jour pour la session LATEST_CAMERA_IMAGE . Cela garantit que nous serons informés des mises à jour de l'image chaque fois que le cadre de la caméra est mis à jour.


Configuration de la base de données d'images


Ajoutez l'image de référence sélectionnée (que vous souhaitez trouver dans le monde physique) dans le dossier des ressources (créez-la si elle ne l'est pas déjà). Nous pouvons maintenant ajouter des images à notre base de données.


Nous créerons cette base de données dÚs que le fragment sera créé. Dans les journaux, nous affichons le résultat de cette opération:


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

Voici Ă  quoi 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); if ((((MainActivity) getActivity()).setupAugmentedImagesDb(config, session))) { Log.d("SetupAugImgDb", "Success"); } else { Log.e("SetupAugImgDb","Faliure setting up db"); } return config; } } 

BientÎt, nous ajouterons la méthode MainActivity à MainActivity . Ajoutons CustomArFragment à notre CustomArFragment :


 <?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> 

Ajout d'une image à la base de données


Nous allons maintenant configurer notre base de données d'images, trouver l'image de référence dans le monde réel et ajouter un modÚle 3D à l'image.


Commençons par mettre en place notre base de données. Créez une méthode setupAugmentedImagesDb publique dans la classe MainActivity :


 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; } 

Nous avons également créé une méthode loadAugmentedImage qui charge une image à partir d'un dossier de ressources et renvoie un bitmap.


Dans setupAugmentedImagesDb nous initialisons d'abord notre base de données pour la session en cours, puis ajoutons l'image à cette base de données. Nous avons nommé notre image tigre . Ensuite, nous installons cette base de données dans la configuration et retournons true , indiquant que l'image a été ajoutée avec succÚs.


Détection d'images de référence dans le monde réel


Nous allons maintenant commencer à découvrir nos images de référence dans le monde réel. Pour ce faire, nous allons créer un écouteur qui sera appelé à chaque mise à jour de la trame vidéo, et cette trame sera analysée pour la présence d'une image de référence.


Ajoutez cette ligne à la méthode onCreate() dans MainActivity :


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

Ajoutez maintenant la méthode MainActivity à 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; } } } } 

Dans la premiĂšre ligne, nous obtenons le cadre lui-mĂȘme. Un cadre peut ĂȘtre imaginĂ© comme une capture d'Ă©cran rĂ©guliĂšre d'une vidĂ©o. Si vous connaissez le fonctionnement de la vidĂ©o, vous savez qu'il ne s'agit que d'une collection d'images qui se changent trĂšs rapidement, donnant l'impression de quelque chose qui bouge. Nous venons de prendre une de ces photos.


AprÚs avoir reçu le cadre, nous l'analysons pour la présence de notre image de référence dessus. Nous prenons une liste de tous les éléments suivis par ARCore à l'aide de frame.getUpdatedTrackables . Ensuite, nous itérons dessus et vérifions si notre image de tigre est présente dans le cadre.


Si une correspondance est trouvée, nous prenons et plaçons simplement le modÚle 3D au-dessus de l'image détectée.


Remarque L'indicateur shouldAddModel utilisé pour que nous ajoutions le modÚle 3D une seule fois.

Placer un modÚle 3D sur une image de référence


Maintenant que nous avons trouvé notre image de référence dans le monde réel, nous pouvons ajouter un modÚle 3D dessus. Ajoutez les addNodeToScene placeObject et addNodeToScene :


  • placeObject : cette mĂ©thode est utilisĂ©e pour construire un objet rendu en utilisant un Uri donnĂ©. Une fois le rendu terminĂ©, l'objet est transmis Ă  la mĂ©thode addNodeToScene , oĂč l'objet est attachĂ© au nƓud et ce nƓud est placĂ© sur la scĂšne.
  • addNodeToScene : cette mĂ©thode crĂ©e un nƓud Ă  partir de l'ancre rĂ©sultante, crĂ©e un autre nƓud auquel se joint l'objet visualisĂ©, puis ajoute ce nƓud au nƓud d'ancrage et le place sur la scĂšne.

Voici Ă  quoi ressemble 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(); } } 

Exécutez maintenant votre application. Vous devriez voir l'écran comme indiqué ci-dessous. Déplacez le téléphone légÚrement au-dessus de l'objet de référence. Et dÚs que ARCore détecte l'image de référence dans le monde réel, il y ajoute votre modÚle 3D.


Résultat


Lire aussi: Création de votre premiÚre application ARCore

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


All Articles