Cara membuat aplikasi augmented reality menggunakan ARCore

Cara membuat aplikasi augmented reality menggunakan ARCore


Dalam panduan ini, Anda akan belajar cara menambahkan model 3D ke dunia nyata. Pustaka ARCore Google memungkinkan Anda untuk menambahkan model 3D lengkap ke gambar 2D (gambar atau video).


Anda perlu memberi sistem semacam gambar referensi, yang akan dicari ARCore di dunia nyata untuk menambahkan model 3D ke gambar yang didasarkan padanya. Augmented reality sudah banyak digunakan, misalnya, di buku, koran, majalah, dll.


Sebelum masuk ke tutorial ini, Anda harus membiasakan diri dengan dua artikel sebelumnya tentang topik ini yang akan memperkenalkan Anda pada ketentuan AR dasar:



Apa itu gambar augmented reality?


Menurut dokumentasi untuk pengembang , gambar augmented reality di ARCore memungkinkan Anda membuat aplikasi augmented reality yang dapat "menghidupkan" gambar 2D, seperti poster atau kemasan produk.


Anda mengunggah beberapa gambar referensi ke ARCore, dan kemudian itu memberi tahu Anda tentang deteksi mereka selama sesi AR, misalnya, saat merekam video. Dan informasi ini digunakan untuk memposisikan model 3D pada gambar 2D.


Keterbatasan dalam Menggunakan Gambar Augmented Reality


Berikut adalah beberapa batasan yang mungkin Anda temui saat menggunakan gambar augmented reality:


  • ARCore hanya dapat memproses hingga 20 gambar referensi dalam satu waktu.
  • Bidang fisik di dunia nyata harus datar, dan luasnya harus lebih dari 15 cm x 15 cm.
  • ARCore tidak dapat melacak gambar dan objek bergerak.

Memilih Gambar Referensi yang Tepat


Berikut adalah beberapa tips untuk memilih gambar referensi yang bagus untuk ARCore:


  • Gambar augmented reality mendukung format PNG, JPEG dan JPG.
  • Tidak masalah apakah gambar itu berwarna atau hitam dan putih, yang terpenting adalah kontrasnya tinggi.
  • Resolusi gambar harus minimal 300 x 300 piksel.
  • Menggunakan gambar beresolusi tinggi tidak berarti peningkatan kinerja.
  • Gambar dengan pola berulang (seperti pola atau bintik-bintik) harus dihindari.
  • Gunakan alat arcoreimg untuk mengevaluasi seberapa baik gambar Anda bekerja. Rating minimal 75 poin direkomendasikan.

Cara menggunakan alat arcoreimg:


  • Unduh ARCore SDK untuk Android dari tautan ini .
  • Buka zip konten file ke lokasi mana pun.
  • Di folder yang diekstraksi, buka alat> arcoreimg> windows (bahkan jika Anda memiliki Linux atau macOS).
  • Buka prompt perintah di direktori ini.
  • Dan masukkan perintah ini:

arcoreimg.exe eval-img --input_image_path=dog.png 

Ganti dog.png dengan path lengkap ke gambar Anda.


Memulai dengan aplikasi augmented reality


Sekarang setelah Anda membiasakan diri dengan ARCore dan memilih gambar yang bagus dengan peringkat 75+, sekarang saatnya untuk mulai menulis kode aplikasi.


Penciptaan fragmen


Kami akan membuat fragmen dan menambahkannya ke Aktivitas kami. Buat kelas yang disebut CustomArFragment dan mewarisinya dari ArFragment . Berikut adalah kode untuk CustomArFragment :


 package com.ayusch.augmentedimages; import android.util.Log; import com.google.ar.core.Config; import com.google.ar.core.Session; import com.google.ar.sceneform.ux.ArFragment; public class CustomArFragment extends ArFragment { @Override protected Config getSessionConfiguration(Session session) { getPlaneDiscoveryController().setInstructionView(null); Config config = new Config(session); config.setUpdateMode(Config.UpdateMode.LATEST_CAMERA_IMAGE); session.configure(config); getArSceneView().setupSession(session); return config; } } 

Pertama-tama, kami mematikan deteksi pesawat. Dengan melakukan ini, kami menghapus ikon tangan dari layar yang muncul segera setelah fragmen diinisialisasi dan memberi tahu pengguna tentang perlunya memindahkan ponsel cerdasnya untuk menemukan pesawat. Kami tidak membutuhkan ini lagi, karena kami menemukan bukan pesawat acak, tetapi gambar konkret.


Kemudian kami mengatur mode pembaruan untuk sesi LATEST_CAMERA_IMAGE . Ini memastikan bahwa kami akan diberitahu tentang pembaruan gambar setiap kali bingkai kamera diperbarui.


Pengaturan Database Gambar


Tambahkan gambar referensi yang dipilih (yang ingin Anda temukan di dunia fisik) ke folder aset (buat jika belum). Sekarang kita dapat menambahkan gambar ke basis data kita.


