Android NDK 앱에서 Raw Depth 사용

Raw Depth API는 전체 Depth API 데이터보다 정확도가 높지만 항상 모든 픽셀을 포함하지는 않는 카메라 이미지에 깊이 데이터를 제공합니다. 원시 깊이 이미지는 일치하는 신뢰도 이미지와 함께 추가로 처리되어 앱이 개별 사용 사례에 충분한 정확성을 갖춘 깊이 데이터만 사용할 수 있습니다.

기기 호환성

Raw Depth는 Depth API를 지원하는 모든 기기에서 사용할 수 있습니다. Full Depth API와 마찬가지로 Raw Depth API에는 비행 시간 (ToF) 센서와 같이 지원되는 하드웨어 깊이 센서가 필요하지 않습니다. 그러나 Raw Depth API 및 전체 Depth API는 모두 기기에 있을 수 있는 지원되는 하드웨어 센서를 사용합니다.

Raw Depth API와 전체 Depth API 비교

Raw Depth API는 더 높은 정확도로 심도 추정값을 제공하지만, 원시 심도 이미지에는 카메라 이미지의 모든 픽셀에 대한 심도 추정치가 포함되지 않을 수 있습니다. 반면, 전체 Depth API는 모든 픽셀에 예상 깊이를 제공하지만, 깊이 추정치의 평활화 및 보간으로 인해 픽셀당 깊이 데이터의 정확도가 떨어질 수 있습니다. 두 API에서 깊이 이미지의 형식과 크기는 동일합니다. 내용만 다릅니다.

다음 표는 주방의 의자와 테이블 이미지를 사용한 Raw Depth API와 Full Depth API의 차이점을 보여줍니다.

API 반환 값 카메라 이미지 깊이 이미지 신뢰도 이미지
Raw Depth API
  • 카메라 이미지의 일부 픽셀에 대해서만 매우 정확한 깊이 추정치가 포함된 원시 깊이 이미지입니다.
  • 모든 원시 깊이 이미지 픽셀에 대한 신뢰도를 제공하는 신뢰도 이미지입니다. 심도 추정치가 없는 카메라 이미지 픽셀의 신뢰도는 0입니다.
Full Depth API
  • 모든 픽셀의 깊이 추정치가 포함된 단일 '평활화된' 깊이 이미지입니다.
  • 이 API에는 신뢰도 이미지가 제공되지 않습니다.
N/A

신뢰도 이미지

Raw Depth API에서 반환된 신뢰도 이미지에서 밝은 픽셀일수록 신뢰도 값이 더 높으며, 흰색 픽셀은 완전한 신뢰도를 나타내고 검은색 픽셀은 신뢰도가 없음을 나타냅니다. 일반적으로 카메라 이미지에서 나무와 같이 텍스처가 많은 영역은 그렇지 않은 영역(예: 빈 벽)보다 원시 깊이 신뢰도가 높습니다. 텍스처가 없는 표면은 일반적으로 신뢰도가 0입니다.

대상 기기에 지원되는 하드웨어 심도 센서가 있는 경우 질감이 없는 표면에서도 카메라에 충분히 가까운 이미지 영역에 대한 신뢰도가 높아질 수 있습니다.

컴퓨팅 비용

Raw Depth API의 컴퓨팅 비용은 전체 Depth API 컴퓨팅 비용의 약 절반입니다.

사용 사례

Raw Depth API를 사용하면 장면에 있는 객체의 도형을 더 자세히 표현하는 깊이 이미지를 얻을 수 있습니다. 원시 깊이 데이터는 기하학적 이해 작업에 높은 깊이의 정확성과 세부 사항이 필요한 AR 환경을 만들 때 유용할 수 있습니다. 일부 사용 사례는 다음과 같습니다.

  • 3D 재구성
  • 측정
  • 모양 감지

기본 요건

계속 진행하기 전에 기본 AR 개념ARCore 세션 구성 방법을 이해해야 합니다.

깊이 사용 설정

새 ARCore 세션에서 사용자 기기가 깊이를 지원하는지 확인합니다. 처리 성능 제약으로 인해 일부 ARCore 호환 기기는 Depth API를 지원하지 않습니다. 리소스를 절약하기 위해 ARCore에서는 깊이가 기본적으로 사용 중지됩니다. 앱에서 Depth API를 사용하도록 깊이 모드를 사용 설정합니다.

int32_t is_depth_supported = 0;

// Check whether the user's device supports the Depth API.
ArSession_isDepthModeSupported(ar_session, AR_DEPTH_MODE_AUTOMATIC,
                               &is_depth_supported);
ArConfig* ar_config = NULL;
ArConfig_create(ar_session, &ar_config);
if (is_depth_supported) {
  ArConfig_setDepthMode(ar_session, ar_config, AR_DEPTH_MODE_AUTOMATIC);
}
CHECK(ArSession_configure(ar_session, ar_config) == AR_SUCCESS);
ArConfig_destroy(ar_config);

최신 원시 깊이 이미지 가져오기

ArFrame_acquireRawDepthImage16Bits()를 호출하여 최신 원시 깊이 이미지를 가져옵니다.

int64_t previous_depth_image_timestamp_ns = -1;
int64_t depth_image_timestamp_ns;
ArImage* depth_image = NULL;

// Acquire the raw depth image for the current frame.
ArStatus acquire_image_status =
    ArFrame_acquireRawDepthImage16Bits(ar_session, ar_frame, &depth_image);

if (acquire_image_status == AR_SUCCESS) {
  // Optional: compare raw depth image timestamps. Use this check if your app
  // uses only new depth data.
  ArImage_getTimestamp(ar_session, depth_image, &depth_image_timestamp_ns);
  if (depth_image_timestamp_ns != previous_depth_image_timestamp_ns) {
    // Raw depth image is based on new depth data.
    previous_depth_image_timestamp_ns = depth_image_timestamp_ns;
    // …
  }
  // Release the acquired image.
  ArImage_release(depth_image);
}

Raw Depth API를 통해 반환되는 모든 이미지 픽셀에 깊이 데이터가 포함되는 것은 아니며, 모든 ARCore 프레임에 새로운 원시 깊이 이미지가 포함되지는 않습니다. 현재 프레임의 원시 깊이 이미지가 새로운지 확인하려면 타임스탬프를 이전 원시 깊이 이미지의 타임스탬프와 비교합니다. 타임스탬프가 다르면 원시 깊이 이미지는 새로운 깊이 데이터를 기반으로 합니다. 그 외의 경우 깊이 이미지는 이전 깊이 데이터를 다시 투영한 것입니다.

최신 신뢰도 이미지 가져오기

ArFrame_acquireRawDepthConfidenceImage()를 호출하여 신뢰도 이미지를 가져옵니다. 신뢰도 이미지를 사용하여 각 원시 깊이 픽셀의 정확성을 확인할 수 있습니다. 신뢰도 이미지는 Y8 형식으로 반환됩니다. 각 픽셀은 부호 없는 8비트 정수입니다. 0은 가장 낮은 신뢰도를 나타내고 255은 가장 높은 신뢰도를 나타냅니다.

// Acquire the raw depth confidence image.
ArImage* confidence_image = NULL;
ArStatus acquire_image_status = ArFrame_acquireRawDepthConfidenceImage(
    ar_session, ar_frame, &confidence_image);

if (acquire_image_status == AR_SUCCESS) {
  // …
  // Release the acquired image.
  ArImage_release(confidence_image);
}