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 zapewnia szacunki głębi o wyższej dokładności, ale obrazy głębi w formacie RAW mogą nie zawierać szacunków głębi dla wszystkich pikseli obrazu z kamery. W przeciwieństwie do tego pełny interfejs Depth API udostępnia szacowaną głębię dla każdego piksela, ale dane o głębi poszczególnych pikseli mogą być mniej dokładne ze względu na wygładzanie i interpolację szacunków głębi. Format i rozmiar obrazów głębi są takie same w obu interfejsach API. Różnią się tylko treści.

Tabela poniżej przedstawia różnice między interfejsem Raw Depth API a pełnym interfejsem Depth API na przykładzie obrazu krzesła i stołu w kuchni.

Interfejs API Zwroty Zdjęcie z aparatu Obraz z głębią Obraz ufności
Raw Depth API
  • obraz głębi w formacie RAW, który zawiera bardzo dokładne oszacowanie głębi dla niektórych, ale nie wszystkich pikseli obrazu z kamery;
  • 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.
  • W ramach tego interfejsu API nie jest udostępniany obraz z poziomem pewności.
Nie dotyczy

Obrazy ufności

W obrazach z poziomem pewności zwróconych przez interfejs Raw Depth API jaśniejsze piksele mają większą wartość pewności. Białe piksele oznaczają pewność, 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 głębi mogą być przydatne podczas tworzenia obiektów AR, w których do wykonywania zadań związanych z rozpoznawaniem 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 zwrócone przez interfejs Raw Depth API będą zawierać dane o głębi, a nie każdy obraz ARCore będzie zawierać nowy obraz głębi w formacie RAW. 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. Za pomocą obrazu z poziomem ufności możesz sprawdzić dokładność każdego piksela głębi w surowym obrazie. 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);
}