Anda dapat menggunakan feed kamera yang direkam ARCore di pipeline machine learning untuk menciptakan pengalaman augmented reality yang cerdas. Contoh ARCore ML Kit menunjukkan cara menggunakan ML Kit dan Google Cloud Vision API untuk mengidentifikasi objek di dunia nyata. Sampel ini menggunakan model machine learning untuk mengklasifikasikan objek dalam tampilan kamera dan melampirkan label ke objek dalam adegan virtual.
Contoh ARCore ML Kit ditulis dalam Kotlin. Alat ini juga tersedia sebagai aplikasi contoh ml_kotlin di repositori GitHub ARCore SDK.
Menggunakan image CPU ARCore
ARCore menangkap setidaknya dua kumpulan aliran gambar secara default:
- Aliran gambar CPU yang digunakan untuk pengenalan fitur dan pemrosesan gambar. Secara default, gambar CPU memiliki resolusi VGA (640x480). ARCore dapat dikonfigurasi untuk menggunakan streaming gambar tambahan dengan resolusi lebih tinggi, jika diperlukan.
- Aliran tekstur GPU, yang berisi tekstur resolusi tinggi, biasanya pada resolusi 1080p. Hal ini biasanya digunakan sebagai pratinjau kamera yang ditampilkan kepada pengguna.
Ini disimpan di tekstur OpenGL yang ditentukan oleh
Session.setCameraTextureName()
. - Feed tambahan apa pun yang ditentukan oleh
SharedCamera.setAppSurfaces()
.
Pertimbangan ukuran image CPU
Tidak ada biaya tambahan yang dikeluarkan jika streaming CPU berukuran VGA default digunakan karena ARCore menggunakan streaming ini untuk pemahaman dunia. Meminta streaming dengan resolusi yang berbeda mungkin mahal, karena streaming tambahan perlu direkam. Ingatlah bahwa resolusi yang lebih tinggi dapat dengan cepat menjadi mahal untuk model Anda: menggandakan lebar dan tinggi gambar akan menghasilkan empat kali lipat jumlah piksel dalam gambar.
Ini mungkin menguntungkan untuk menurunkan ukuran gambar, jika model Anda tetap dapat bekerja dengan baik pada gambar resolusi lebih rendah.
Mengonfigurasi streaming gambar CPU resolusi tinggi tambahan
Performa model ML Anda mungkin bergantung pada resolusi gambar yang digunakan sebagai input. Resolusi streaming ini dapat disesuaikan dengan mengubah CameraConfig
saat ini menggunakan Session.setCameraConfig()
, dengan memilih konfigurasi yang valid dari 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)
Mengambil image CPU
Ambil CPU image menggunakan Frame.acquireCameraImage()
.
Gambar ini harus dibuang segera setelah tidak diperlukan lagi.
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. }
Memproses image CPU
Untuk memproses image CPU, berbagai library machine learning dapat digunakan.
- ML Kit: ML Kit menyediakan Deteksi dan Pelacakan Objek API di perangkat.
Class ini dilengkapi dengan pengklasifikasi kasar yang dibangun ke dalam API, dan juga dapat menggunakan model klasifikasi kustom untuk mencakup domain objek yang lebih sempit.
Gunakan
InputImage.fromMediaImage
untuk mengonversi image CPU menjadiInputImage
. - Firebase Machine Learning: Firebase menyediakan Machine Learning API yang berfungsi di cloud atau di perangkat. Lihat dokumentasi Firebase tentang Memberi Label pada Gambar secara Aman dengan Cloud Vision menggunakan Firebase Auth dan Functions di Android.
Menampilkan hasil dalam scene AR
Model pengenalan citra sering menghasilkan objek yang terdeteksi dengan menunjukkan titik tengah atau poligon pembatas yang mewakili objek yang terdeteksi.
Dengan menggunakan titik tengah atau tengah kotak pembatas yang merupakan output dari model, Anda bisa memasang anchor ke objek yang terdeteksi. Gunakan Frame.hitTest()
untuk memperkirakan pose objek dalam adegan virtual.
Konversi koordinat IMAGE_PIXELS
menjadi koordinat 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.
Gunakan koordinat VIEW
ini untuk melakukan hit test dan membuat anchor dari hasil:
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. }
Pertimbangan performa
Ikuti rekomendasi berikut untuk menghemat daya pemrosesan dan mengonsumsi lebih sedikit energi:
- Jangan menjalankan model ML Anda di setiap frame yang masuk. Sebaiknya jalankan deteksi objek pada kecepatan frame rendah.
- Pertimbangkan model inferensi ML online untuk mengurangi kompleksitas komputasi.
Langkah berikutnya
- Pelajari Praktik Terbaik untuk Rekayasa ML.
- Pelajari praktik responsible AI.
- Ikuti kursus dasar-dasar machine learning dengan TensorFlow.