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

Interfejs Raw Depth API dostarcza dane głębi obrazu z aparatu, które mają większą dokładność niż dane interfejsu Depth API, ale nie zawsze obejmują każdy piksel. Nieprzetworzone obrazy głębi wraz z ich pasującymi obrazami ufności również mogą być dalej przetwarzane, dzięki czemu aplikacje mogą korzystać tylko z tych danych, które są wystarczająco dokładne w danym przypadku użycia.

Zgodność urządzeń

Depth (Nieprzetworzona głębia) jest dostępna na wszystkich urządzeniach, które obsługują interfejs Depth API. Interfejs Raw Depth API, podobnie jak pełny interfejs Depth API, nie wymaga obsługiwanego sprzętowego czujnika głębokości, takiego jak czujnik czasu lotu (ToF). Jednak zarówno interfejs Raw Depth API, jak i full Depth API wykorzystują wszystkie obsługiwane czujniki sprzętowe, które może mieć urządzenie.

Interfejs Raw Depth API a pełną głębię interfejsu API

Interfejs Raw Depth API pozwala uzyskać bardziej dokładne oszacowania głębi, ale nieprzetworzona głębia obrazu może nie uwzględniać wszystkich pikseli na zdjęciu aparatu. W przeciwieństwie do tego pełny interfejs API Depth podaje szacunkową głębię dla każdego piksela, ale dane na piksel mogą być mniej dokładne z powodu wygładzania i interpolacji szacunkowych wartości głębi. Format i rozmiar obrazów głębi są takie same w obu interfejsach API. Różni się tylko ich treść.

W tabeli poniżej przedstawiono różnice między interfejsem Raw Depth API a pełnym interfejsem Depth API na podstawie zdjęcia krzesła i stołu w kuchni.

Interfejs API Zwroty Zdjęcie z aparatu Obraz z głębią Obraz ufności
Interfejs API Raw Depth
  • Obraz z nieprzetworzoną głębią, który zawiera bardzo dokładne oszacowanie głębi w przypadku niektórych pikseli w obrazie.
  • Obraz ufności, który daje pewność dla każdego piksela obrazu z nieprzetworzonej głębi. Poziom ufności pikseli zdjęć z aparatu bez oszacowania głębi wynosi 0.
Interfejs API pełnej głębi
  • Singiel „wygładzone” obraz głębi z szacowaną głębią dla każdego piksela.
  • Ten interfejs API nie zawiera obrazu pewności.
Nie dotyczy

Obrazy ufności

W przypadku obrazów z poziomem ufności zwracanych przez interfejs Raw Depth API jaśniejsze piksele mają wyższe wartości ufności, przy czym białe piksele oznaczają pełny poziom ufności, a czarne – brak pewności. Ogólnie obszary na zdjęciu z kamery, które mają większą teksturę, takie jak drzewo, mają większą głębię pewności niż te, w których nie ma takiej głębi, takie jak pusta ściana. W przypadku powierzchni bez tekstury stopień ufności wynosi 0.

Jeśli urządzenie docelowe ma obsługiwany sprzętowy czujnik głębi, stopień pewności w obszarach obrazu znajdujących się wystarczająco blisko aparatu jest prawdopodobnie wyższy, nawet na powierzchniach bez tekstur.

Koszt mocy obliczeniowej

Koszt mocy obliczeniowej interfejsu Raw Depth API to około połowy kosztu mocy obliczeniowej pełnego interfejsu Depth API.

Przypadki użycia

Interfejs Raw Depth API umożliwia uzyskiwanie obrazów głębi, które zapewniają bardziej szczegółową reprezentację geometrii obiektów na scenie. Nieprzetworzone dane o głębi mogą być przydatne podczas tworzenia obiektów AR, w których do rozumienia geometrii potrzebna jest większa dokładność i więcej szczegółów. Oto niektóre przypadki użycia:

  • Rekonstrukcja 3D
  • Pomiary
  • Wykrywanie kształtu

Wymagania wstępne

Upewnij się, że znasz podstawowe pojęcia związane z AR. i dowiedz się, jak skonfigurować sesję ARCore, zanim przejdziesz dalej.

Włącz głębię

W nowej sesji ARCore sprawdź, czy urządzenie użytkownika obsługuje Depth. Nie wszystkie urządzenia zgodne z ARCore obsługują Depth API ze względu na ograniczenia mocy obliczeniowej. Aby można było oszczędzać zasoby, głębokość 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);

Uzyskaj najnowszy obraz z nieprzetworzoną głębią

Wywołaj ArFrame_acquireRawDepthImage16Bits(), aby pobrać najnowszy obraz z nieprzetworzonej głębi.

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 zwracane przez interfejs Raw Depth API zawierają dane o głębi, a nie każda klatka ARCore zawiera nowy obraz z nieprzetworzoną głębią. Aby określić, czy obraz z bieżącą głębią obrazu jest nowy, porównaj jego sygnaturę czasową z sygnaturą czasową poprzedniego obrazu z nieprzetworzoną głębią. Jeśli sygnatury czasowe są różne, obraz z nieprzetworzoną głębią jest oparty na nowych danych o głębi. W przeciwnym razie obraz głębi odzwierciedla odwzorowanie poprzednich danych o głębi.

Uzyskanie najnowszego obrazu pewności

Wywołaj metodę ArFrame_acquireRawDepthConfidenceImage(), aby uzyskać obraz ufności. Obrazu ufności możesz użyć do sprawdzenia dokładności każdego piksela nieprzetworzonej głębi. Obrazy ufności są zwracane w formacie Y8. Każdy piksel to 8-bitowa nieoznaczona liczba całkowita. 0 oznacza 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);
}