Android 適用的擴增圖片開發人員指南

瞭解如何在自家應用程式中使用擴增圖片。

必要條件

請務必先瞭解基本 AR 概念,並瞭解如何設定 ARCore 工作階段,再繼續操作。

建立圖片資料庫

每個圖片資料庫最多可儲存 1,000 張圖片的資訊。

您可以透過兩種方式建立 AugmentedImageDatabase

  • 載入已儲存的圖片資料庫。接著視需要新增更多參考圖片。
  • 建立新的空資料庫。然後逐一新增參考圖像。

載入已儲存的圖片資料庫

使用 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,並將 TrackingState 設為 TRACKING,將 TrackingMethod 設為 FULL_TRACKING。當追蹤的圖片移出相機檢視畫面時,ARCore 會將 TrackingMethod 變更為 LAST_KNOWN_POSE,同時繼續提供圖片的方向和位置。

應用程式應視用途而定,以不同方式使用這些列舉。

  • 修正圖片。大多數涉及固定圖片 (也就是不會移動的圖片) 的用途,只要使用 TrackingState 即可判斷是否已偵測到圖片,以及是否已知圖片的位置。TrackingMethod 可忽略。

  • 動態圖片:如果應用程式需要追蹤移動中的圖片,請同時使用 TrackingStateTrackingMethod,判斷是否已偵測到圖片,以及是否已知圖片的位置。

用途 已修正的圖片 動態圖片
範例 牆上掛著海報 公車車身廣告
當姿勢符合下列條件時,系統會將其視為有效:
TrackingState == TRACKING TrackingState == TRACKING

TrackingMethod == FULL_TRACKING

另請參閱