Utilizzare la profondità grezza nell'app per Android

L'API Raw depth fornisce dati di profondità per l'immagine di una fotocamera che ha una precisione maggiore rispetto ai dati dell'API Full depth, ma non sempre copre tutti i pixel. Anche le immagini di profondità non elaborate, insieme alle immagini di confidenza corrispondenti, possono essere elaborate ulteriormente, consentendo alle app di usare solo dati di profondità con una precisione sufficiente per il singolo caso d'uso.

Compatibilità dei dispositivi

L'opzione Profondità non elaborata è disponibile su tutti i dispositivi che supportano l'API Profondità. L'API Raw Profondità, come l'API Full depth, non richiede un sensore di profondità hardware supportato, ad esempio un sensore ToF (time-of-flight). Tuttavia, sia l'API Raw depth che l'API Full depth utilizzano qualsiasi sensore hardware supportato di un dispositivo.

API Raw depth e API full depth

L'API Raw Profondità fornisce stime di profondità con maggiore precisione, ma le immagini di profondità non elaborate potrebbero non includere stime di profondità per tutti i pixel nell'immagine della fotocamera. Al contrario, l'API Full depth fornisce una stima della profondità per ogni pixel, ma i dati sulla profondità per pixel potrebbero essere meno precisi a causa del perfezionamento e dell'interpolazione delle stime della profondità. Il formato e le dimensioni delle immagini di profondità sono uguali in entrambe le API. Solo i contenuti differiscono.

La seguente tabella illustra le differenze tra l'API Raw Profondità e l'API Full Profondità utilizzando l'immagine di una sedia e di un tavolo in cucina.

API Ritorni Immagine fotocamera Immagine con profondità Immagine affidabilità
API Raw depth
  • Un'immagine di profondità non elaborata che contiene una stima della profondità molto accurata per alcuni pixel (ma non tutti) nell'immagine della fotocamera.
  • Un'immagine affidabile che dà sicurezza per ogni pixel immagine con profondità non elaborata. I pixel dell'immagine della fotocamera per cui non è disponibile una stima della profondità hanno un'affidabilità pari a zero.
API Full depth
  • Una singola immagine di profondità "smussata" che contiene una stima della profondità per ogni pixel.
  • Questa API non fornisce un'immagine di affidabilità.
N/A

Immagini relative all'affidabilità

Per quanto riguarda l'affidabilità delle immagini restituite dall'API Raw depth, i pixel più chiari presentano valori di affidabilità più elevati, dove i pixel bianchi rappresentano l'affidabilità completa e i pixel neri non rappresentano un'affidabilità. In generale, le aree dell'immagine della fotocamera che hanno più texture, come un albero, hanno un'affidabilità della profondità non elaborata maggiore rispetto alle aree che non hanno più texture, ad esempio un muro vuoto. Le superfici senza texture di solito restituiscono un'affidabilità pari a zero.

Se il dispositivo target è dotato di un sensore di profondità hardware supportato, l'affidabilità nelle aree dell'immagine abbastanza vicine alla fotocamera sarà probabilmente maggiore, anche su superfici senza texture.

Costo calcolo

Il costo di calcolo dell'API Raw depth corrisponde a circa la metà del costo di calcolo per l'API depth completa.

Casi d'uso

Con l'API Raw depth, puoi ottenere immagini di profondità che forniscono una rappresentazione più dettagliata della geometria degli oggetti nella scena. I dati non elaborati di profondità possono essere utili durante la creazione di esperienze AR in cui sono necessari maggiori dettagli e precisione di profondità per le attività di comprensione della geometria. Ecco alcuni casi d'uso:

  • Ricostruzione in 3D
  • Misurazione
  • Rilevamento delle forme

Prerequisiti

Assicurati di aver compreso i concetti fondamentali di AR e di configurare una sessione ARCore prima di procedere.

Attiva profondità

In una nuova sessione ARCore, controlla se il dispositivo di un utente supporta la profondità. Non tutti i dispositivi compatibili con ARCore supportano l'API Profondità a causa dei vincoli della potenza di elaborazione. Per risparmiare risorse, la profondità è disattivata per impostazione predefinita su ARCore. Attiva la modalità depth per fare in modo che la tua app utilizzi l'API Profondità.

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

Acquisisci le ultime immagini non elaborate di profondità e sicurezza

Chiama il numero frame.acquireRawDepthImage16Bits() per acquisire l'ultima immagine di profondità non elaborata. Non tutti i pixel immagine restituiti tramite l'API Raw depth contengono dati di profondità e non tutti i frame ARCore contengono una nuova immagine di profondità non elaborata. Per determinare se l'immagine non elaborata del frame corrente è nuova, confronta il timestamp con il timestamp dell'immagine non elaborata precedente. Se i timestamp sono diversi, l'immagine non elaborata della profondità si basa su nuovi dati sulla profondità. Altrimenti, l'immagine relativa alla profondità è una riproiezione di dati di profondità precedenti.

Chiama frame.acquireRawDepthConfidenceImage() per acquisire l'immagine di confidenza. Puoi utilizzare l'immagine di confidenza per verificare l'accuratezza di ogni pixel di profondità non elaborato. Le immagini di affidabilità vengono restituite in formato Y8. Ogni pixel è un numero intero senza segno a 8 bit. 0 indica la minore affidabilità, mentre 255 indica la massima affidabilità.

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

Passaggio successivo