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 |
|
|||
Interfejs API pełnej głębi |
|
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.
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 }) }
Pobieraj najnowsze zdjęcia o pełnej głębi i pewności siebie
Wywołaj frame.acquireRawDepthImage16Bits()
, aby pobrać najnowszy obraz z nieprzetworzonej głębi. 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.
Wywołaj metodę frame.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.
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?
- Ukończ laboratorium dotyczące Raw Depth, aby dowiedzieć się, jak stworzyć własną aplikację z zastosowaniem Raw Depth.