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

क्या आपने पहली बार ARCore ऐप्लिकेशन बनाया है?
क्या आपको इस कोडलैब में सैंपल कोड लिखना है या सिर्फ़ इन पेजों को पढ़ना है?
आपको क्या सीखने को मिलेगा
- Java में ARCore की ऑगमेंटेड इमेज सुविधा का इस्तेमाल करने का तरीका
- यह पता लगाने का तरीका कि ARCore किसी इमेज की पहचान कर सकता है या नहीं
- किसी इमेज में वर्चुअल कॉन्टेंट जोड़ने और उसकी मूवमेंट को ट्रैक करने का तरीका
ज़रूरी शर्तें
इस कोडलैब को पूरा करने के लिए, आपको कुछ खास हार्डवेयर और सॉफ़्टवेयर की ज़रूरत होगी.
हार्डवेयर की ज़रूरी शर्तें
- यूएसबी केबल के ज़रिए, ARCore के साथ काम करने वाला डिवाइस, डेवलपमेंट मशीन से कनेक्ट किया गया हो
ज़रूरी सॉफ़्टवेयर
- ARCore APK 1.9.0 या इसके बाद का वर्शन. यह APK आम तौर पर, Play Store के ज़रिए डिवाइस पर अपने-आप इंस्टॉल हो जाता है
- डेवलपमेंट मशीन में Android Studio (v3.1 या इसके बाद का वर्शन) इंस्टॉल होना चाहिए
- इंटरनेट का ऐक्सेस, क्योंकि डेवलपमेंट के दौरान आपको लाइब्रेरी डाउनलोड करनी होंगी
अब जब आपके पास सब कुछ तैयार है, तो चलिए शुरू करते हैं!
2. डेवलपमेंट एनवायरमेंट सेट अप करना
एसडीके टूल डाउनलोड करना
हम GitHub से, ARCore Android SDK का नया वर्शन डाउनलोड करके शुरू करेंगे. इसे अपनी पसंद की जगह पर अनज़िप करें. इस कोडलैब के लिए, एसडीके टूल का सबसे पुराना वर्शन 1.18.1 है. इस फ़ोल्डर को arcore-android-sdk-x.xx.x के तौर पर दिखाया जाएगा. इसकी वैल्यू, SDK टूल का वह वर्शन होगा जिसका इस्तेमाल किया जा रहा है.
Android Studio लॉन्च करें और Android Studio का कोई मौजूदा प्रोजेक्ट खोलें पर क्लिक करें.

इस अनज़िप किए गए फ़ोल्डर पर जाएं:
arcore-android-sdk-x.xx.x/samples/augmented_image_java
खोलें पर क्लिक करें.
Android Studio में प्रोजेक्ट सिंक होने की प्रोसेस पूरी होने तक इंतज़ार करें. अगर आपके Android Studio में ज़रूरी कॉम्पोनेंट नहीं हैं, तो आपको यह मैसेज Install missing platform and sync project दिख सकता है. समस्या को ठीक करने के लिए, निर्देशों का पालन करें.
सैंपल ऐप्लिकेशन चलाना
अब आपके पास काम करने वाला ARCore ऐप्लिकेशन प्रोजेक्ट है. इसलिए, आइए इसे टेस्ट करके देखते हैं.
अपने ARCore डिवाइस को डेवलपमेंट मशीन से कनेक्ट करें. इसके बाद, डिवाइस पर डीबग वर्शन चलाने के लिए, मेन्यू Run > Run ‘app' का इस्तेमाल करें. डायलॉग बॉक्स में, कनेक्ट किया गया डिवाइस चुनें और ठीक है पर क्लिक करें.


इस सैंपल प्रोजेक्ट में targetSdkVersion 28 का इस्तेमाल किया गया है. अगर आपको Failed to find Build Tools revision 28.0.3 जैसी कोई बिल्ड गड़बड़ी दिखती है, तो Android Studio में दिए गए निर्देशों का पालन करके, Android Build Tools का ज़रूरी वर्शन डाउनलोड और इंस्टॉल करें.
अगर सब कुछ ठीक रहता है, तो डिवाइस पर सैंपल ऐप्लिकेशन लॉन्च हो जाएगा. साथ ही, आपसे ऑगमेंटेड इमेज को फ़ोटो और वीडियो रिकॉर्ड करने की अनुमति देने के लिए कहा जाएगा. अनुमति देने के लिए, अनुमति दें पर टैप करें.
सैंपल इमेज का इस्तेमाल करके टेस्ट करना
डेवलपमेंट एनवायरमेंट सेट अप करने के बाद, ऐप्लिकेशन को इमेज दिखाकर उसे टेस्ट किया जा सकता है.
Android Studio में वापस जाकर, Project विंडो में, app > assets पर जाएं. इसके बाद, फ़ाइल default.jpg को खोलने के लिए उस पर दो बार क्लिक करें.

