Używanie nieprzetworzonej głębi w aplikacji NDK na Androida

Interfejs Raw Depth API dostarcza dane o głębi zdjęcia z aparatu, które ma większą dokładność niż pełne dane Depth API, ale nie zawsze obejmuje każdy piksel. Nieprzetworzone obrazy głębi wraz z pasującymi do nich obrazami ufności mogą być dalej przetwarzane. Dzięki temu aplikacje mogą korzystać tylko z danych szczegółowych, które są dostosowane do danego przypadku użycia.

Zgodność urządzeń

Nieprzetworzona głębokość jest dostępna na wszystkich urządzeniach obsługujących Depth API. Interfejs Raw Depth API, podobnie jak Full Depth API, nie wymaga obsługiwanego sprzętowego czujnika głębokości, takiego jak czujnik czasu lotu. Zarówno interfejs Raw Depth API, jak i Full Depth API korzystają jednak z obsługiwanych czujników sprzętowych, które może posiadać urządzenie.

Porównanie interfejsu Raw Depth API z pełnym interfejsem Depth API

Interfejs Raw Depth API umożliwia szacowanie głębi z większą dokładnością, ale zdjęcia nieprzetworzone mogą nie zawierać szacunków dla wszystkich pikseli na zdjęciu z aparatu. Z kolei pełny interfejs Depth API podaje szacunkową głębię każdego piksela, ale dane dotyczące głębokości piksela mogą być mniej dokładne z powodu wygładzania i interpolacji szacowania głębi. Format i rozmiar obrazów głębi są takie same w obu interfejsach API. Różni się tylko treść.

W tabeli poniżej pokazujemy różnice między interfejsem Raw Depth API a pełnym interfejsem Depth API za pomocą zdjęcia krzesła i stół w kuchni.

API Akcje powrotne Zdjęcie z aparatu Obraz głębi Obraz pewności
Interfejs API Raw Depth
  • Nieprzetworzone zdjęcie z bardzo dokładnym oszacowaniem głębi dla niektórych (ale nie wszystkich) pikseli na zdjęciu.
  • Obraz pewności, który daje pewność przy każdym pikselu obrazu z nieprzetworzoną głębią. Piksele obrazu z aparatu, dla których nie określono szacowanej głębi, mają pewność o wartości 0.
Interfejs API Full Depth
  • Pojedyncze zdjęcie „wygładzone” z oszacowaną głębią dla każdego piksela.
  • Ten interfejs API nie dostarcza obrazu pewności.
Nie dotyczy

Obrazy potwierdzające pewność

Obrazy z nakładem ufności zwracane przez interfejs Raw Depth API – jaśniejsze piksele mają wyższe wartości ufności, przy czym białe piksele reprezentują pełną pewność, a czarne – brak pewności. Ogólnie obszary na zdjęciu z aparatu, które mają więcej tekstury, takie jak drzewo, mają większą pewność nieprzetworzonej głębi niż obszary, które tego nie robią, np. pusta ściana. Powierzchnie bez tekstury mają zwykle wartość zero.

Jeśli urządzenie docelowe ma obsługiwany sprzętowy czujnik głębokości, poziom ufności w obszarach wystarczająco blisko aparatu będzie prawdopodobnie wyższy, nawet na powierzchniach bez tekstur.

Koszt mocy obliczeniowej

Koszt mocy obliczeniowej interfejsu Raw Depth API to około połowy kosztów mocy obliczeniowej interfejsu Depth API.

Przypadki użycia

Za pomocą interfejsu Raw Depth API możesz uzyskiwać obrazy głębi, które dokładniej przedstawiają geometrię obiektów prezentowanych na scenie. Nieprzetworzone dane o głębi mogą być przydatne podczas tworzenia doświadczeń AR, w których zadania polegające na zrozumieniu geometrii wymagają większej dokładności i szczegółów szczegółowości. Przykłady użycia:

  • Rekonstrukcja 3D
  • Pomiary
  • Wykrywanie kształtów

Wymagania wstępne

Zanim przejdziesz dalej, upewnij się, że znasz podstawowe pojęcia związane z AR i wiesz, jak skonfigurować sesję ARCore.

Włącz głębię

W nowej sesji ARCore sprawdź, czy urządzenie użytkownika obsługuje Depth. Z powodu ograniczeń mocy obliczeniowej nie wszystkie urządzenia zgodne z ARCore obsługują interfejs Depth API. Aby oszczędzać zasoby, głębia jest domyślnie wyłączona w ARCore. Włącz tryb głębi, aby aplikacja używała interfejsu 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);

Pobierz najnowsze zdjęcie nieprzetworzone

Wywołaj ArFrame_acquireRawDepthImage16Bits(), aby uzyskać najnowsze zdjęcie nieprzetworzone.

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

Nie wszystkie piksele obrazu zwrócone przez interfejs Raw Depth API zawierają dane o głębi. Nie każda ramka ARCore będzie zawierać nowy obraz nieprzetworzonej głębi. Aby sprawdzić, czy obraz nieprzetworzonej głębi dla bieżącej klatki jest nowy, porównaj jego sygnaturę czasową z sygnaturą czasową poprzedniego zdjęcia nieprzetworzonej głębi. Jeśli sygnatury czasowe są różne, nieprzetworzony obraz głębi jest generowany na podstawie nowych danych o głębi. W przeciwnym razie zdjęcie głębi jest odzwierciedleniem poprzednich danych o głębokości.

Pobierz najnowszy obraz pewności

Wywołaj ArFrame_acquireRawDepthConfidenceImage(), aby uzyskać obraz ufności. Obraz ufności pozwala sprawdzić dokładność każdego piksela nieprzetworzonej głębi. Obrazy ufności są zwracane w formacie Y8. Każdy piksel jest 8-bitową nieoznaczoną liczbą całkowitą. Wartość 0 wskazuje najmniejszy poziom ufności, a 255 – najwyższy.

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