Obrazy rozszerzone – przewodnik dla programistów na Androida

Dowiedz się, jak korzystać z obrazów rozszerzonych we własnych aplikacjach.

Wymagania wstępne

Upewnij się, że znasz podstawowe pojęcia związane z AR. i dowiedz się, jak skonfigurować sesję ARCore, zanim przejdziesz dalej.

Tworzenie bazy danych obrazów

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

Są 2 sposoby tworzenia AugmentedImageDatabase:

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

Wczytywanie bazy danych zapisanych obrazów

Użyj formatu AugmentedImageDatabase.deserialize() , aby wczytać istniejącą bazę danych zdjęć:

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ą: arcoreimg narzędzia wiersza poleceń w fazie tworzenia lub przez wywołanie AugmentedImageDatabase.serialize() w bazie danych, która jest wczytywana do 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)

Dodawanie obrazów do istniejącej bazy danych

Dodaj obrazy do bazy danych zdjęć, wywołując AugmentedImageDatabase.addImage() dla każdego obrazu, podając opcjonalną wartość 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 zostać użyte do określenia, który obraz referencyjny – wykryto.

Włącz śledzenie obrazów

Skonfiguruj sesję ARCore, aby rozpocząć śledzenie obrazów przez ustawienie sesji config na takiej, która jest skonfigurowana z użyciem odpowiedniej bazy 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 cech z z tymi w bazie danych zdjęć.

Aby uzyskać dopasowane obrazy, przeprowadź ankietę w sprawie 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ługa różnych przypadków użycia

Gdy ARCore wykryje obraz rozszerzony, tworzy dla niego Trackable Rozszerzony obraz i zestawy TrackingState do TRACKING i TrackingMethod do FULL_TRACKING. Gdy śledzony obraz zniknie z pola widzenia aparatu, ARCore zmienia TrackingMethod do LAST_KNOWN_POSE, jednocześnie podając orientację i położenie zdjęcia.

Aplikacja powinna używać tych wyliczeń różnie w zależności od zamierzonego użycia tych kwestii.

  • Poprawione obrazy. Większość przypadków użycia obejmujących obrazy, które mają stałą wysokość (czyli nie zostanie przeniesiony) może za pomocą funkcji TrackingState określić czy obraz został wykryty i czy jego lokalizacja jest znana. TrackingMethod można zignorować.

  • Ruchome obrazy. Jeśli aplikacja ma śledzić ruchomy obraz, użyj obu funkcji TrackingState i TrackingMethod, aby określić, czy obraz został i czy jest znana jej pozycja.

Przypadek użycia Stały obraz Przenoszę obraz
Przykład Plakat na ścianie Reklama na boku autobusu
Pozycja może być:
uważane za prawidłowe, gdy
TrackingState == TRACKING TrackingState == TRACKING
i
TrackingMethod == FULL_TRACKING

Zobacz też