Kami akan membuat database ini segera setelah fragmen dibuat. Dalam log kami menampilkan hasil operasi ini:


 if ((((MainActivity) getActivity()).setupAugmentedImagesDb(config, session))) { Log.d("SetupAugImgDb", "Success"); } else { Log.e("SetupAugImgDb","Faliure setting up db"); } 

Begini tampilannya CustomArFragment :


 package com.ayusch.augmentedimages; import android.util.Log; import com.google.ar.core.Config; import com.google.ar.core.Session; import com.google.ar.sceneform.ux.ArFragment; public class CustomArFragment extends ArFragment { @Override protected Config getSessionConfiguration(Session session) { getPlaneDiscoveryController().setInstructionView(null); Config config = new Config(session); config.setUpdateMode(Config.UpdateMode.LATEST_CAMERA_IMAGE); session.configure(config); getArSceneView().setupSession(session); if ((((MainActivity) getActivity()).setupAugmentedImagesDb(config, session))) { Log.d("SetupAugImgDb", "Success"); } else { Log.e("SetupAugImgDb","Faliure setting up db"); } return config; } } 

Segera kami akan menambahkan metode setupAugmentedImagesDb ke MainActivity . Sekarang mari kita tambahkan CustomArFragment ke activity_main.xml kami:


 <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <fragment android:id="@+id/sceneform_fragment" android:name="com.ayusch.augmentedimages.CustomArFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.constraint.ConstraintLayout> 

Menambahkan gambar ke database


Sekarang kita akan mengatur basis data gambar kita, menemukan gambar referensi di dunia nyata dan menambahkan model 3D ke gambar.


Mari kita mulai dengan mengatur basis data kita. Buat metode setupAugmentedImagesDb publik di kelas MainActivity :


 public boolean setupAugmentedImagesDb(Config config, Session session) { AugmentedImageDatabase augmentedImageDatabase; Bitmap bitmap = loadAugmentedImage(); if (bitmap == null) { return false; } augmentedImageDatabase = new AugmentedImageDatabase(session); augmentedImageDatabase.addImage("tiger", bitmap); config.setAugmentedImageDatabase(augmentedImageDatabase); return true; } private Bitmap loadAugmentedImage() { try (InputStream is = getAssets().open("blanket.jpeg")) { return BitmapFactory.decodeStream(is); } catch (IOException e) { Log.e("ImageLoad", "IO Exception", e); } return null; } 

Kami juga menciptakan metode loadAugmentedImage yang memuat gambar dari folder sumber daya dan mengembalikan bitmap.


Di setupAugmentedImagesDb kami pertama-tama menginisialisasi database kami untuk sesi saat ini, dan kemudian menambahkan gambar ke database ini. Kami menamai gambar harimau kami . Kemudian kami menginstal database ini di config dan mengembalikan true , menunjukkan bahwa gambar berhasil ditambahkan.


Deteksi gambar referensi dunia nyata


Sekarang kita akan mulai menemukan gambar referensi kita di dunia nyata. Untuk melakukan ini, kita akan membuat pendengar yang akan dipanggil setiap kali bingkai video diperbarui, dan bingkai ini akan dianalisis untuk kehadiran gambar referensi di sana.


Tambahkan baris ini ke metode onCreate() di MainActivity :


 arFragment.getArSceneView().getScene().addOnUpdateListener(this::onUpdateFrame); 

Sekarang tambahkan metode onUpdateFrame ke MainActivity :


 @RequiresApi(api = Build.VERSION_CODES.N) private void onUpdateFrame(FrameTime frameTime) { Frame frame = arFragment.getArSceneView().getArFrame(); Collection<AugmentedImage> augmentedImages = frame.getUpdatedTrackables(AugmentedImage.class); for (AugmentedImage augmentedImage : augmentedImages) { if (augmentedImage.getTrackingState() == TrackingState.TRACKING) { if (augmentedImage.getName().equals("tiger") && shouldAddModel) { placeObject(arFragment, augmentedImage.createAnchor(augmentedImage.getCenterPose()), Uri.parse("Mesh_BengalTiger.sfb")); shouldAddModel = false; } } } } 

Di baris pertama kita mendapatkan frame itu sendiri. Bingkai dapat dibayangkan sebagai tangkapan layar biasa dari video. Jika Anda terbiasa dengan cara video bekerja, Anda tahu bahwa itu hanya kumpulan gambar yang saling berubah dengan sangat cepat, memberikan kesan sesuatu bergerak. Kami hanya mengambil satu dari foto-foto ini.


Setelah kami menerima bingkai, kami menganalisisnya untuk keberadaan gambar referensi kami di atasnya. Kami mengambil daftar semua item yang dilacak oleh ARCore menggunakan frame.getUpdatedTrackables . Kemudian kita beralih dan memeriksa apakah gambar harimau kita ada di dalam bingkai.


