ARCore Artırılmış Resimler

1. Genel Bakış

ARCore, Android'de artırılmış gerçeklik uygulamaları oluşturmaya yönelik bir platformdur. Artırılmış görüntüler, gerçek dünyada önceden kaydedilmiş 2D görüntüleri tanıyabilen ve sanal içeriği bu görüntülerin üzerine yerleştirebilen AR uygulamaları oluşturmanıza olanak tanır.

Bu codelab, mevcut bir ARCore örnek uygulamasını, hareket eden veya yerinde sabit duran artırılmış görüntüleri içerecek şekilde değiştirme konusunda size yol gösterir.

Ne oluşturacaksınız?

Bu codelab'de, önceden oluşturulmuş bir ARCore örnek uygulamasını temel alarak çalışacaksınız. Codelab'in sonunda uygulamanız şunları yapabilecek:

  • Bir resim hedefini algılama ve hedefe sanal labirent ekleme
  • Hareket eden hedefi kamera görünümünde olduğu sürece takip etme

6bc6605df89de525.gif

İlk ARCore uygulamanızı mı oluşturuyorsunuz?

Evet Hayır

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

Örnek kod yazma Sadece bu sayfaları okuma

Neler öğreneceksiniz?

  • Java'da ARCore'da Artırılmış Görüntüler'i kullanma
  • Bir resmin ARCore tarafından tanınma özelliğini ölçme
  • Resme sanal içerik ekleme ve hareketini izleme

Ön koşullar

Bu codelab'i tamamlamak için belirli donanım ve yazılımlara ihtiyacınız vardı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 (3.1 veya sonraki sürümler) yüklü bir geliştirme makinesi
  • Geliştirme sırasında kitaplıkları indirmeniz gerektiğinden internet erişimi

Her şey hazır olduğuna göre başlayalım.

2. Geliştirme ortamını kurma

SDK'yı indir

GitHub'dan en son ARCore Android SDK'sını indirerek başlayacağız. Dosyayı tercih ettiğiniz konuma açın. Bu codelab için en eski SDK sürümü 1.18.1'dir. Klasör arcore-android-sdk-x.xx.x olarak adlandırılır. Tam değer, kullandığınız SDK'nın sürümü olur.

Android Studio'yu başlatın ve Open an existing Android Studio project (Mevcut bir Android Studio projesini aç) seçeneğini tıklayın.

5fbf2b21609187cc.png

Açılan bu klasöre gidin:

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

'ı tıklayın.

Android Studio'nun projeyi senkronize etmesini bekleyin. Android Studio'da gerekli bileşenler yoksa Install missing platform and sync project mesajıyla hata verebilir. Sorunu düzeltmek için talimatları uygulayın.

Örnek uygulamayı çalıştırma

Çalışan bir ARCore uygulama projeniz olduğuna göre şimdi bunu test edelim.

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

1aa2c6faa7ecdbd0.png

92e4c144a632b4ca.png

Bu örnek proje targetSdkVersion 28 kullanır. Failed to find Build Tools revision 28.0.3 gibi bir derleme hatası alırsanız gerekli Android Build Tools 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ış Görüntü'nün fotoğraf ve video çekmesine izin vermeniz istenir. İzin vermek için İZİN VER'e dokunun.

Örnek bir resimle test etme

Geliştirme ortamınızı ayarladığınıza göre artık uygulamaya bakması için bir resim vererek uygulamayı test edebilirsiniz.

Android Studio'ya geri dönün. Project (Proje) penceresinde app > assets'e gidin ve dosyayı açmak için default.jpg çift tıklayın.

9b333680e7b9f247.jpeg

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

Resmin üzerine aşağıdaki gibi bir resim çerçevesi yerleştirilir:

999e05ed35964f6e.png

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

3. 2D görüntüde labirent modeli gösterme

Artırılmış görüntülerin üzerine 3D model yerleştirerek bu özellikten yararlanmaya başlayabilirsiniz.

3D model indirme

Bu codelab'de Evol tarafından oluşturulan ve CC-BY 3.0 lisansı altında sunulan "Circle Maze - Green" adlı resmi kullanacağız. Bu 3D modelin bir kopyasını bu codelab'in GitHub deposunda sakladım. Bu kopyayı burada bulabilirsiniz.

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

  1. Bu codelab'in GitHub deposu olan third_party dizinine gidin.
  2. GreenMaze_obj.zip'i ve İndir düğmesini tıklayın.

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

  1. Android Studio'da app > assets > models altında green-maze dizini oluşturun.
  2. GreenMaze_obj.zip dosyası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 app > assets > models > green-maze'e (uygulama > öğeler > modeller > yeşil labirent) gidin.

Bu klasörde GreenMaze.obj ve GreenMaze.mtl olmak üzere iki dosya olmalıdır.

a1f33a2d2d407e03.png

Labirent modelini oluşturma

GreenMaze.obj 3D modeli mevcut 2D görüntünün üzerinde göstermek için aşağıdaki adımları uygulayın.

AugmentedImageRenderer.java içinde, labirent modelini oluşturmak için mazeRenderer adlı bir üye değişkeni ekleyin. Labirent resme ekleneceğ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 dosyasını yükleyin. İşinizi kolaylaştırmak için dokusuyla aynı çerçeve 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 işlem, labirenti algılanan resmin boyutuna göre ayarlar ve ekranda oluşturur.

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);
  }

