ARCore Artırılmış Resimler

1. Genel Bakış

ARCore, Android'de artırılmış gerçeklik uygulamaları geliştirme amaçlı bir platformdur. Artırılmış Resimler, gerçek dünyadaki ön kayıtlı 2D görüntüleri tanıyabilen ve sanal içerikleri bu görüntülerin üzerine sabitleyebilen AR uygulamaları oluşturmanıza olanak tanır.

Bu codelab'de, taşınan veya sabitlenen artırılmış görüntüler eklemek için mevcut bir ARCore örnek uygulamasını değiştirme konusunda size yol gösterilir.

Neler oluşturacaksınız?

Bu codelab'de, mevcut bir ARCore örnek uygulamasını geliştireceksiniz. Codelab'in sonunda uygulamanız şunları yapabilecek:

  • Bir görüntü hedefi tespit edin ve hedefe sanal bir labirent ekleyin
  • Kamera görüş alanında olduğu sürece hareketli hedefi takip edin

6bc6605df89de525.gif

İlk kez bir ARCore uygulaması mı geliştiriyorsunuz?

Evet Hayır

Bu codelab'de örnek kod yazmayı mı yoksa sadece bu sayfaları mı okumak istiyorsunuz?

Örnek kod yazın Bu sayfaları okumanız yeterli

Neler öğreneceksiniz?

  • Java'da ARCore'da Artırılmış Resimler'i kullanma
  • Bir görüntünün ARCore tarafından tanınma yeteneği nasıl ölçülür?
  • Bir resme sanal içerik ekleme ve hareketini takip etme

Ön koşullar

Bu codelab'i tamamlamak için belirli donanım ve yazılımlara ihtiyacınız olacaktır.

Donanım gereksinimleri

Yazılım gereksinimleri

  • ARCore APK 1.9.0 veya sonraki sürümler. Bu APK normalde Play Store üzerinden cihaza otomatik olarak yüklenir
  • Android Studio (v3.1 veya sonraki sürümler) yüklü bir geliştirme makinesi
  • Geliştirme sırasında kitaplıkları indirmeniz gerekeceğinden internete erişim

Artık her şey hazır olduğuna göre, başlayalım.

2. Geliştirme ortamını ayarlama

SDK'yı indir

GitHub'dan en son ARCore Android SDK'sını indirerek başlayacağız. Sıkıştırılmış dosyayı açın ve tercih ettiğiniz konuma getirin. Bu codelab'de en eski SDK sürümü 1.18.1'dir. Klasör arcore-android-sdk-x.xx.x olarak adlandırılır. Buradaki tam değer, kullandığınız SDK'nın sürümü olur.

Android Studio'yu başlatın ve Mevcut bir Android Studio projesini aç'ı tıklayın.

5fbf2b21609187cc.png

Sıkıştırılmamış şu klasöre gidin:

arcore-android-sdk-x.xx.x/samples/augmented_image_java

'ı tıklayın.

Android Studio'nun proje senkronizasyonunu tamamlamasını bekleyin. Android Studio'nuz gerekli bileşenlere sahip değilse Install missing platform and sync project mesajıyla işlem başarısız olabilir. Sorunu gidermek için talimatları uygulayın.

Örnek uygulamayı çalıştırma

Artık çalışan bir ARCore uygulama projeniz olduğuna göre projeyi test edelim.

ARCore cihazınızı geliştirme makinesine bağlayın ve Çalıştır > > Çalıştır menüsünü kullanın. Cihazda hata ayıklama sürümünü çalıştırmak için "app" komutunu çalıştırın. Hangi cihazdan çalıştırılacağını seçmenizi isteyen iletişim kutusunda, bağlı cihazı seçin ve Tamam'ı tıklayın.

1aa2c6faa7ecdbd0.png

92e4c144a632b4ca.png

Bu örnek projede targetSdkVersion 28 kullanılmıştır. Failed to find Build Tools revision 28.0.3 gibi bir derleme hatasıyla karşılaşırsanız gerekli Android Derleme Araçları sürümünü indirip yüklemek için Android Studio'da açıklanan talimatları uygulayın.

