„Rohtiefe“ in Ihrer Android-App verwenden

Die Raw Depth API liefert Tiefendaten für ein Kamerabild, die eine höhere Genauigkeit als vollständige Depth API-Daten haben, deckt jedoch nicht immer jedes Pixel ab. Rohtiefenbilder und die zugehörigen Konfidenzbilder können auch weiter verarbeitet werden, sodass Apps nur die Tiefendaten verwenden können, die eine ausreichende Genauigkeit für ihren jeweiligen Anwendungsfall haben.

Eingeschränkte Gerätekompatibilität

„Raw Depth“ ist auf allen Geräten verfügbar, die die Depth API unterstützen. Wie die Full Depth API benötigt die Raw Depth API keinen unterstützten Hardware-Tiefensensor wie einen Time-of-Flight-Sensor. Sowohl die Raw Depth API als auch die vollständige Depth API verwenden jedoch alle unterstützten Hardwaresensoren eines Geräts.

Raw Depth API und Full Depth API im Vergleich

Die Raw Depth API ermöglicht Tiefenschätzungen mit höherer Genauigkeit, aber die Bilder für die Rohtiefe enthalten möglicherweise nicht für alle Pixel im Kamerabild Tiefenschätzungen. Im Gegensatz dazu liefert die Full Depth API die geschätzte Tiefe für jedes Pixel. Die Daten für die Tiefen pro Pixel sind jedoch möglicherweise aufgrund der Glättung und Interpolation der Tiefenschätzungen weniger genau. Das Format und die Größe der Tiefenbilder sind in beiden APIs gleich. Nur der Inhalt ist anders.

In der folgenden Tabelle werden die Unterschiede zwischen der Raw Depth API und der Full Depth API anhand des Bildes eines Stuhls und eines Tisches in einer Küche dargestellt.

API Rückgaben Kamerabild Tiefenbild Konfidenzbild
Raw Depth API
  • Ein Rohtiefenbild, das eine sehr genaue Tiefenschätzung für einige, aber nicht alle Pixel im Kamerabild enthält.
  • Ein Konfidenzbild, das die Konfidenz für jedes Bildpixel mit Rohtiefe angibt. Kamerabildpixel, die keine Tiefenschätzung haben, haben eine Konfidenz von null.
Full Depth API
  • Ein einzelnes "geglättetes" Tiefenbild, das eine Schätzung der Tiefe für jedes Pixel enthält.
  • Mit dieser API wird kein Konfidenzbild bereitgestellt.

Konfidenzbilder

In Konfidenzbildern, die von der Raw Depth API zurückgegeben werden, haben hellere Pixel höhere Konfidenzwerte, wobei weiße Pixel für die volle Konfidenz und schwarze Pixel für keine Konfidenz stehen. Im Allgemeinen weisen Bereiche im Kamerabild mit mehr Textur, z. B. ein Baum, ein höheres Konfidenzniveau für die Tiefentiefe auf als Regionen, in denen dies nicht der Fall ist, z. B. eine leere Wand. Oberflächen ohne Textur haben in der Regel einen Konfidenzwert von null.

Wenn das Zielgerät über einen unterstützten Hardware-Tiefensensor verfügt, ist die Konfidenz in Bereichen des Bildes, die nahe genug an der Kamera sind, wahrscheinlich höher, selbst auf texturlosen Oberflächen.

Compute-Kosten

Die Computing-Kosten der Raw Depth API betragen etwa die Hälfte der Computing-Kosten für die vollständige Depth API.

Anwendungsfälle

Mit der Raw Depth API können Sie Tiefenbilder abrufen, die eine detailliertere Darstellung der Geometrie der Objekte in der Szene bieten. Rohtiefendaten können bei der Erstellung von AR-Anwendungen nützlich sein, bei denen eine höhere Tiefengenauigkeit und mehr Details zum Verständnis der Geometrie erforderlich sind. Einige Anwendungsfälle:

  • 3D-Rekonstruktion
  • Messwerte ermitteln
  • Formerkennung

Voraussetzungen

Machen Sie sich mit den grundlegenden AR-Konzepten und zur Konfiguration einer ARCore-Sitzung vertraut, bevor Sie fortfahren.

Tiefe aktivieren

Prüfen Sie in einer neuen ARCore-Sitzung, ob das Gerät eines Nutzers die Funktion „Tiefe“ unterstützt. Die Depth API wird aufgrund von Einschränkungen bei der Verarbeitungsleistung nicht von allen ARCore-kompatiblen Geräten unterstützt. Die Tiefe ist bei ARCore standardmäßig deaktiviert, um Ressourcen zu sparen. Aktivieren Sie den Tiefenmodus, damit Ihre Anwendung die Depth API verwendet.

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

Die neuesten Bilder mit Tiefentiefe und Konfidenz abrufen

Rufen Sie frame.acquireRawDepthImage16Bits() auf, um das neueste Bild mit Tiefentiefe aufzunehmen. Nicht alle Bildpixel, die über die Raw Depth API zurückgegeben werden, enthalten Tiefendaten und nicht jeder ARCore-Frame enthält ein neues Rohtiefenbild. Um zu ermitteln, ob das Rohtiefenbild für den aktuellen Frame neu ist, vergleichen Sie seinen Zeitstempel mit dem Zeitstempel des vorherigen Bildtiefenbilds. Wenn sich die Zeitstempel unterscheiden, basiert das Tiefenbild auf neuen Tiefendaten. Andernfalls ist das Tiefenbild eine Reprojektion früherer Tiefendaten.

Rufen Sie frame.acquireRawDepthConfidenceImage() auf, um das Konfidenzbild abzurufen. Sie können das Konfidenzbild verwenden, um die Genauigkeit der einzelnen Tiefenpixel zu überprüfen. Konfidenzbilder werden im Y8-Format zurückgegeben. Jedes Pixel ist eine vorzeichenlose 8-Bit-Ganzzahl. 0 gibt die geringste Konfidenz an, während 255 die höchste Konfidenz angibt.

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.
}

Nächste Schritte

  • Im Codelab zu Rohdaten erfahren Sie, wie Sie Ihre eigene App mit Raw Depth erstellen können.