Guía para desarrolladores sobre imágenes aumentadas en Android

Aprende a usar imágenes aumentadas en tus propias apps.

Requisitos previos

Asegúrate de comprender los conceptos fundamentales de RA y cómo configurar una sesión de ARCore antes de continuar.

Crea una base de datos de imágenes

Cada base de datos de imágenes puede almacenar información de hasta 1,000 imágenes.

Existen dos maneras de crear un AugmentedImageDatabase:

  • Carga una base de datos de imágenes guardada. Luego, de manera opcional, agrega más imágenes de referencia.
  • Crea una nueva base de datos vacía. Luego, agrega una imagen de referencia a la vez.

Carga una base de datos de imágenes guardada

Usa AugmentedImageDatabase.deserialize() para cargar una base de datos de imágenes existente:

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

Las bases de datos de imágenes se pueden crear con la herramienta de línea de comandos arcoreimg durante el desarrollo o con una llamada a AugmentedImageDatabase.serialize() en una base de datos que esté cargada en la memoria.

Crea una base de datos vacía nueva

Para crear una base de datos de imágenes vacía en el entorno de ejecución, usa el constructor AugmentedImageDatabase:

Java

AugmentedImageDatabase imageDatabase = new AugmentedImageDatabase(session);

Kotlin

val imageDatabase = AugmentedImageDatabase(session)

Agrega imágenes a una base de datos existente

Para agregar imágenes a tu base de datos de imágenes, llama a AugmentedImageDatabase.addImage() para cada imagen y especifica un widthInMeters opcional.

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)

Los índices que se muestran más adelante se pueden usar para identificar qué imagen de referencia se detectó.

Habilitar el seguimiento de imágenes

Configura tu sesión de ARCore para comenzar a hacer un seguimiento de imágenes. Para ello, establece la configuración de la sesión en una que esté configurada con la base de datos de imágenes deseada:

Java

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

Kotlin

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

Durante la sesión, ARCore busca imágenes haciendo coincidir los puntos de características de la imagen de la cámara con los de la base de datos de imágenes.

Para obtener las imágenes coincidentes, sondea en busca de AugmentedImage actualizadas en el bucle de actualización del marco.

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()")
    }
  }
}

Compatibilidad con diferentes casos de uso

Cuando ARCore detecta una imagen aumentada, crea un Trackable para ella y establece TrackingState en TRACKING y TrackingMethod en FULL_TRACKING. Cuando la imagen rastreada sale de la vista de cámara, ARCore cambia TrackingMethod a LAST_KNOWN_POSE sin dejar de proporcionar la orientación y la posición de la imagen.

Tu app debe usar estas enumeraciones de manera diferente según el caso de uso previsto.

  • Imágenes fijas. La mayoría de los casos de uso que involucran imágenes fijas en el lugar (es decir, que no se espera que se muevan) pueden simplemente usar TrackingState para determinar si se detectó la imagen y si se conoce su ubicación. Se puede ignorar TrackingMethod.

  • Imágenes en movimiento Si tu app necesita realizar el seguimiento de una imagen en movimiento, usa TrackingState y TrackingMethod para determinar si se detectó la imagen y si se conoce su posición.

Caso de uso Imagen fija Moviendo la imagen
Ejemplo Un póster colgado en una pared Un anuncio junto a un autobús
La pose puede
considerarse válida cuando
TrackingState == TRACKING TrackingState == TRACKING
y
TrackingMethod == FULL_TRACKING

Consulta también