ARCore ऑगमेंटेड इमेज

1. खास जानकारी

ARCore, Android पर ऑगमेंटेड रिएलिटी (एआर) ऐप्लिकेशन बनाने का प्लैटफ़ॉर्म है. ऑगमेंटेड इमेज की मदद से, ऐसे एआर ऐप्लिकेशन बनाए जा सकते हैं जो असल दुनिया में पहले से रजिस्टर की गई 2D इमेज की पहचान कर सकते हैं और उनके ऊपर वर्चुअल कॉन्टेंट को ऐंकर कर सकते हैं.

यह कोडलैब आपको मौजूदा ARCore सैंपल ऐप्लिकेशन में बदलाव करने का तरीका बताता है, ताकि आप ऐसी ऑगमेंटेड इमेज को शामिल कर सकें जो एक जगह से दूसरी जगह ले जा रही हैं या सही जगह पर मौजूद हैं.

आपको क्या बनाना होगा

इस कोडलैब में, पहले से मौजूद ARCore सैंपल ऐप्लिकेशन को बनाया जा रहा है. कोडलैब के खत्म होने तक, आपका ऐप्लिकेशन ये काम कर पाएगा:

  • इमेज के टारगेट का पता लगाएं और टारगेट पर वर्चुअल भूलभुलैया को अटैच करें
  • ऑब्जेक्ट के कैमरे के व्यू में होने पर, मूविंग टारगेट को ट्रैक करते रहें

6bc6605df89de525.gif

क्या आप पहली बार ARCore ऐप्लिकेशन बना रहे हैं?

हां नहीं

क्या आपको इस कोडलैब में सैंपल कोड लिखना है या सिर्फ़ इन पेजों को पढ़ना है?

सैंपल कोड लिखें बस ये पेज पढ़ें

आप इन चीज़ों के बारे में जानेंगे

  • Java में ARCore में ऑगमेंटेड इमेज को इस्तेमाल करने का तरीका
  • ARCore से किसी इमेज की पहचान करने की क्षमता का पता लगाने का तरीका
  • किसी इमेज पर वर्चुअल कॉन्टेंट अटैच करने और उसकी मूवमेंट को ट्रैक करने का तरीका

ज़रूरी शर्तें

इस कोडलैब को पूरा करने के लिए, आपको खास हार्डवेयर और सॉफ़्टवेयर की ज़रूरत होगी.

हार्डवेयर की आवश्यकताएं

ज़रूरी सॉफ़्टवेयर

  • ARCore APK 1.9.0 या इसके बाद का वर्शन. आम तौर पर, यह APK आपके डिवाइस पर Play Store से अपने-आप इंस्टॉल हो जाता है
  • Android Studio वाली डेवलपमेंट मशीन (v3.1 या इसके बाद के वर्शन)
  • इंटरनेट ऐक्सेस करें, क्योंकि डेवलपमेंट के दौरान आपको लाइब्रेरी डाउनलोड करनी होंगी

अब जब आपने सब कुछ तैयार कर लिया है, तो चलिए शुरू करते हैं!

2. डेवलपमेंट एनवायरमेंट सेट अप करना

SDK टूल डाउनलोड करें

सबसे पहले, हम GitHub से नया ARCore Android SDK डाउनलोड करेंगे. अपनी पसंदीदा जगह पर इसे अनज़िप करें. इस कोडलैब के लिए, SDK टूल का सबसे पुराना वर्शन 1.18.1 है. इस फ़ोल्डर को arcore-android-sdk-x.xx.x के तौर पर दिखाया जाएगा. इसकी सटीक वैल्यू, आपके इस्तेमाल किए जा रहे SDK टूल का वर्शन होगी.

Android Studio लॉन्च करें और मौजूदा Android Studio प्रोजेक्ट खोलें पर क्लिक करें.

5fbf2b21609187cc.png

इस अनज़िप किए गए फ़ोल्डर पर जाएं:

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

खोलें पर क्लिक करें.

प्रोजेक्ट को सिंक करने के लिए, Android Studio का इंतज़ार करें. अगर आपके Android Studio में ज़रूरी कॉम्पोनेंट मौजूद नहीं हैं, तो हो सकता है कि यह Install missing platform and sync project मैसेज के साथ काम न करे. समस्या को ठीक करने के लिए निर्देशों का पालन करें.

सैंपल ऐप्लिकेशन चलाएं

अब आपके पास एक चालू ARCore ऐप्लिकेशन प्रोजेक्ट है, तो आइए इसे टेस्ट करके देखें.