Her şey başarılı olursa örnek uygulama cihazda başlatılır ve Artırılmış Resim'in resim ve video çekmesine izin vermek için sizden izin ister. İzin vermek için İZİN VER'e dokunun.

Örnek resimle test etme

Artık geliştirme ortamınızı oluşturduğunuza göre, bakılacak bir resim vererek uygulamayı test edebilirsiniz.

Android Studio'ya dönün ve Proje penceresinde uygulama > öğeleri ekleyin ve default.jpg dosyasını çift tıklayarak açın.

9b333680e7b9f247.jpeg

Cihazınızın kamerasını ekrandaki Dünya görüntüsüne doğru tutun ve taradığınız görüntüyü artı işaretine sığdırmak için talimatları uygulayın.

Resmin üzerinde, aşağıdaki gibi bir resim çerçevesi yer alır:

999e05ed35964f6e.png

Ardından, örnek uygulamada küçük iyileştirmeler yapacağız.

3. 2D Resimde labirent modelini göster

Üzerinde bir 3D model görüntüleyerek, Artırılmış Resimlerle oynamaya başlayabilirsiniz.

3D model indir

Bu codelab için "Circle Labirent - Yeşil" yöntemini kullanacağız. Evol tarafından sağlanmıştır ve CC-BY 3.0 kapsamında lisanslanmıştır. Bu 3D modelin bir kopyasını, bu codelab'in gitHub deposunda depoladım. Söz konusu depoya buradan ulaşabilirsiniz.

Modeli indirmek ve Android Studio'ya eklemek için aşağıdaki adımları uygulayın.

  1. Bu codelab'in GitHub deposuna, üçüncü taraf dizinine gidin.
  2. GreenMaze_obj.zip dosyasını ve ardından İndir düğmesini tıklayın.

Bu işlem, GreenMaze_obj.zip adlı bir dosya indirir.

  1. Android Studio'da, app > altında green-maze dizini oluşturun. öğeler > modeller
  2. GreenMaze_obj.zip adlı dosyanın sıkıştırmasını açın ve içeriği şu konuma kopyalayın: arcore-android-sdk-x.xx.x/samples/augmented_image_java/app/src/main/assets/models/green-maze
  3. Android Studio'da uygulama > öğeler > modeller > yeşil-labirent.

Bu klasörde iki dosya olmalıdır: GreenMaze.obj ve GreenMaze.mtl.

a1f33a2d2d407e03.png

Labirent modelini oluştur

GreenMaze.obj 3D modelini mevcut 2D görüntünün üzerinde görüntülemek için bu adımları uygulayın.

AugmentedImageRenderer.java içinde, labirent modelini oluşturmak için mazeRenderer adlı bir üye değişkeni ekleyin. Labirentin resme eklenmesi gerektiğinden, mazeRenderer öğesini AugmentedImageRenderer sınıfının içine yerleştirmek mantıklıdır.

AugmentedImageRenderer.java

  // Add a member variable to hold the maze model.
  private final ObjectRenderer mazeRenderer = new ObjectRenderer();

createOnGlThread() işlevinde GreenMaze.obj öğesini yükleyin. Kolaylık sağlaması için dokusuyla aynı kare dokusunu kullanın.

AugmentedImageRenderer.java

  // Replace the definition of the createOnGlThread() function with the
  // following code, which loads GreenMaze.obj.
  public void createOnGlThread(Context context) throws IOException {

    mazeRenderer.createOnGlThread(
        context, "models/green-maze/GreenMaze.obj", "models/frame_base.png");
    mazeRenderer.setMaterialProperties(0.0f, 3.5f, 1.0f, 6.0f);

  }

draw() işlevinin tanımını aşağıdakiyle değiştirin. Bu, labirentin boyutunu algılanan resmin boyutuna göre ayarlar ve labirenti ekranda gösterir.

