Utiliser la profondeur brute dans votre application Android

L'API Raw Depth fournit des données de profondeur pour une image d'appareil photo dont la précision est supérieure à celle de l'API Depth, mais ne couvre pas toujours tous les pixels. Les images de profondeur brutes, ainsi que les images de confiance correspondantes, peuvent également être traitées de manière plus approfondie, ce qui permet aux applications d'utiliser uniquement les données de profondeur suffisamment précises pour leur cas d'utilisation individuel.

Compatibilité avec les appareils

Raw Depth est disponible sur tous les appareils compatibles avec l'API Depth. L'API Raw Depth, comme l'API Depth complète, ne nécessite pas de capteur de profondeur matériel compatible, comme un capteur de temps de vol. Cependant, l'API Raw Depth et l'API Depth complète utilisent tous les deux les capteurs matériels compatibles d'un appareil.

Comparaison entre l'API Raw Depth et l'API Full Depth

L'API Raw Depth fournit des estimations de profondeur plus précises, mais les représentations de profondeur brutes peuvent ne pas inclure d'estimation de profondeur pour tous les pixels de l'image de l'appareil photo. En revanche, l'API Depth complète fournit une estimation de la profondeur pour chaque pixel, mais les données de profondeur par pixel peuvent être moins précises en raison du lissage et de l'interpolation des estimations de profondeur. Le format et la taille des représentations de profondeur sont les mêmes dans les deux API. Seul le contenu diffère.

Le tableau suivant illustre les différences entre l'API Raw Depth et l'API Depth complète à l'aide d'une image représentant une chaise et une table dans une cuisine.

API Renvoie Image de la caméra Image de profondeur Image de confiance
API Raw Depth
  • Image de profondeur brute contenant une estimation très précise de la profondeur pour certains pixels de l'image de l'appareil photo, mais pas tous.
  • Image de confiance qui donne la confiance pour chaque pixel de profondeur brute. Pour les pixels de l'image de l'appareil photo qui n'ont pas d'estimation de profondeur, le niveau de confiance est de zéro.
API Full Depth
  • Une seule image de profondeur "lissée" contenant une estimation de la profondeur pour chaque pixel
  • Image "Aucune confiance" fournie avec cette API.
N/A

Images de confiance

Dans les images de confiance renvoyées par l'API Raw Depth, les pixels plus clairs ont un niveau de confiance plus élevé, les pixels blancs correspondant à l'indice de confiance maximal et les pixels noirs à l'absence de confiance. En général, les zones de l'image de l'appareil photo qui présentent davantage de texture, comme un arbre, présentent un niveau de confiance de profondeur plus élevé que les régions qui n'en ont pas, comme un mur blanc. Les surfaces sans texture affichent généralement un indice de confiance de zéro.

Si l'appareil cible est équipé d'un capteur de profondeur matériel compatible, la confiance dans les zones de l'image suffisamment proches de l'appareil photo sera probablement plus élevée, même sur des surfaces sans texture.

Coût de calcul

Le coût de calcul de l'API Raw Depth représente environ la moitié de celui de l'API Depth complète.

Cas d'utilisation

L'API Raw Depth permet d'obtenir des représentations de profondeur qui fournissent une représentation plus détaillée de la géométrie des objets de la scène. Les données de profondeur brutes peuvent être utiles pour créer des expériences de RA dans lesquelles la précision et la précision de la profondeur sont nécessaires pour les tâches de compréhension de la géométrie. Voici quelques cas d'utilisation:

  • Reconstruction 3D
  • Mesure
  • Détection de formes

Conditions préalables

Assurez-vous de bien comprendre les concepts fondamentaux de la RA et de configurer une session ARCore avant de continuer.

Activer la profondeur

Dans une nouvelle session ARCore, vérifiez si l'appareil d'un utilisateur est compatible avec Depth. Certains appareils compatibles avec ARCore ne sont pas compatibles avec l'API Depth en raison de contraintes de puissance de traitement. Pour économiser les ressources, la profondeur est désactivée par défaut sur ARCore. Activez le mode Profondeur pour que votre application utilise l'API Depth.

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

Obtenez les dernières images de profondeur et de confiance brutes

Appelez frame.acquireRawDepthImage16Bits() pour acquérir la dernière image de profondeur brute. Les pixels d'image renvoyés via l'API Raw Depth ne contiennent pas tous des données de profondeur, et toutes les images ARCore ne contiennent pas toutes une nouvelle profondeur de couleur brute. Pour déterminer si la représentation de profondeur brute de l'image actuelle est nouvelle, comparez son code temporel avec celui de la précédente image de profondeur. Si les codes temporels sont différents, la représentation de profondeur brute est basée sur les nouvelles données de profondeur. Sinon, la représentation de profondeur est une reprojection des données de profondeur précédentes.

Appelez frame.acquireRawDepthConfidenceImage() pour acquérir l'image de confiance. Vous pouvez utiliser l'image de confiance pour vérifier la précision de chaque pixel de profondeur brute. Les images de confiance sont renvoyées au format Y8. Chaque pixel est un entier non signé de 8 bits. 0 indique le niveau de confiance le moins élevé, tandis que 255 indique le niveau le plus élevé.

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

Et ensuite ?