Puoi utilizzare il feed della videocamera acquisito da ARCore in una pipeline di machine learning per creare un'esperienza di realtà aumentata intelligente. L'esempio di ARCore ML Kit illustra come utilizzare ML Kit e l'API Google Cloud Vision per identificare oggetti reali. L'esempio utilizza un modello di machine learning per classificare gli oggetti nel campo visivo della videocamera e applica un'etichetta all'oggetto nella scena virtuale.
L'esempio di ARCore ML Kit è scritto in Kotlin. È anche disponibile come app di esempio ml_kotlin nel repository GitHub di ARCore SDK.
Utilizza l'immagine della CPU di ARCore
Per impostazione predefinita, ARCore acquisisce almeno due insiemi di stream di immagini:
- Uno stream di immagini CPU utilizzato per il riconoscimento delle funzionalità e l'elaborazione di immagini. Per impostazione predefinita, l'immagine della CPU ha una risoluzione VGA (640 x 480). ARCore può essere configurato per utilizzare uno stream di immagini aggiuntivo a risoluzione più elevata, se necessario.
- Uno stream di texture GPU, che contiene una texture ad alta risoluzione, generalmente a una risoluzione di 1080p. In genere viene utilizzata come anteprima della fotocamera rivolta all'utente.
Questo viene memorizzato nella texture OpenGL specificata da
Session.setCameraTextureName()
. - Eventuali stream aggiuntivi specificati da
SharedCamera.setAppSurfaces()
.
Considerazioni sulle dimensioni delle immagini della CPU
Se viene utilizzato lo stream della CPU di dimensioni VGA predefinito non vengono addebitati costi aggiuntivi perché ARCore usa questo stream per la comprensione a livello mondiale. Richiedere uno stream con una risoluzione diversa può essere costoso, in quanto sarà necessario acquisire uno stream aggiuntivo. Tieni presente che una risoluzione più elevata può diventare rapidamente dispendiosa per il tuo modello: raddoppiando la larghezza e l'altezza dell'immagine, quadruplica la quantità di pixel nell'immagine.
Potrebbe essere vantaggioso ridimensionare l'immagine se il modello può comunque funzionare bene su un'immagine a risoluzione più bassa.
Configura un flusso di immagini della CPU ad alta risoluzione aggiuntivo
Le prestazioni del modello ML possono dipendere dalla risoluzione dell'immagine utilizzata come input. La risoluzione di questi stream può essere regolata cambiando l'attuale CameraConfig
con Session.setCameraConfig()
, selezionando una configurazione valida da Session.getSupportedCameraConfigs()
.
Java
CameraConfigFilter cameraConfigFilter = new CameraConfigFilter(session) // World-facing cameras only. .setFacingDirection(CameraConfig.FacingDirection.BACK); List<CameraConfig> supportedCameraConfigs = session.getSupportedCameraConfigs(cameraConfigFilter); // Select an acceptable configuration from supportedCameraConfigs. CameraConfig cameraConfig = selectCameraConfig(supportedCameraConfigs); session.setCameraConfig(cameraConfig);
Kotlin
val cameraConfigFilter = CameraConfigFilter(session) // World-facing cameras only. .setFacingDirection(CameraConfig.FacingDirection.BACK) val supportedCameraConfigs = session.getSupportedCameraConfigs(cameraConfigFilter) // Select an acceptable configuration from supportedCameraConfigs. val cameraConfig = selectCameraConfig(supportedCameraConfigs) session.setCameraConfig(cameraConfig)
Recupera l'immagine CPU
Recupera l'immagine CPU utilizzando Frame.acquireCameraImage()
.
Queste immagini devono essere eliminate non appena non sono più necessarie.
Java
Image cameraImage = null; try { cameraImage = frame.acquireCameraImage(); // Process `cameraImage` using your ML inference model. } catch (NotYetAvailableException e) { // NotYetAvailableException is an exception that can be expected when the camera is not ready // yet. The image may become available on a next frame. } catch (RuntimeException e) { // A different exception occurred, e.g. DeadlineExceededException, ResourceExhaustedException. // Handle this error appropriately. handleAcquireCameraImageFailure(e); } finally { if (cameraImage != null) { cameraImage.close(); } }
Kotlin
// NotYetAvailableException is an exception that can be expected when the camera is not ready yet. // Map it to `null` instead, but continue to propagate other errors. fun Frame.tryAcquireCameraImage() = try { acquireCameraImage() } catch (e: NotYetAvailableException) { null } catch (e: RuntimeException) { // A different exception occurred, e.g. DeadlineExceededException, ResourceExhaustedException. // Handle this error appropriately. handleAcquireCameraImageFailure(e) } // The `use` block ensures the camera image is disposed of after use. frame.tryAcquireCameraImage()?.use { image -> // Process `image` using your ML inference model. }
Elabora l'immagine CPU
Per elaborare l'immagine CPU, possono essere utilizzate varie librerie di machine learning.
- ML Kit: ML Kit fornisce un'API Object Detection and Tracking on-device.
È dotato di un classificatore approssimativo integrato nell'API e può anche utilizzare modelli di classificazione personalizzati per coprire un dominio più ristretto di oggetti.
Utilizza
InputImage.fromMediaImage
per convertire l'immagine CPU inInputImage
. - Firebase Machine Learning: Firebase fornisce API per il machine learning che funzionano nel cloud o sul dispositivo. Consulta la documentazione di Firebase su come etichettare le immagini in modo sicuro con Cloud Vision utilizzando Firebase Auth e Functions su Android.
Visualizza i risultati nella tua scena AR
I modelli di riconoscimento delle immagini spesso restituiscono gli oggetti rilevati indicando un punto centrale o un poligono di delimitazione che rappresenta l'oggetto rilevato.
Utilizzando il punto centrale o il centro del riquadro di delimitazione emesso dal modello, è possibile applicare un ancoraggio all'oggetto rilevato. Utilizza Frame.hitTest()
per stimare la posizione di un oggetto nella scena virtuale.
Converti le coordinate IMAGE_PIXELS
in coordinate VIEW
:
Java
// Suppose `mlResult` contains an (x, y) of a given point on the CPU image. float[] cpuCoordinates = new float[] {mlResult.getX(), mlResult.getY()}; float[] viewCoordinates = new float[2]; frame.transformCoordinates2d( Coordinates2d.IMAGE_PIXELS, cpuCoordinates, Coordinates2d.VIEW, viewCoordinates); // `viewCoordinates` now contains coordinates suitable for hit testing.
Kotlin
// Suppose `mlResult` contains an (x, y) of a given point on the CPU image. val cpuCoordinates = floatArrayOf(mlResult.x, mlResult.y) val viewCoordinates = FloatArray(2) frame.transformCoordinates2d( Coordinates2d.IMAGE_PIXELS, cpuCoordinates, Coordinates2d.VIEW, viewCoordinates ) // `viewCoordinates` now contains coordinates suitable for hit testing.
Utilizza queste coordinate di VIEW
per eseguire un hit test e creare un ancoraggio a partire dal risultato:
Java
List<HitResult> hits = frame.hitTest(viewCoordinates[0], viewCoordinates[1]); HitResult depthPointResult = null; for (HitResult hit : hits) { if (hit.getTrackable() instanceof DepthPoint) { depthPointResult = hit; break; } } if (depthPointResult != null) { Anchor anchor = depthPointResult.getTrackable().createAnchor(depthPointResult.getHitPose()); // This anchor will be attached to the scene with stable tracking. // It can be used as a position for a virtual object, with a rotation prependicular to the // estimated surface normal. }
Kotlin
val hits = frame.hitTest(viewCoordinates[0], viewCoordinates[1]) val depthPointResult = hits.filter { it.trackable is DepthPoint }.firstOrNull() if (depthPointResult != null) { val anchor = depthPointResult.trackable.createAnchor(depthPointResult.hitPose) // This anchor will be attached to the scene with stable tracking. // It can be used as a position for a virtual object, with a rotation prependicular to the // estimated surface normal. }
Considerazioni sul rendimento
Segui i seguenti consigli per risparmiare potenza di elaborazione e consumare meno energia:
- Non eseguire il tuo modello ML su ogni frame in entrata. Valuta invece di eseguire il rilevamento degli oggetti a una frequenza fotogrammi bassa.
- Considera un modello di inferenza ML online per ridurre la complessità di calcolo.
Passaggi successivi
- Scopri di più sulle best practice per ML Engineering.
- Scopri di più sulle pratiche per l'IA responsabile.
- Segui il corso sulle nozioni di base del machine learning con TensorFlow.