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 |
|
|||
Interfejs API Full Depth |
|
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.
Java
Config config = session.getConfig(); // Check whether the user's device supports Depth. if (session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)) { // Enable depth mode. config.setDepthMode(Config.DepthMode.AUTOMATIC); } session.configure(config);
Kotlin
if (session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)) { session.configure(session.config.apply { depthMode = Config.DepthMode.AUTOMATIC }) }
Pobierz najnowsze obrazy nieprzetworzone
Wywołaj frame.acquireRawDepthImage16Bits()
, aby uzyskać najnowsze zdjęcie nieprzetworzone. 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.
Wywołaj frame.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.
Java
// Use try-with-resources, so that images are released automatically. try ( // Depth image is in uint16, at GPU aspect ratio, in native orientation. Image rawDepth = frame.acquireRawDepthImage16Bits(); // Confidence image is in uint8, matching the depth image size. Image rawDepthConfidence = frame.acquireRawDepthConfidenceImage(); ) { // Compare timestamps to determine whether depth is is based on new // depth data, or is a reprojection based on device movement. boolean thisFrameHasNewDepthData = frame.getTimestamp() == rawDepth.getTimestamp(); if (thisFrameHasNewDepthData) { ByteBuffer depthData = rawDepth.getPlanes()[0].getBuffer(); ByteBuffer confidenceData = rawDepthConfidence.getPlanes()[0].getBuffer(); int width = rawDepth.getWidth(); int height = rawDepth.getHeight(); someReconstructionPipeline.integrateNewImage(depthData, confidenceData, width, height); } } catch (NotYetAvailableException e) { // Depth image is not (yet) available. }
Kotlin
try { // Depth image is in uint16, at GPU aspect ratio, in native orientation. frame.acquireRawDepthImage16Bits().use { rawDepth -> // Confidence image is in uint8, matching the depth image size. frame.acquireRawDepthConfidenceImage().use { rawDepthConfidence -> // Compare timestamps to determine whether depth is is based on new // depth data, or is a reprojection based on device movement. val thisFrameHasNewDepthData = frame.timestamp == rawDepth.timestamp if (thisFrameHasNewDepthData) { val depthData = rawDepth.planes[0].buffer val confidenceData = rawDepthConfidence.planes[0].buffer val width = rawDepth.width val height = rawDepth.height someReconstructionPipeline.integrateNewImage( depthData, confidenceData, width = width, height = height ) } } } } catch (e: NotYetAvailableException) { // Depth image is not (yet) available. }
Co dalej?
- Aby dowiedzieć się, jak stworzyć własną aplikację z wykorzystaniem surowej głębokości, wykonaj ćwiczenie z programowania dotyczące głębokości kodu.