Guia do desenvolvedor sobre imagens aumentadas para Android

Saiba como usar imagens aumentadas nos seus próprios apps.

Pré-requisitos

Verifique se você entendeu os conceitos fundamentais de RA e como configurar uma sessão do ARCore antes de continuar.

Criar um banco de dados de imagens

Cada banco de dados de imagens pode armazenar informações de até mil imagens.

Há duas maneiras de criar um AugmentedImageDatabase:

  • Carregue um banco de dados de imagens salvas. Se quiser, adicione mais imagens de referência.
  • Crie um novo banco de dados vazio. Em seguida, adicione imagens de referência, uma de cada vez.

Carregar um banco de dados de imagens salvas

Use AugmentedImageDatabase.deserialize() para carregar um banco de dados de imagens atual:

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

Os bancos de dados de imagens podem ser criados usando a ferramenta de linha de comando arcoreimg durante o desenvolvimento ou chamando AugmentedImageDatabase.serialize() em um banco de dados carregado na memória.

Criar um novo banco de dados vazio

Para criar um banco de dados de imagens vazio no momento da execução, use o construtor AugmentedImageDatabase:

Java

AugmentedImageDatabase imageDatabase = new AugmentedImageDatabase(session);

Kotlin

val imageDatabase = AugmentedImageDatabase(session)

Adicionar imagens a um banco de dados atual

Adicione imagens ao banco de dados chamando AugmentedImageDatabase.addImage() para cada imagem e especificando um 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)

Posteriormente, os índices retornados poderão ser usados para identificar qual imagem de referência foi detectada.

Ativar rastreamento de imagem

Configure sua sessão do ARCore para começar a rastrear imagens. Para isso, defina a configuração da sessão como uma definida no banco de dados de imagens desejado:

Java

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

Kotlin

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

Durante a sessão, o ARCore procura imagens comparando os pontos de recursos da imagem da câmera com os do banco de dados de imagens.

Para acessar as imagens correspondentes, procure AugmentedImages atualizados no loop de atualização de frames.

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

Compatibilidade com diferentes casos de uso

Quando o ARCore detecta uma imagem aumentada, ele cria um Trackable para essa imagem aumentada e define TrackingState como TRACKING e TrackingMethod como FULL_TRACKING. Quando a imagem rastreada sai da visualização da câmera, o ARCore altera o TrackingMethod para LAST_KNOWN_POSE enquanto continua a fornecer a orientação e a posição da imagem.

Seu app precisa usar essas enumerações de forma diferente, dependendo do caso de uso esperado.

  • Imagens corrigidas. A maioria dos casos de uso envolvendo imagens fixas no local, ou seja, que não devem ser movidas, pode simplesmente usar TrackingState para determinar se a imagem foi detectada e se a localização dela é conhecida. TrackingMethod pode ser ignorado.

  • Imagens em movimento. Caso o app precise rastrear uma imagem em movimento, use TrackingState e TrackingMethod para determinar se a imagem foi detectada e se a posição dela é conhecida.

Caso de uso Imagem fixa Movendo a imagem
Exemplo Um pôster pendurado na parede Anúncio na lateral de um ônibus
A pose pode ser
considerada válida quando
TrackingState == TRACKING TrackingState == TRACKING
e
TrackingMethod == FULL_TRACKING

Veja também