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를 생성하고 TrackingStateTRACKING로, TrackingMethodFULL_TRACKING로 설정합니다. 추적된 이미지가 카메라 뷰에서 벗어나면 ARCore는 TrackingMethodLAST_KNOWN_POSE로 변경하는 동시에 이미지의 방향과 위치를 계속 제공합니다.

앱에서는 의도한 사용 사례에 따라 이러한 열거형을 다르게 사용해야 합니다.

  • 고정 이미지. 제자리에 고정된(즉, 이동할 것으로 예상되지 않음) 이미지와 관련된 대부분의 사용 사례에서는 TrackingState를 사용하여 이미지가 감지되었는지, 이미지의 위치가 알려져 있는지를 확인할 수 있습니다. TrackingMethod는 무시해도 됩니다.

  • 움직이는 이미지. 앱에서 움직이는 이미지를 추적해야 한다면 TrackingStateTrackingMethod를 모두 사용하여 이미지가 감지되었는지, 이미지의 위치가 알려져 있는지를 확인합니다.

사용 사례 고정된 이미지 이미지 이동 중
벽에 걸려 있는 포스터 버스 측면에 표시된 광고
포즈는
유효한 것으로 간주할 수 있습니다.
TrackingState == TRACKING TrackingState == TRACKING

TrackingMethod == FULL_TRACKING

참고 항목