Jika kecocokan ditemukan, maka kami cukup mengambil dan menempatkan model 3D di atas gambar yang terdeteksi.


Catatan Bendera shouldAddModel digunakan sehingga kami menambahkan model 3D hanya sekali.

Menempatkan model 3D di atas gambar referensi


Sekarang kami telah menemukan gambar referensi kami di dunia nyata, kami dapat menambahkan model 3D di atasnya. Tambahkan metode placeObject dan addNodeToScene :


  • placeObject : metode ini digunakan untuk membangun objek yang dirender menggunakan Uri diberikan. Setelah rendering selesai, objek diteruskan ke metode addNodeToScene , di mana objek dilampirkan ke node, dan node ini ditempatkan di tempat kejadian.
  • addNodeToScene : metode ini membuat simpul dari jangkar yang dihasilkan, membuat simpul lain tempat objek yang divisualisasikan bergabung, kemudian menambahkan simpul ini ke simpul jangkar dan menempatkannya di atas panggung.

Inilah yang terlihat seperti MainActivity :


 package com.ayusch.augmentedimages; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Build; import android.support.annotation.RequiresApi; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.widget.Toast; import com.google.ar.core.Anchor; import com.google.ar.core.AugmentedImage; import com.google.ar.core.AugmentedImageDatabase; import com.google.ar.core.Config; import com.google.ar.core.Frame; import com.google.ar.core.Session; import com.google.ar.core.TrackingState; import com.google.ar.sceneform.AnchorNode; import com.google.ar.sceneform.FrameTime; import com.google.ar.sceneform.rendering.ModelRenderable; import com.google.ar.sceneform.rendering.Renderable; import com.google.ar.sceneform.ux.ArFragment; import com.google.ar.sceneform.ux.TransformableNode; import java.io.IOException; import java.io.InputStream; import java.util.Collection; public class MainActivity extends AppCompatActivity { ArFragment arFragment; boolean shouldAddModel = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); arFragment = (CustomArFragment) getSupportFragmentManager().findFragmentById(R.id.sceneform_fragment); arFragment.getPlaneDiscoveryController().hide(); arFragment.getArSceneView().getScene().addOnUpdateListener(this::onUpdateFrame); } @RequiresApi(api = Build.VERSION_CODES.N) private void placeObject(ArFragment arFragment, Anchor anchor, Uri uri) { ModelRenderable.builder() .setSource(arFragment.getContext(), uri) .build() .thenAccept(modelRenderable -> addNodeToScene(arFragment, anchor, modelRenderable)) .exceptionally(throwable -> { Toast.makeText(arFragment.getContext(), "Error:" + throwable.getMessage(), Toast.LENGTH_LONG).show(); return null; } ); } @RequiresApi(api = Build.VERSION_CODES.N) private void onUpdateFrame(FrameTime frameTime) { Frame frame = arFragment.getArSceneView().getArFrame(); Collection<AugmentedImage> augmentedImages = frame.getUpdatedTrackables(AugmentedImage.class); for (AugmentedImage augmentedImage : augmentedImages) { if (augmentedImage.getTrackingState() == TrackingState.TRACKING) { if (augmentedImage.getName().equals("tiger") && shouldAddModel) { placeObject(arFragment, augmentedImage.createAnchor(augmentedImage.getCenterPose()), Uri.parse("Mesh_BengalTiger.sfb")); shouldAddModel = false; } } } } public boolean setupAugmentedImagesDb(Config config, Session session) { AugmentedImageDatabase augmentedImageDatabase; Bitmap bitmap = loadAugmentedImage(); if (bitmap == null) { return false; } augmentedImageDatabase = new AugmentedImageDatabase(session); augmentedImageDatabase.addImage("tiger", bitmap); config.setAugmentedImageDatabase(augmentedImageDatabase); return true; } private Bitmap loadAugmentedImage() { try (InputStream is = getAssets().open("blanket.jpeg")) { return BitmapFactory.decodeStream(is); } catch (IOException e) { Log.e("ImageLoad", "IO Exception", e); } return null; } private void addNodeToScene(ArFragment arFragment, Anchor anchor, Renderable renderable) { AnchorNode anchorNode = new AnchorNode(anchor); TransformableNode node = new TransformableNode(arFragment.getTransformationSystem()); node.setRenderable(renderable); node.setParent(anchorNode); arFragment.getArSceneView().getScene().addChild(anchorNode); node.select(); } } 

Sekarang jalankan aplikasi Anda. Anda akan melihat layar seperti yang ditunjukkan di bawah ini. Pindahkan ponsel sedikit di atas objek referensi. Dan begitu ARCore mendeteksi gambar referensi di dunia nyata, itu menambah model 3D Anda ke sana.


Hasil


Baca juga: Membuat aplikasi ARCore pertama Anda

Source: https://habr.com/ru/post/id439190/


All Articles