Android 向け拡張画像デベロッパー ガイド

ご自身のアプリで拡張画像を使用する方法をご覧ください。

前提条件

続行する前に、AR の基本的なコンセプトARCore セッションを構成する方法を理解しておいてください。

画像データベースを作成する

各画像データベースには、最大 1,000 個の画像の情報を保存できます。

AugmentedImageDatabase を作成するには、次の 2 つの方法があります。

  • 保存した画像データベースを読み込みます。その後、必要に応じて参照画像を追加します。
  • 新しい空のデータベースを作成します。参照画像を 1 枚ずつ追加します。

保存した画像データベースを読み込む

AugmentedImageDatabase.deserialize() を使用して、既存の画像データベースを読み込みます。

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

画像データベースを作成するには、開発中に arcoreimg コマンドライン ツールを使用するか、メモリに読み込まれたデータベースを含むデータベースに対して AugmentedImageDatabase.serialize() を呼び出します。

空のデータベースを新規作成する

実行時に空の画像データベースを作成するには、AugmentedImageDatabase コンストラクタを使用します。

Java

AugmentedImageDatabase imageDatabase = new AugmentedImageDatabase(session);

Kotlin

val imageDatabase = AugmentedImageDatabase(session)

既存のデータベースに画像を追加する

画像ごとに AugmentedImageDatabase.addImage() を呼び出して、オプションの 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)

返されたインデックスは、検出された参照画像を特定するために使用できます。

画像トラッキングを有効にする

セッション構成を目的の画像データベースで構成されたものに設定して、画像のトラッキングを開始するように ARCore セッションを構成します。

Java

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

Kotlin

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

セッション中、ARCore はカメラ画像の特徴点と画像データベース内の特徴ポイントを照合して、画像を探します。

一致した画像を取得するには、フレーム更新ループ内で更新された AugmentedImage をポーリングします。

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

さまざまなユースケースのサポート

ARCore は、拡張画像を検出すると、その拡張画像の Trackable を作成し、TrackingStateTRACKING に、TrackingMethodFULL_TRACKING に設定します。トラッキングされた画像がカメラビューから出ると、ARCore は画像の向きと位置を指定しながら、TrackingMethodLAST_KNOWN_POSE に変更します。

これらの列挙型は、意図するユースケースに応じて異なる方法で使用する必要があります。

  • 固定画像。所定の位置に固定されている(つまり移動するはずではない)画像に関するほとんどのユースケースでは、TrackingState を使用するだけで、画像が検出されたかどうかと、位置が判明しているかどうかを判定できます。TrackingMethod は無視して構いません。

  • 動画。アプリで動画をトラッキングする必要がある場合は、TrackingStateTrackingMethod の両方を使用して、画像が検出されたかどうかと、その位置がわかっているかどうかを確認します。

使用例 固定された画像 画像を移動しています
壁に掛けられたポスター バスの車体の横に表示される広告
このポーズは、
TrackingState == TRACKING TrackingState == TRACKING
および
TrackingMethod == FULL_TRACKING

関連ドキュメント