अपने ARCore डिवाइस को डेवलपमेंट मशीन से कनेक्ट करें और मेन्यू Run > डिवाइस पर डीबग वर्शन चलाने के लिए, ‘ऐप्लिकेशन' चलाएं. जिस डिवाइस से आपको चलाना है उसे चुनने के लिए कहने वाले डायलॉग बॉक्स में, कनेक्ट किया गया डिवाइस चुनें और ठीक है पर क्लिक करें.

1aa2c6faa7ecdbd0.png

92e4c144a632b4ca.png

यह सैंपल प्रोजेक्ट, targetSdkVersion 28 का इस्तेमाल करता है. अगर आपके डिवाइस में Failed to find Build Tools revision 28.0.3 जैसी कोई बिल्ड की गड़बड़ी है, तो Android Studio में बताए गए निर्देशों का पालन करके, Android बिल्ड टूल का ज़रूरी वर्शन डाउनलोड और इंस्टॉल करें.

अगर जांच पूरी हो जाती है, तो डिवाइस पर सैंपल ऐप्लिकेशन लॉन्च होगा. इसके बाद, आपको ऑगमेंटेड इमेज को फ़ोटो और वीडियो लेने की अनुमति देने का प्रॉम्प्ट मिलेगा. अनुमति देने के लिए, अनुमति दें पर टैप करें.

सैंपल इमेज की मदद से जांच करना

अब आपने अपना डेवलपमेंट एनवायरमेंट सेट अप कर लिया है, तो ऐप्लिकेशन को देखने के लिए उसकी इमेज देकर उसकी जांच की जा सकती है.

Android Studio में प्रोजेक्ट विंडो में जाकर, ऐप्लिकेशन > ऐसेट पर क्लिक करें और default.jpg फ़ाइल को खोलने के लिए, उस पर दो बार क्लिक करें.

9b333680e7b9f247.jpeg

अपने डिवाइस के कैमरे को स्क्रीन पर मौजूद अर्थ की इमेज के सामने लाएं और स्कैन की जा रही इमेज को क्रॉसहेयर में फ़िट करने के लिए निर्देशों का पालन करें.

एक इमेज फ़्रेम, इमेज के ऊपर इस तरह से ओवरले करेगा:

999e05ed35964f6e.png

इसके बाद, हम सैंपल ऐप्लिकेशन में कुछ सुधार करेंगे.

3. 2D इमेज पर भूलभुलैया मॉडल दिखाएं

ऑगमेंटेड इमेज की मदद से गेम खेलना शुरू किया जा सकता है. इसके लिए, आपको ऑगमेंटेड इमेज के ऊपर एक 3D मॉडल दिखाना होगा.

3D मॉडल डाउनलोड करें

इस कोडलैब के लिए, हम "Circle Maze - Green" इस्तेमाल करने जा रहे हैं और साथ ही, CC-BY 3.0 के तहत लाइसेंस मिला है. मैंने इस कोडलैब के GitHub रिपॉज़िटरी में इस 3D मॉडल की एक कॉपी सेव की है. आपको यहां पर जाकर यह जानकारी मिल सकती है.

मॉडल डाउनलोड करने और उसे Android Studio में शामिल करने के लिए, यह तरीका अपनाएं.

  1. इस कोडलैब (कोड बनाना सीखना) की GitHub रिपॉज़िटरी (तीसरे पक्ष की डायरेक्ट्री) पर जाएं.
  2. GreenMaze_obj.zip पर क्लिक करें और GreenMaze_obj.zip बटन पर क्लिक करें.

इससे GreenMaze_obj.zip नाम की फ़ाइल डाउनलोड हो जाती है.

  1. Android Studio में, ऐप्लिकेशन > में जाकर green-maze डायरेक्ट्री बनाएं ऐसेट > मॉडल
  2. GreenMaze_obj.zip को अनज़िप करें और कॉन्टेंट को इस जगह पर कॉपी करें: arcore-android-sdk-x.xx.x/samples/augmented_image_java/app/src/main/assets/models/green-maze
  3. Android Studio में, ऐप्लिकेशन > ऐसेट > मॉडल > हरी-भुलैया.

इस फ़ोल्डर में दो फ़ाइलें होनी चाहिए: GreenMaze.obj और GreenMaze.mtl.

a1f33a2d2d407e03.png

भूलभुलैया मॉडल को रेंडर करें

GreenMaze.obj 3D मॉडल को मौजूदा 2D इमेज के ऊपर दिखाने के लिए, यह तरीका अपनाएं.

