Guía para desarrolladores de imágenes aumentadas del NDK de Android

Aprende a usar las Imágenes aumentadas en tus propias apps.

Requisitos previos

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

Crea una base de datos de imágenes

Crea un ArAugmentedImageDatabase para almacenar imágenes de referencia. Existen dos maneras:

  • Crea una base de datos vacía
ArAugmentedImageDatabase* ar_augmented_image_database = NULL;
ArAugmentedImageDatabase_create(ar_session, &ar_augmented_image_database);
std::string database_buffer;
util::LoadFileFromAssetManager(asset_manager_, "sample_database.imgdb",
                               &database_buffer);
uint8_t* raw_buffer = reinterpret_cast<uint8_t*>(&database_buffer.front());

ArAugmentedImageDatabase* ar_augmented_image_database = NULL;
const ArStatus status = ArAugmentedImageDatabase_deserialize(
    ar_session, raw_buffer, database_buffer.size(),
    &ar_augmented_image_database);

Los archivos de base de datos se pueden crear con la herramienta de imágenes o llamando a ArAugmentedImageDatabase_serialize().

Agrega imágenes a la base de datos

Este paso es opcional si las imágenes de referencia que deseas ya se cargaron desde el archivo de la base de datos. Para agregar una imagen durante el tiempo de ejecución, llama a ArAugmentedImageDatabase_addImage() como se muestra a continuación. Consulta la augmented_image_c para ver las funciones en el espacio de nombres util.

int32_t width, height, stride, index;
uint8_t* image_pixel_buffer = nullptr;
constexpr const char kSampleImageName[] = "default.jpg";
bool load_image_result = util::LoadImageFromAssetManager(
    kSampleImageName, &width, &height, &stride, &image_pixel_buffer);

uint8_t* grayscale_buffer = nullptr;
util::ConvertRgbaToGrayscale(image_pixel_buffer, width, height, stride,
                             &grayscale_buffer);

int32_t grayscale_stride = stride / 4;
const ArStatus status = ArAugmentedImageDatabase_addImage(
    ar_session_, ar_augmented_image_database, kSampleImageName,
    grayscale_buffer, width, height, grayscale_stride, &index);

// If the physical size of the image is known, you can instead use
//     ArStatus ArAugmentedImageDatabase_addImageWithPhysicalSize
// This will improve the initial detection speed. ARCore will still actively
// estimate the physical size of the image as it is viewed from multiple
// viewpoints.

delete[] image_pixel_buffer;
delete[] grayscale_buffer;

Los valores index y name se usan más adelante para identificar qué imagen de referencia se detectó.

Habilita el seguimiento de imágenes

Para configurar tu sesión de ARCore para hacer un seguimiento de las imágenes, registra la base de datos de imágenes:

ArConfig_setAugmentedImageDatabase(ar_session_, ar_config,
                                   ar_augmented_image_database);
const ArStatus status = ArSession_configure(ar_session_, ar_config);

Durante la sesión, ARCore usa puntos de características de la imagen de la cámara para hacer coincidir los de la base de datos de imágenes.

Cómo encontrar imágenes aumentadas en una sesión de RA

Para obtener las imágenes coincidentes, sondea los ArAugmentedImage actualizados en el bucle de actualización de fotogramas.

// Update loop, in onDrawFrame
ArTrackableList* updated_image_list = nullptr;
ArTrackableList_create(ar_session_, &updated_image_list);
ArFrame_getUpdatedTrackables(
    ar_session_, ar_frame_, AR_TRACKABLE_AUGMENTED_IMAGE, updated_image_list);

int32_t image_list_size;
ArTrackableList_getSize(ar_session_, updated_image_list, &image_list_size);

for (int i = 0; i < image_list_size; ++i) {
  ArTrackable* ar_trackable = nullptr;
  ArTrackableList_acquireItem(ar_session_, updated_image_list, i,
                              &ar_trackable);
  ArAugmentedImage* image = ArAsAugmentedImage(ar_trackable);

  ArTrackingState tracking_state;
  ArTrackable_getTrackingState(ar_session_, ar_trackable, &tracking_state);

  int image_index;
  ArAugmentedImage_getIndex(ar_session_, image, &image_index);

  if (tracking_state == AR_TRACKING_STATE_TRACKING) {
    util::ScopedArPose scopedArPose(ar_session_);
    ArAugmentedImage_getCenterPose(ar_session_, image,
                                   scopedArPose.GetArPose());

    ArAnchor* image_anchor = nullptr;
    const ArStatus status = ArTrackable_acquireNewAnchor(
        ar_session_, ar_trackable, scopedArPose.GetArPose(), &image_anchor);

    // For example, you can now render content at the image anchor, choosing
    // content based on the image index (or name).
  }
}

Compatibilidad con diferentes casos de uso

Cuando ARCore detecta una imagen aumentada, crea un Trackable para esa imagen y establece ArTrackingState en TRACKING y ArAugmentedImageTrackingMethod en FULL_TRACKING. Cuando la imagen a la que se le realiza un seguimiento se aleja de la vista de la cámara, ARCore sigue configurando ArTrackingState en TRACKING, pero cambia ArAugmentedImageTrackingMethod a LAST_KNOWN_POSE y, al mismo tiempo, sigue proporcionando la orientación y la posición de la imagen.

Tu app debe usar el estado de seguimiento y el método de seguimiento de manera diferente según el caso de uso previsto.

  • Imágenes fijas: En la mayoría de los casos de uso que involucran imágenes fijas (es decir, que no se espera que se muevan), simplemente se puede usar ArTrackingState para determinar si se detectó la imagen y si se conoce su ubicación. Se puede ignorar ArAugmentedImageTrackingMethod.

  • Imágenes en movimiento. Si tu app necesita hacer un seguimiento de una imagen en movimiento, usa ArTrackingState y ArAugmentedImageTrackingMethod para determinar si se detectó la imagen y si se conoce su posición.

Caso de uso Imagen fija Imagen en movimiento
Ejemplo Un póster colgado en una pared Un anuncio en el costado de un autobús
La pose se puede
considerar válida cuando
ArTrackingState == TRACKING ArTrackingState == TRACKING
y
ArAugmentedImageTrackingMethod == FULL_TRACKING