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 znasz podstawowe pojęcia związane z AR i wiesz, jak skonfigurować sesję ARCore.

Tworzenie bazy danych obrazów

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

AugmentedImageDatabase możesz utworzyć na 2 sposoby:

  • Wczytaj bazę danych zapisanych obrazów. Następnie możesz dodać więcej obrazów referencyjnych.
  • Utwórz nową pustą bazę danych. Następnie dodawaj obrazy referencyjne pojedynczo.

Wczytaj bazę danych zapisanych obrazów

Użyj narzędzia AugmentedImageDatabase.deserialize(), aby wczytać 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ć podczas programowania za pomocą narzędzia wiersza poleceń arcoreimg lub za pomocą wywołania AugmentedImageDatabase.serialize() w bazie danych, która zawiera wczytaną w pamięci.

Utwórz nową pustą bazę danych

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

Java

AugmentedImageDatabase imageDatabase = new AugmentedImageDatabase(session);

Kotlin

val imageDatabase = AugmentedImageDatabase(session)

Dodaj obrazy do istniejącej bazy danych

Dodaj obrazy do bazy danych, wywołując dla każdego obrazu metodę AugmentedImageDatabase.addImage(), określając opcjonalną właściwość 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 mogą później posłużyć do identyfikacji obrazu referencyjnego, który został wykryty.

Włącz śledzenie obrazów

Skonfiguruj sesję ARCore, aby rozpocząć śledzenie obrazów, ustawiając konfigurację sesji na taką, która zawiera odpowiednią 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 szuka obrazów, dopasowując punkty cech z obrazu z aparatu do tych w bazie danych obrazów.

Aby uzyskać dopasowane obrazy, przeprowadź ankietę dotyczącą zaktualizowanych elementów AugmentedImage w pętli aktualizacji ramki.

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ługiwanie różnych przypadków użycia

Gdy ARCore wykryje obraz rozszerzonych, tworzy dla niego obiekt Trackable i ustawia TrackingState na TRACKING oraz TrackingMethod na FULL_TRACKING. Gdy śledzony obraz zniknie z widoku aparatu, ARCore zmieni TrackingMethod na LAST_KNOWN_POSE, zachowując jednocześnie orientację i położenie obrazu.

Aplikacja powinna używać tych wyliczeń w różny sposób w zależności od przeznaczenia.

  • Stałe obrazy. W większości przypadków użycia obejmujących obrazy, które są stałe (czyli nie powinny się przesuwać), można po prostu użyć atrybutu TrackingState, aby określić, czy obraz został wykryty i czy jest znana jego lokalizacja. Element TrackingMethod można zignorować.

  • Ruchome obrazy. Jeśli aplikacja musi śledzić ruchomy obraz, użyj obu właściwości, TrackingState i TrackingMethod, aby ustalić, czy obraz został wykryty i czy jest znana jego pozycja.

Przypadek użycia Poprawiony obraz Przenosisz obraz
Przykład Plakat zawieszony na ścianie Reklama z boku autobusu
Pozycja może być
uznana za prawidłową, gdy
TrackingState == TRACKING TrackingState == TRACKING
i
TrackingMethod == FULL_TRACKING

Zobacz też