AugmentedImageRenderer.java में, भूलभुलैया मॉडल को रेंडर करने के लिए mazeRenderer नाम का सदस्य वैरिएबल जोड़ें. भूलभुलैया को इमेज से जोड़ना चाहिए, इसलिए mazeRenderer को AugmentedImageRenderer क्लास के अंदर रखना सही रहता है.

AugmentedImageRenderer.java

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

createOnGlThread() फ़ंक्शन में, GreenMaze.obj को लोड करें. सरलता के लिए, उसी फ़्रेम टेक्स्चर का इस्तेमाल करें जो इसकी बनावट है.

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() फ़ंक्शन की परिभाषा को नीचे दी गई परिभाषा से बदलें. यह भूलभुलैया के आकार को पता लगाई गई चित्र के आकार के अनुसार समायोजित करता है और उसे स्क्रीन पर रेंडर करता है.

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

अब यह भूल-भुलैया, पृथ्वी की default.jpg तस्वीर के ऊपर दिखनी चाहिए.

ध्यान दें: क्योंकि आपके पास इस सैंपल 3D मॉडल पर पूरा कंट्रोल नहीं है, इसलिए ऊपर दिया गया कोड कुछ "मैजिक" का इस्तेमाल करता है नंबर. भूलभुलैया मॉडल का आयाम 492.65 x 120 x 492.65 है, जिसके केंद्र का मान (251.3, 60, -129.0) है. इसके शीर्षों की सीमा X, Y, और Z कोऑर्डिनेट की वैल्यू [5.02, 497.67], [0, 120], और [-375.17, 117.25] हैं. इसलिए, भूलभुलैया मॉडल का स्केल image_size / 492.65 होना चाहिए. mazeModelLocalOffset को इसलिए पेश किया गया है, क्योंकि भूल-भुलैया का 3D मॉडल, मूल (0, 0, 0) के केंद्र में नहीं है.

भूलभुलैया की दीवार अभी भी चित्र में ऊपर फ़िट होने के लिए बहुत ऊंची है. ऐसा हेल्पर फ़ंक्शन updateModelMatrix() बनाएं जो X, Y, Z को असमान रूप से स्केल करके, मेज़ की ऊंचाई को 0.1 से स्केल कर सके. ध्यान दें, आपको मौजूदा updateModelMatrix(float[] modelMatrix, float scaleFactor) को बनाए रखना होगा और फ़ंक्शन ओवरलोड updateModelMatrix(float[] modelMatrix, float scaleFactorX, float scaleFactorY, float scaleFactorZ) को नए फ़ंक्शन के तौर पर जोड़ना होगा.

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

कोड चलाएं. भूलभुलैया को अब चित्र के ऊपर ठीक से फ़िट होना चाहिए.

772cbe2a8baef3ba.png

4. भूल-भुलैया में एंडी को जोड़ें

अब आपके पास एक भूल-भुलैया है, तो उसमें चारों ओर घूमने के लिए एक वर्ण जोड़ें. ARCore Android SDK में शामिल andy.obj फ़ाइल का इस्तेमाल करें. चित्र फ़्रेम की बनावट को उसकी बनावट के रूप में रखें, क्योंकि यह चित्र के शीर्ष पर रेंडर की गई हरी भूलभुलैया से अलग दिखती है.

AugmentedImageRenderer.java में, एंडी को रेंडर करने के लिए निजी ObjectRenderer जोड़ें.

AugmentedImageRenderer.java

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

इसके बाद, createOnGlThread() के आखिर में andyRenderer शुरू करें.

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

आखिर में, draw() फ़ंक्शन के आखिर में, एंडी को भूल-भुलैया पर खड़े होकर रेंडर करें.

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

  }

अपना कोड चलाएं. आपको देखना होगा कि एंडी भूलभुलैया पर सबसे ऊपर खड़ा है.

cb1e74569d7ace69.png

टारगेट इमेज क्वालिटी तय करें

इमेज की पहचान करने के लिए ARCore विज़ुअल सुविधाओं का इस्तेमाल करता है. क्वालिटी में अंतर होने की वजह से, सभी इमेज की आसानी से पहचान नहीं की जा सकती.

arcoreimg एक कमांड-लाइन टूल है, जिससे यह पता लगाया जा सकता है कि ARCore की मदद से, कोई इमेज कितनी आसानी से पहचानी जा सकेगी. यह 0 से 100 के बीच की कोई संख्या होती है और 100 की पहचान करना सबसे आसान होता है.

को अपनाएं. यहां एक उदाहरण दिया गया है:

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

maze.jpg की वैल्यू 100 है, इसलिए ARCore से इसे आसानी से पहचाना जा सकता है.