AugmentedImageRenderer.java

  // Adjust size of detected image and render it on-screen
  public void draw(
      float[] viewMatrix,
      float[] projectionMatrix,
      AugmentedImage augmentedImage,
      Anchor centerAnchor,
      float[] colorCorrectionRgba) {
    float[] tintColor =
        convertHexToColor(TINT_COLORS_HEX[augmentedImage.getIndex() % TINT_COLORS_HEX.length]);

    final float mazeEdgeSize = 492.65f; // Magic number of maze size
    final float maxImageEdgeSize = Math.max(augmentedImage.getExtentX(), augmentedImage.getExtentZ()); // Get largest detected image edge size

    Pose anchorPose = centerAnchor.getPose();

    float mazeScaleFactor = maxImageEdgeSize / mazeEdgeSize; // scale to set Maze to image size
    float[] modelMatrix = new float[16];

    // OpenGL Matrix operation is in the order: Scale, rotation and Translation
    // So the manual adjustment is after scale
    // The 251.3f and 129.0f is magic number from the maze obj file
    // You mustWe need to do this adjustment because the maze obj file
    // is not centered around origin. Normally when you
    // work with your own model, you don't have this problem.
    Pose mazeModelLocalOffset = Pose.makeTranslation(
                                -251.3f * mazeScaleFactor,
                                0.0f,
                                129.0f * mazeScaleFactor);
    anchorPose.compose(mazeModelLocalOffset).toMatrix(modelMatrix, 0);
    mazeRenderer.updateModelMatrix(modelMatrix, mazeScaleFactor, mazeScaleFactor/10.0f, mazeScaleFactor); // This line relies on a change in ObjectRenderer.updateModelMatrix later in this codelab.
    mazeRenderer.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, tintColor);
  }

Şimdi, labirent Dünya'nın default.jpg resminin üzerinde görüntülenmelidir.

Not: Bu örnek 3D model üzerinde tam denetime sahip olmadığınız için yukarıdaki kodda birkaç "sihir" numaraları'na dokunun. Labirent modelinin boyutu 492,65 x 120 x 492,65'tir ve ortadaki değer (251,3, 60, -129,0) şeklindedir. Köşelerinin aralığı X, Y ve Z koordinatları değerleri sırasıyla [5,02, 497,67], [0, 120] ve [-375,17, 117,25] şeklindedir. Dolayısıyla, labirent modelinin ölçeğinin image_size / 492.65 olması gerekir. Labirentin 3D modeli başlangıç noktası (0, 0, 0) etrafında ortalanmadığı için mazeModelLocalOffset başlatılır.

Labirentin duvarı resmin üzerine sığmayacak kadar yüksek. Labirentin yüksekliğini 0,1 ölçeklemek için X, Y, Z'yi eşit olmayan şekilde ölçeklendirebilen updateModelMatrix() yardımcı işlevi oluşturun. Mevcut updateModelMatrix(float[] modelMatrix, float scaleFactor) öğesini korumanız ve aşırı yük updateModelMatrix(float[] modelMatrix, float scaleFactorX, float scaleFactorY, float scaleFactorZ) işlevini yeni bir işlev olarak eklemeniz gerektiğini unutmayın.

common/rendering/ObjectRenderer.java

// Scale X, Y, Z coordinates unevenly
public void updateModelMatrix(float[] modelMatrix, float scaleFactorX, float scaleFactorY, float scaleFactorZ) {
    float[] scaleMatrix = new float[16];
    Matrix.setIdentityM(scaleMatrix, 0);
    scaleMatrix[0] = scaleFactorX;
    scaleMatrix[5] = scaleFactorY;
    scaleMatrix[10] = scaleFactorZ;
    Matrix.multiplyMM(this.modelMatrix, 0, modelMatrix, 0, scaleMatrix, 0);
}

Kodu çalıştırın. Labirent artık resmin üzerine mükemmel bir şekilde sığmalıdır.

772cbe2a8baef3ba.png

4. Andy'yi labirente ekleyin

Artık bir labirentiniz olduğuna göre labirentin içinde dolaşmak için bir karakter ekleyin. ARCore Android SDK'sında bulunan andy.obj dosyasını kullanın. Resmin üstünde oluşturulan yeşil labirentten farklı göründüğü için resim çerçevesi dokusunu doku olarak koruyun.

Andy'yi oluşturmak için AugmentedImageRenderer.java içinde gizli bir ObjectRenderer ekleyin.

AugmentedImageRenderer.java

// Render for Andy
  private final ObjectRenderer andyRenderer = new ObjectRenderer();

Sonra, createOnGlThread() sonunda andyRenderer uygulamasını başlatın.

