Obrazy rozszerzone – przewodnik dla programistów na Androida

Dowiedz się, jak używać obrazów rozszerzonych w swoich aplikacjach.

Wymagania wstępne

Zanim przejdziesz dalej, upewnij się, że rozumiesz podstawowe zagadnienia związane z rozszerzoną rzeczywistością oraz że wiesz, jak skonfigurować sesję ARCore.

Tworzenie bazy danych obrazów

Każda baza danych obrazów może przechowywać informacje o maksymalnie 1000 obrazach.

Możesz utworzyć AugmentedImageDatabase na 2 sposoby:

  • Wczytaj zapisaną bazę danych obrazów. Następnie opcjonalnie dodaj więcej obrazów referencyjnych.
  • Utwórz nową pustą bazę danych. Następnie dodawaj obrazy referencyjne pojedynczo.

Wczytywanie zapisanej bazy danych obrazów

Użyj polecenia AugmentedImageDatabase.deserialize(), aby załadować istniejącą bazę danych obrazów:

Java

AugmentedImageDatabase imageDatabase;
try (InputStream inputStream = this.getAssets().open("example.imgdb")) {
  imageDatabase = AugmentedImageDatabase.deserialize(session, inputStream);
} catch (IOException e) {
  // The Augmented Image database could not be deserialized; handle this error appropriately.
}

Kotlin

val imageDatabase = this.assets.open("example.imgdb").use {
  AugmentedImageDatabase.deserialize(session, it)
}

Bazy danych obrazów można tworzyć za pomocą narzędzia wiersza poleceń arcoreimg podczas tworzenia lub wywołując AugmentedImageDatabase.serialize() na bazie danych, która jest wczytana do pamięci.

Tworzenie nowej pustej bazy danych

Aby utworzyć pustą bazę danych obrazów w czasie wykonywania, użyj konstruktora AugmentedImageDatabase:

Java

AugmentedImageDatabase imageDatabase = new AugmentedImageDatabase(session);

Kotlin

val imageDatabase = AugmentedImageDatabase(session)

Dodawanie obrazów do istniejącej bazy danych

Dodaj obrazy do bazy danych obrazów, wywołując funkcję AugmentedImageDatabase.addImage() dla każdego obrazu, podając opcjonalny parametr widthInMeters.

Java

Bitmap bitmap;
try (InputStream bitmapString = getAssets().open("dog.jpg")) {
  bitmap = BitmapFactory.decodeStream(bitmapString);
} catch (IOException e) {
  // The bitmap could not be found in assets; handle this error appropriately.
  throw new AssertionError("The bitmap could not be found in assets.", e);
}

// If the physical size of the image is not known, use addImage(String, Bitmap) instead, at the
// expense of an increased image detection time.
float imageWidthInMeters = 0.10f; // 10 cm
int dogIndex = imageDatabase.addImage("dog", bitmap, imageWidthInMeters);

Kotlin

val bitmap = assets.open("dog.jpg").use { BitmapFactory.decodeStream(it) }
// If the physical size of the image is not known, use addImage(String, Bitmap) instead, at the
// expense of an increased image detection time.
val imageWidthInMeters = 0.10f // 10 cm
val dogIndex = imageDatabase.addImage("dog", bitmap, imageWidthInMeters)

Zwrócone indeksy można później wykorzystać do określenia, który obraz referencyjny został wykryty.

Włączanie śledzenia obrazów

Aby rozpocząć śledzenie obrazów, skonfiguruj sesję ARCore, ustawiając konfigurację sesji na taką, która jest skonfigurowana z pożądaną bazą danych obrazów:

Java

Config config = new Config(session);
config.setAugmentedImageDatabase(imageDatabase);
session.configure(config);

Kotlin

val config = Config(session)
config.augmentedImageDatabase = imageDatabase
session.configure(config)

Podczas sesji ARCore wyszukuje obrazy, dopasowując punkty charakterystyczne z obrazu z kamery do tych w bazie danych obrazów.

Aby uzyskać dopasowane obrazy, sprawdź, czy w pętli aktualizacji klatek są dostępne nowe AugmentedImage.

Java

Collection<AugmentedImage> updatedAugmentedImages =
    frame.getUpdatedTrackables(AugmentedImage.class);
for (AugmentedImage img : updatedAugmentedImages) {
  if (img.getTrackingState() == TrackingState.TRACKING) {
    // Use getTrackingMethod() to determine whether the image is currently
    // being tracked by the camera.
    switch (img.getTrackingMethod()) {
      case LAST_KNOWN_POSE:
        // The planar target is currently being tracked based on its last
        // known pose.
        break;
      case FULL_TRACKING:
        // The planar target is being tracked using the current camera image.
        break;
      case NOT_TRACKING:
        // The planar target isn't been tracked.
        break;
    }

    // You can also check which image this is based on img.getName().
    if (img.getIndex() == dogIndex) {
      // TODO: Render a 3D version of a dog in front of img.getCenterPose().
    } else if (img.getIndex() == catIndex) {
      // TODO: Render a 3D version of a cat in front of img.getCenterPose().
    }
  }
}

Kotlin

val updatedAugmentedImages = frame.getUpdatedTrackables(AugmentedImage::class.java)

for (img in updatedAugmentedImages) {
  if (img.trackingState == TrackingState.TRACKING) {
    // Use getTrackingMethod() to determine whether the image is currently
    // being tracked by the camera.
    when (img.trackingMethod) {
      AugmentedImage.TrackingMethod.LAST_KNOWN_POSE -> {
        // The planar target is currently being tracked based on its last known pose.
      }
      AugmentedImage.TrackingMethod.FULL_TRACKING -> {
        // The planar target is being tracked using the current camera image.
      }
      AugmentedImage.TrackingMethod.NOT_TRACKING -> {
        // The planar target isn't been tracked.
      }
    }

    // You can also check which image this is based on AugmentedImage.getName().
    when (img.index) {
      dogIndex -> TODO("Render a 3D version of a dog at img.getCenterPose()")
      catIndex -> TODO("Render a 3D version of a cat at img.getCenterPose()")
    }
  }
}

Obsługa różnych przypadków użycia

Gdy ARCore wykryje obraz rozszerzony, utworzy Trackable dla tego obrazu rozszerzonego i ustawi TrackingState na TRACKING, a TrackingMethod na FULL_TRACKING. Gdy śledzony obraz zniknie z pola widzenia kamery, ARCore zmieni TrackingMethod na LAST_KNOWN_POSE, nadal podając orientację i położenie obrazu.

Aplikacja powinna używać tych typów w różny sposób w zależności od zastosowania.

  • Obrazy zostały naprawione. W większości przypadków obrazy, które są nieruchome (czyli nie powinny się przemieszczać), można po prostu wykrywać za pomocą funkcji TrackingState. TrackingMethod można zignorować.

  • Przesuwanie obrazów. Jeśli Twoja aplikacja musi śledzić ruchomy obraz, użyj zarówno TrackingState, jak i TrackingMethod, aby określić, czy obraz został wykryty i czy jego pozycja jest znana.

Przypadek użycia Obraz statyczny Obraz w ruchu
Przykład Plakat powieszony na ścianie Reklama na boku autobusu
Poza może być
uznawana za prawidłową, gdy
TrackingState == TRACKING TrackingState == TRACKING

TrackingMethod == FULL_TRACKING

Zobacz też