अपने डिवाइस के कैमरे को स्क्रीन पर मौजूद पृथ्वी की इमेज पर रखें. इसके बाद, इमेज को क्रॉसहेयर में फ़िट करने के लिए दिए गए निर्देशों का पालन करें.
इमेज के ऊपर एक इमेज फ़्रेम ओवरले होगा. यह इस तरह दिखेगा:

इसके बाद, हम सैंपल ऐप्लिकेशन में कुछ छोटे-मोटे सुधार करेंगे.
3. 2D इमेज पर भूलभुलैया का मॉडल दिखाना
ऑगमेंटेड इमेज का इस्तेमाल शुरू करने के लिए, उसके ऊपर 3D मॉडल दिखाएं.
3D मॉडल डाउनलोड करना
इस कोडलैब के लिए, हम Evol का "Circle Maze - Green" इस्तेमाल करेंगे. इसका लाइसेंस CC-BY 3.0 के तहत मिला है. मैंने इस 3D मॉडल की एक कॉपी, इस कोडलैब की github रिपॉज़िटरी में सेव की है. इसे यहां देखा जा सकता है.
मॉडल डाउनलोड करने और उसे Android Studio में शामिल करने के लिए, यह तरीका अपनाएं.
- इस कोडलैब की GitHub रिपॉज़िटरी, third_party डायरेक्ट्री पर जाएं.
- GreenMaze_obj.zip पर क्लिक करें. इसके बाद, डाउनलोड करें बटन पर क्लिक करें.
इससे GreenMaze_obj.zip नाम की फ़ाइल डाउनलोड होती है.
- Android Studio में, app > assets > models के नीचे
green-mazeडायरेक्ट्री बनाएं GreenMaze_obj.zipअनज़िप करें और कॉन्टेंट को इस जगह पर कॉपी करें:arcore-android-sdk-x.xx.x/samples/augmented_image_java/app/src/main/assets/models/green-maze- Android Studio में, app > assets > models > green-maze पर जाएं.
इस फ़ोल्डर में दो फ़ाइलें होनी चाहिए: GreenMaze.obj और GreenMaze.mtl.

भूलभुलैया मॉडल रेंडर करना
मौजूदा 2D इमेज के ऊपर GreenMaze.obj 3D मॉडल दिखाने के लिए, यह तरीका अपनाएं.
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);
}
कोड को चलाएं. अब भूलभुलैया, इमेज के ऊपर पूरी तरह से फ़िट हो जानी चाहिए.

4. एंड्री को भूलभुलैया में जोड़ो
अब जब आपके पास एक भूलभुलैया है, तो उसमें घूमने के लिए एक कैरेक्टर जोड़ें. ARCore Android SDK में शामिल andy.obj फ़ाइल का इस्तेमाल करें. इमेज फ़्रेम के टेक्सचर को उसके टेक्सचर के तौर पर ही रखें, क्योंकि यह इमेज के ऊपर रेंडर किए गए हरे रंग के मेज़ से अलग दिखता है.
AugmentedImageRenderer.java में, Andy को रेंडर करने के लिए एक निजी 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);
}
अपना कोड चलाएं. आपको भूलभुलैया के ऊपर खड़े एंडी की इमेज दिखेगी.

टारगेट इमेज की क्वालिटी तय करना
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 को app > assets > models > green-maze से app > assets में कॉपी करें.
ऐप्लिकेशन की 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 वैरिएबल का इस्तेमाल करके, Andy को रेंडर करने के लिए 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;
ऐप्लिकेशन चलाएं. अब इमेज को झुकाने पर, ऐंडी को असलियत में घूमते हुए दिखना चाहिए.
नीचे दिए गए उदाहरण में, इमेज दिखाने के लिए किसी दूसरे फ़ोन का इस्तेमाल किया गया है. हालांकि, आपके पास अपनी सुविधा के हिसाब से कोई भी चीज़ इस्तेमाल करने का विकल्प है. जैसे, टैबलेट, हार्डकॉपी बुक का कवर या किसी समतल चीज़ पर चिपकाया गया प्रिंट किया गया पेपर.

हो गया! इस भूलभुलैया में से एंडी को बाहर निकालने की कोशिश करें. अहम जानकारी: टारगेट इमेज को उल्टा करके देखने पर, बाहर निकलने का रास्ता आसानी से मिल जाता है.
6. बधाई हो
बधाई हो, आपने इस कोडलैब को पूरा कर लिया है. इसलिए:
- ARCore AugmentedImage Java सैंपल बनाया और चलाया.
- इमेज पर सही साइज़ में मेज़ मॉडल दिखाने के लिए, सैंपल को अपडेट किया गया.
- इमेज में मौजूद पोज़ का इस्तेमाल करके, कुछ मज़ेदार बनाया गया हो.
अगर आपको पूरा कोड देखना है, तो इसे यहां से डाउनलोड करें.