AugmentedImageRenderer.java

public void createOnGlThread(Context context) throws IOException {

    // Initialize andyRenderer
    andyRenderer.createOnGlThread(
        context, "models/andy.obj", "models/andy.png");
    andyRenderer.setMaterialProperties(0.0f, 3.5f, 1.0f, 6.0f);
  }

Son olarak, draw() işlevinin sonunda Andy'yi labirentin tepesinde görün.

AugmentedImageRenderer.java

public void draw(
      float[] viewMatrix,
      float[] projectionMatrix,
      AugmentedImage augmentedImage,
      Anchor centerAnchor,
      float[] colorCorrectionRgba) {


    // Render Andy, standing on top of the maze
    Pose andyModelLocalOffset = Pose.makeTranslation(
        0.0f,
        0.1f,
        0.0f);
    anchorPose.compose(andyModelLocalOffset).toMatrix(modelMatrix, 0);
    andyRenderer.updateModelMatrix(modelMatrix, 0.05f); // 0.05f is a Magic number to scale
    andyRenderer.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, tintColor);

  }

Kodunuzu çalıştırın. Andy'yi labirentin tepesinde durduğunu göreceksiniz.

cb1e74569d7ace69.png

Hedef resim kalitesini belirleme

ARCore, resimleri tanımak için görsel özelliklerden yararlanır. Kalite farklılıkları nedeniyle tüm resimler kolayca tanınmayabilir.

arcoreimg, bir resmin ARCore'un ne kadar tanınabileceğini belirlemenize olanak tanıyan bir komut satırı aracıdır. 0 ile 100 arasında bir sayı verir. 100, tanınması en kolay değerdir.

, Bir örnek verelim:

arcore-android-sdk-x.xx.x/tools/arcoreimg/macos$
$ ./arcoreimg  eval-img --input_image_path=/Users/username/maze.jpg
100

maze.jpg, 100 değerine sahip olduğu için ARCore tarafından kolayca tanınır.

5. İsteğe bağlı: Andy'nin labirentte hareket etmesini sağlayın

Son olarak, labirentte andy'nin hareket etmesini sağlayacak birkaç kod ekleyebilirsiniz. Örneğin, fizik simülasyonu yapmak için açık kaynaklı Fizik motoru jBullet'ı kullanın. Bu bölümü atlayabilirsiniz.

PhysicsController.java dosyasını indirin ve dizindeki projenize ekleyin

arcore-android-sdk-x.xx.x/samples/augmented_image_java/app/src/main/java/com/google/ar/core/examples/java/augmentedimage/

Çalışma zamanında yüklenebilmesi için Android Studio'da GreenMaze.obj dosyasını proje öğeleri dizinine ekleyin. GreenMaze.obj öğesini uygulamadan kopyala > öğeler > modeller > yeşil-labirent'i uygulamaya > öğeler.

Uygulamanın build.gradle dosyasına aşağıdaki bağımlılıkları ekleyin.

app/build.gradle

    // jbullet library
    implementation 'cz.advel.jbullet:jbullet:20101010-1'

Anıl'ın mevcut pozunun konumunu depolamak için bir andyPose değişkeni tanımlayın.

AugmentedImageRenderer.java

  // Create a new pose for the Andy
  private Pose andyPose = Pose.IDENTITY;

Andy'yi yeni andyPose değişkenini kullanarak oluşturmak için AugmentedImageRenderer.java dosyasını değiştirin.

AugmentedImageRenderer.java

public void draw(
      float[] viewMatrix,
      float[] projectionMatrix,
      AugmentedImage augmentedImage,
      Anchor centerAnchor,
      float[] colorCorrectionRgba) {

    // Use these code to replace previous code for rendering the Andy object
    // 
    // Adjust the Andy's rendering position
    // The Andy's pose is at the maze's vertex's coordinate
    Pose andyPoseInImageSpace = Pose.makeTranslation(
        andyPose.tx() * mazeScaleFactor,
        andyPose.ty() * mazeScaleFactor,
        andyPose.tz() * mazeScaleFactor);

    anchorPose.compose(andyPoseInImageSpace).toMatrix(modelMatrix, 0);
    andyRenderer.updateModelMatrix(modelMatrix, 0.05f);
    andyRenderer.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, tintColor);
  }