Artık labirent, default.jpg Dünya resminin üzerinde gösterilir.

Not: Bu örnek 3D model üzerinde tam kontrolünüz olmadığı için yukarıdaki kodda birkaç "sihirli" sayı kullanılmıştır. Labirent modelinin boyutu 492,65 x 120 x 492,65 olup merkezi (251,3, 60, -129,0) konumundadır. Köşelerinin X, Y ve Z koordinat değerleri sırasıyla [5,02, 497,67], [0, 120] ve [-375,17, 117,25] aralığındadır. Bu nedenle, labirent modelinin ölçeği image_size / 492.65 olmalıdır. Labirentin 3D modeli başlangıç noktası (0, 0, 0) etrafında ortalanmadığı için mazeModelLocalOffset değeri kullanılıyor.

Labirenti oluşturan duvar, resmin üst kısmına sığmayacak kadar yüksek. Labirenti 0, 1 oranında ölçeklendirmek için X, Y ve Z'yi eşit olmayan şekilde ölçeklendirebilen bir yardımcı işlev updateModelMatrix() oluşturun. Mevcut updateModelMatrix(float[] modelMatrix, float scaleFactor) işlevini koruyup 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 tam olarak oturmalıdır.

772cbe2a8baef3ba.png

4. Andy'yi labirente ekle

Labirentiniz olduğuna göre şimdi labirentin içinde hareket edecek bir karakter ekleyin. ARCore Android SDK'sında bulunan andy.obj dosyasını kullanın. Resmin üzerinde oluşturulan yeşil labirentten farklı göründüğü için resim çerçevesinin dokusunu olduğu gibi bırakın.

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

AugmentedImageRenderer.java

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

Ardından, createOnGlThread()'ın sonunda andyRenderer'ı 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() fonksiyonunun sonunda Andy'nin labirenti tepeden gördüğü bir görüntü oluşturun.

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'nin labirentin üzerinde durduğunu görürsünüz.

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ınamayabilir.

arcoreimg, bir resmin ARCore tarafından ne kadar tanınacağını belirlemenize olanak tanıyan bir komut satırı aracıdır. 0 ile 100 arasında bir sayı verir. 100, tanınması en kolay olanıdır.

. Örneğin:

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

maze.jpg değeri 100 olduğundan ARCore tarafından kolayca tanınır.

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

Son olarak, andy'nin labirentte hareket etmesini sağlamak için kod ekleyebilirsiniz. Örneğin, fizik simülasyonunu işlemek için açık kaynaklı fizik motoru jBullet'ı kullanın. Bu bölümü atlamanızda hiçbir sakınca yoktur.

PhysicsController.java dosyasını indirip dizindeki projenize ekleyin.

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

Android Studio'da, çalışma zamanında yüklenebilmesi için Add GreenMaze.obj dosyasını project assets dizinine ekleyin. GreenMaze.obj dosyasını app > assets > models > green-maze konumundan app > assets konumuna kopyalayın.

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'

Andy'nin mevcut pozunun konumunu depolamak için bir değişken andyPose 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 öğesini 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 poz güncellemelerini almak için yeni bir hizmet işlevi olan updateAndyPose()'yı ekleyin.

AugmentedImageRenderer.java

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

AugmentedImageActivity.java içinde, fizik ile 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 aslında sert bir top kullanıyoruz ve topun pozunu kullanarak Andy'nin pozunu güncelliyoruz. Uygulama bir resmi her tanıdığında fiziği güncellemek için PhysicsController işlevini çağırın. Topu gerçek dünyadaymış gibi hareket ettirmek için labirentte topu hareket ettirirken gerçek dünyadaki yer çekimini uygulayın.

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. Andy, resmi eğdiğinizde artık gerçekçi bir şekilde hareket etmelidir.

Aşağıdaki örnekte resmi göstermek için başka bir telefon kullanılıyor. Tablet, basılı bir kitabın kapağı veya düz bir nesneye iliştirilmiş basılı bir kağıt gibi size uygun olan herhangi bir şeyi kullanabilirsiniz.

2f0df284705d3704.gif

İşte bu kadar. Andy'yi labirentten geçirmeye çalışırken iyi eğlenceler. İpucu: Hedef resmi ters çevirerek tuttuğunuzda çıkışı daha kolay bulabilirsiniz.

6. Tebrikler

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

  • ARCore AugmentedImage Java örneğini oluşturup çalıştırdıysanız.
  • Resimde uygun ölçekte bir labirent modeli göstermek için örneği güncelledi.
  • Resmin pozunu kullanarak eğlenceli bir şeyler yapın.

Kodun tamamını incelemek isterseniz buradan indirebilirsiniz.

Bu codelab'i yaparken eğlendiniz mi?

Evet Hayır

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

Evet Hayır

Bu codelab'de uygulamayı oluşturma işlemini tamamladınız mı?

Evet Hayır

Önümüzdeki 6 ay içinde ARCore uygulaması oluşturmayı planlıyor musunuz?

Evet Belki Hayır