Puoi utilizzare il feed videocamera acquisito da ARCore in una pipeline di machine learning per creare un'esperienza di realtà aumentata intelligente. L'esempio di ARCore ML Kit mostra 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 assegna un'etichetta all'oggetto nella scena virtuale.
L'esempio di ARCore ML Kit è scritto in Kotlin. È disponibile anche come campione ml_kotlin nell'SDK ARCore GitHub di ASL.
Utilizza immagine CPU di ARCore
ARCore acquisisce almeno due insiemi di flussi di immagini per impostazione predefinita:
- Uno stream di immagini CPU utilizzato per il riconoscimento delle caratteristiche e l'elaborazione delle immagini. Per impostazione predefinita, l'immagine CPU ha una risoluzione VGA (640 x 480). ARCore può essere configurato per utilizzare uno stream di immagini a risoluzione più elevata, se necessario.
- Uno stream di texture GPU, che contiene una texture ad alta risoluzione, solitamente a 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 CPU
Non sono previsti costi aggiuntivi se viene utilizzato lo stream predefinito con CPU di dimensioni VGA, perché ARCore lo utilizza per la comprensione del mondo. Richiedere uno stream con una risoluzione diversa può essere costoso, in quanto dovrà essere acquisito uno stream aggiuntivo. Tieni presente che una risoluzione più alta può diventare rapidamente costosa per il tuo modello: raddoppiando la larghezza e l'altezza dell'immagine, la quantità di pixel nell'immagine quadruplica.
Potrebbe essere vantaggioso scalare l'immagine se il modello ha un buon rendimento su un'immagine a risoluzione inferiore.
Configura uno stream di immagini CPU ad alta risoluzione aggiuntivo
Le prestazioni del tuo modello ML possono dipendere dalla risoluzione dell'immagine utilizzata come input. La risoluzione di questi stream può essere regolata modificando l'attuale CameraConfig
mediante 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 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 di rilevamento e monitoraggio degli oggetti on-device.
È dotato di un classificatore approssimativo integrato nell'API e può anche utilizzare modelli di classificazione personalizzati per coprire un dominio di oggetti più ristretto.
Utilizza
InputImage.fromMediaImage
per convertire l'immagine CPU in unInputImage
. - Firebase Machine Learning: Firebase fornisce API per il machine learning che funzionano sia nel cloud che sul dispositivo. Consulta la documentazione di Firebase su Etichetta le immagini in modo sicuro con Cloud Vision utilizzando Firebase Auth e Functions on Android.
Mostra i risultati nella scena AR
I modelli di riconoscimento delle immagini spesso inviano l'output degli 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 restituito dal modello, è possibile collegare un ancoraggio all'oggetto rilevato. Utilizza Frame.hitTest()
per stimare la posa di un oggetto nella scena virtuale.
Converti le coordinate di IMAGE_PIXELS
in 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 test hit e creare un ancoraggio 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 sulle prestazioni
Segui i consigli riportati di seguito per risparmiare potenza di elaborazione e consumare meno energia:
- Non eseguire il modello ML su ogni frame in entrata. Valuta la possibilità di eseguire il rilevamento degli oggetti a una frequenza fotogrammi ridotta.
- Prendi in considerazione un modello di inferenza ML online per ridurre la complessità computazionale.
Passaggi successivi
- Scopri di più sulle best practice per ML Engineering.
- Scopri di più sulle pratiche dell'IA responsabile.
- Segui il corso sulle nozioni di base del machine learning con TensorFlow.