Andy pozu güncellemelerini almak için yeni bir yardımcı program işlevi (updateAndyPose()) ekleyin.

AugmentedImageRenderer.java

  // Receive Andy pose updates
  public void updateAndyPose(Pose pose) {
    andyPose = pose;
  }

AugmentedImageActivity.java içinde, fizikle ilgili tüm işlevleri yönetmek için JBullet fizik motorunu kullanan bir PhysicsController nesnesi oluşturun.

AugmentedImageActivity.java

import com.google.ar.core.Pose;

  // Declare the PhysicsController object
  private PhysicsController physicsController;

Fizik motorunda, Andy'yi temsil etmek için sabit bir top kullanıyoruz ve topun duruşunu kullanarak Andy'nin duruşunu güncelliyoruz. Uygulama bir görüntü algıladığında fizik kurallarını güncellemek için PhysicsController numaralı telefonu arayın. Topu gerçek dünyadaymış gibi hareket ettirmek için gerçek dünyadan yer çekimini kullanarak topu labirentte hareket ettirin.

AugmentedImageActivity.java

// Update the case clause for TRACKING to call PhysicsController
// whenever the app recognizes an image
  private void drawAugmentedImages(

    ...

        case TRACKING:
          // Switch to UI Thread to update View
          this.runOnUiThread(
              new Runnable() {
                @Override
                public void run() {
                  fitToScanView.setVisibility(View.GONE);
                }
              });

          // Create a new anchor for newly found images
          if (!augmentedImageMap.containsKey(augmentedImage.getIndex())) {
            Anchor centerPoseAnchor = augmentedImage.createAnchor(augmentedImage.getCenterPose());
            augmentedImageMap.put(
                augmentedImage.getIndex(), Pair.create(augmentedImage, centerPoseAnchor));

            physicsController = new PhysicsController(this);
          } else {
            Pose ballPose = physicsController.getBallPose();
            augmentedImageRenderer.updateAndyPose(ballPose);


            // Use real world gravity, (0, -10, 0), as gravity
            // Convert to Physics world coordinate(maze mesh has to be static)
            // Use the converted coordinate as a force to move the ball
            Pose worldGravityPose = Pose.makeTranslation(0, -10f, 0);
            Pose mazeGravityPose = augmentedImage.getCenterPose().inverse().compose(worldGravityPose);
            float mazeGravity[] = mazeGravityPose.getTranslation();
            physicsController.applyGravityToBall(mazeGravity);

            physicsController.updatePhysics();
          }
          break;

Uygulamayı çalıştırın. Artık resmi yatırdığınızda Andy gerçekçi bir şekilde hareket etmelidir.

Aşağıdaki örnekte, resmi görüntülemek için başka bir telefon kullanılmaktadır; tablet, basılı bir kitabın kapağı veya düz bir nesneye yerleştirilmiş basılı bir kağıt gibi size uygun herhangi bir şeyi kullanabilirsiniz.

2f0df284705d3704.gif

İşte bu kadar. Andy'yi labirentten başarıyla atlatmaya çalışırken keyfini çıkarın. İpucu: Hedef resmi baş aşağı tuttuğunuzda çıkışı bulmak daha kolay olur.

6. Tebrikler

Tebrikler! Bu codelab'in sonuna geldiniz. Böylece:

  • ARCore AugmentedImage Java örneği oluşturup çalıştırdı.
  • Örnek, labirent modelini resim üzerinde uygun ölçekte görüntüleyecek şekilde güncellendi.
  • Resmin pozunu eğlenceli bir şey yapmak için kullandı.

Kodun tamamına bakmak isterseniz buradan indirebilirsiniz.

Bu codelab'i yaparken eğlendiniz mi?

Evet Hayır

Bu codelab'i yaparken faydalı bir şeyler öğrendiniz mi?

Evet Hayır

Uygulamayı oluşturma işlemini bu codelab'de tamamladınız mı?

Evet Hayır

Önümüzdeki 6 ay içinde bir ARCore uygulaması geliştirmeyi planlıyor musunuz?

Evet Belki Hayır