5. ज़रूरी नहीं: ऐंडी को भूल-भुलैया में घुमाएं

आखिर में, एंडी को भूल-भुलैया में ले जाने के लिए, उसमें कुछ कोड जोड़े जा सकते हैं. उदाहरण के लिए, फ़िज़िक्स सिम्युलेशन को हैंडल करने के लिए, ओपन सोर्स फ़िज़िक्स इंजन jBullet का इस्तेमाल करें. अगर आप इस हिस्से को छोड़ दें, तो कोई बात नहीं.

PhysicsController.java को डाउनलोड करें और इसे डायरेक्ट्री में अपने प्रोजेक्ट में जोड़ें

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

Android Studio में, प्रोजेक्ट ऐसेट डायरेक्ट्री में GreenMaze.obj जोड़ें, ताकि इसे रनटाइम के दौरान लोड किया जा सके. GreenMaze.obj को ऐप्लिकेशन से कॉपी करें > ऐसेट > मॉडल > green-maze से app के लिए > ऐसेट.

ऐप्लिकेशन की build.gradle फ़ाइल में, ये डिपेंडेंसी जोड़ें.

app/build.gradle

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

एंडी के मौजूदा पोज़ की जगह को सेव करने के लिए, वैरिएबल andyPose तय करें.

AugmentedImageRenderer.java

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

नए andyPose वैरिएबल का इस्तेमाल करके एंडी को रेंडर करने के लिए, AugmentedImageRenderer.java में बदलाव करें.

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

एंडी पोज़ से जुड़े अपडेट पाने के लिए, एक नया यूटिलिटी फ़ंक्शन updateAndyPose() जोड़ें.

AugmentedImageRenderer.java

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

AugmentedImageActivity.java में, एक ऐसा PhysicsController ऑब्जेक्ट बनाएं जो भौतिकी से जुड़े सभी फ़ंक्शन को मैनेज करने के लिए, JBullet भौतिक इंजन का इस्तेमाल करता हो.

AugmentedImageActivity.java

import com.google.ar.core.Pose;

  // Declare the PhysicsController object
  private PhysicsController physicsController;

फ़िज़िक्स इंजन में, हम एंडी को दिखाने के लिए एक ठोस बॉल का इस्तेमाल करते हैं और बॉल के पोज़ का इस्तेमाल करके एंडी के पोज़ को अपडेट करते हैं. PhysicsController को कॉल करें, ताकि ऐप्लिकेशन जब भी किसी इमेज की पहचान करे, तब फ़िज़िक्स को अपडेट करने में मदद मिले. बॉल को असली दुनिया की तरह मूव करने के लिए, रीयल-वर्ल्ड के गुरुत्वाकर्षण का इस्तेमाल करके उसे भूल-भुलैया में ले जाएं.

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;

ऐप्लिकेशन चलाएं. इमेज को झुकाने पर, एंडी को अब असल में आस-पास घूमना चाहिए.

नीचे दिए गए उदाहरण में, इमेज दिखाने के लिए किसी दूसरे फ़ोन का इस्तेमाल किया गया है. अपनी सुविधा के हिसाब से किसी भी चीज़ का इस्तेमाल किया जा सकता है. जैसे, टैबलेट, हार्डकॉपी बुक का कवर या किसी सपाट चीज़ पर अटैच किया गया पेपर.

2f0df284705d3704.gif

हो गया! भूलभुलैया में एंडी को बाहर निकालने की कोशिश करें. संकेत: टारगेट इमेज को ऊपर की ओर रखने पर, बाहर निकलने का रास्ता ढूंढना आसान होता है.

6. बधाई हो

बधाई हो, आप इस कोडलैब के आखिर तक पहुंच गए हैं और आपने:

  • ARCore AugmentedImage Java सैंपल बनाया गया और चलाया गया.
  • सही स्केल पर, इमेज पर भूलभुलैया मॉडल दिखाने के लिए, सैंपल को अपडेट किया गया.
  • कुछ मज़ेदार करने के लिए, इमेज की फ़ोटो का इस्तेमाल किया.

अगर आपको पूरा कोड देखना है, तो उसे यहां से डाउनलोड करें.

क्या आपको यह कोडलैब (कोड बनाना सीखना) करने में आनंद आया?

हां नहीं

क्या आपको कोडलैब का यह मॉड्यूल करने में कुछ मदद मिली?

हां नहीं

क्या आपने इस कोडलैब में ऐप्लिकेशन बनाना पूरा कर लिया है?

हां नहीं

क्या आपको अगले छह महीने में ARCore ऐप्लिकेशन बनाना है?

हां शायद नहीं