Android पर Vision API की प्रॉडक्ट खोज के बैकएंड को कॉल करना

1. शुरू करने से पहले

bd8c01b2f8013c6d.png

क्या आपने Google Lens का डेमो देखा है? इसमें, फ़ोन के कैमरे को किसी ऑब्जेक्ट पर फ़ोकस करके, यह पता लगाया जा सकता है कि उसे ऑनलाइन कहां से खरीदा जा सकता है. अगर आपको अपने ऐप्लिकेशन में इसी सुविधा को जोड़ने का तरीका जानना है, तो यह कोडलैब आपके लिए है. यह एक लर्निंग पाथवे का हिस्सा है. इसमें आपको किसी मोबाइल ऐप्लिकेशन में, प्रॉडक्ट की इमेज खोजने की सुविधा बनाने का तरीका सिखाया जाता है.

इस कोडलैब में, आपको मोबाइल ऐप्लिकेशन से Vision API Product Search की मदद से बनाए गए बैकएंड को कॉल करने का तरीका बताया जाएगा. यह बैकएंड, क्वेरी इमेज ले सकता है और प्रॉडक्ट कैटलॉग से मिलते-जुलते प्रॉडक्ट खोज सकता है.

लर्निंग पाथवे में, इमेज या कैमरे से खोज करने की सुविधा बनाने के बाकी चरणों के बारे में जानें. इसमें यह भी शामिल है कि क्वेरी इमेज में मौजूद चीज़ों का पता लगाने के लिए, ML Kit Object Detection and Tracking का इस्तेमाल कैसे करें. साथ ही, उपयोगकर्ताओं को यह चुनने की सुविधा कैसे दें कि उन्हें किस प्रॉडक्ट को खोजना है.

आपको क्या बनाने को मिलेगा

  • इस कोडलैब में, आपको एक Android ऐप्लिकेशन दिया गया है. यह ऐप्लिकेशन, इनपुट इमेज में मौजूद ऑब्जेक्ट का पता लगा सकता है. आपको ऐसा कोड लिखना होगा जो उपयोगकर्ता के चुने गए ऑब्जेक्ट को ले सके, उसे प्रॉडक्ट सर्च के बैकएंड में भेज सके, और खोज के नतीजे को स्क्रीन पर दिखा सके.
  • आखिर में, आपको दाईं ओर मौजूद इमेज जैसा कुछ दिखेगा.

आपको क्या सीखने को मिलेगा

  • Android ऐप्लिकेशन से, Vision API Product Search API को कॉल करने और उसके जवाब को पार्स करने का तरीका

आपको इन चीज़ों की ज़रूरत होगी

  • Android Studio का नया वर्शन (v4.1.2+)
  • Android Studio Emulator या कोई Android डिवाइस
  • सैंपल कोड
  • Kotlin में Android डेवलपमेंट की बुनियादी जानकारी

यह कोडलैब, Vision API Product Search पर फ़ोकस करता है. इसमें काम के न होने वाले कॉन्सेप्ट और कोड ब्लॉक के बारे में नहीं बताया जाता. इन्हें सिर्फ़ कॉपी करके चिपकाने के लिए उपलब्ध कराया जाता है.

2. Vision API की प्रॉडक्ट खोज सुविधा के बारे में जानकारी

Vision API Product Search, Google Cloud में मौजूद एक सुविधा है. इसकी मदद से उपयोगकर्ता, प्रॉडक्ट कैटलॉग में मौजूद मिलते-जुलते प्रॉडक्ट खोज सकते हैं. खुदरा दुकानदार, प्रॉडक्ट बना सकते हैं. हर प्रॉडक्ट में रेफ़रंस इमेज शामिल होती हैं. ये इमेज, अलग-अलग ऐंगल से प्रॉडक्ट को दिखाती हैं. इसके बाद, इन प्रॉडक्ट को प्रॉडक्ट सेट (यानी कि प्रॉडक्ट कैटलॉग) में जोड़ा जा सकता है. फ़िलहाल, Vision API Product Search इन प्रॉडक्ट कैटगरी के लिए काम करता है: घरेलू सामान, कपड़े, खिलौने, पैकेज किए गए सामान, और सामान्य सामान.

जब लोग अपनी इमेज का इस्तेमाल करके प्रॉडक्ट सेट के बारे में क्वेरी करते हैं, तो Vision API Product Search, मशीन लर्निंग का इस्तेमाल करता है. इससे, क्वेरी में शामिल इमेज में मौजूद प्रॉडक्ट की तुलना, खुदरा दुकानदार के प्रॉडक्ट सेट में मौजूद इमेज से की जाती है. इसके बाद, विज़ुअल और सिमैंटिक तौर पर मिलते-जुलते नतीजों की रैंक की गई सूची दिखाई जाती है.

3. स्टार्टर ऐप्लिकेशन डाउनलोड और चलाना

कोड डाउनलोड करें

इस कोडलैब के लिए पूरा कोड डाउनलोड करने के लिए, यहां दिए गए लिंक पर क्लिक करें:

डाउनलोड की गई ज़िप फ़ाइल को अनपैक करें. इससे एक रूट फ़ोल्डर (odml-pathways-main) अनपैक हो जाएगा. इसमें आपको ज़रूरी सभी संसाधन मिलेंगे. इस कोडलैब के लिए, आपको सिर्फ़ product-search/codelab2/android सबडायरेक्ट्री में मौजूद सोर्स की ज़रूरत होगी.

codelab2 रिपॉज़िटरी में मौजूद codelab2 सबडायरेक्ट्री में दो डायरेक्ट्री होती हैं:odml-pathways

  • android_studio_folder.pngस्टार्टर—यह कोडलैब के लिए शुरुआती कोड है.
  • android_studio_folder.pngfinal—यह फ़ोल्डर, सैंपल ऐप्लिकेशन के लिए पूरा कोड दिखाता है.

यहां दिया गया स्टार्टर ऐप्लिकेशन वही है जिसे आपने इमेज में मौजूद ऑब्जेक्ट का पता लगाकर, विज़ुअल प्रॉडक्ट सर्च की सुविधा बनाना: Android कोडलैब में बनाया था. यह इमेज में मौजूद ऑब्जेक्ट का पता लगाने और उन्हें स्क्रीन पर दिखाने के लिए, ML Kit Object Detection and Tracking का इस्तेमाल करता है.

ऐप्लिकेशन को Android Studio में इंपोर्ट करना

सबसे पहले, स्टार्टर ऐप्लिकेशन को Android Studio में इंपोर्ट करें.

Android Studio पर जाएं. इसके बाद, Import Project (Gradle, Eclipse ADT, etc.) को चुनें. अब, सोर्स कोड से starter फ़ोल्डर चुनें. यह वही सोर्स कोड है जिसे आपने पहले डाउनलोड किया था.

7c0f27882a2698ac.png

स्टार्टर ऐप्लिकेशन चलाना

प्रोजेक्ट को Android Studio में इंपोर्ट करने के बाद, अब ऐप्लिकेशन को पहली बार चलाने के लिए तैयार हैं. अपने Android डिवाइस को यूएसबी के ज़रिए होस्ट से कनेक्ट करें या Android Studio Emulator शुरू करें. इसके बाद,Android Studio टूलबार में Run ( execute.png) पर क्लिक करें.

(अगर यह बटन बंद है, तो पक्का करें कि आपने सिर्फ़ starter/app/build.gradle इंपोर्ट किया हो, न कि पूरी रिपॉज़िटरी.)

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

c6102a808fdfcb11.png

स्टार्टर ऐप्लिकेशन का स्क्रीनशॉट, जो किसी इमेज में मौजूद ऑब्जेक्ट का पता लगा सकता है

इसके बाद, ऐप्लिकेशन को इस तरह से बढ़ाया जाएगा कि वह Vision API Product Search के बैकएंड को खोजे गए ऑब्जेक्ट भेज सके और स्क्रीन पर खोज के नतीजे दिखा सके.

4. ऑब्जेक्ट चुनने की सुविधा को मैनेज करना

उपयोगकर्ताओं को पहचाने गए ऑब्जेक्ट पर टैप करके उसे चुनने की अनुमति दें

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

9cdfcead6d95a87.png

इमेज में मौजूद फ़ैशन आइटम का स्क्रीनशॉट

कोडलैब को आसान बनाने और मशीन लर्निंग पर फ़ोकस करने के लिए, स्टार्टर ऐप्लिकेशन में कुछ बॉयलरप्लेट Android कोड लागू किया गया है. इससे आपको यह पता लगाने में मदद मिलेगी कि उपयोगकर्ता ने किस ऑब्जेक्ट पर टैप किया है. मुख्य ऐक्टिविटी (ObjectDetectorActivity) में इमेज दिखाने वाला व्यू, असल में एक कस्टम व्यू (ImageClickableView) है. यह Android OS के डिफ़ॉल्ट ImageView को बढ़ाता है. यह कुछ आसान यूटिलिटी मेथड लागू करता है. इनमें ये शामिल हैं:

  • fun setOnObjectClickListener(listener: ((objectImage: Bitmap) -> Unit)) यह एक कॉलबैक है. इससे काटी गई इमेज मिलती है. इसमें सिर्फ़ वह ऑब्जेक्ट होता है जिस पर उपयोगकर्ता ने टैप किया है. आपको काटी गई इस इमेज को, प्रॉडक्ट खोजने वाले बैकएंड को भेजना होगा.

उपयोगकर्ता के टैप किए गए ऑब्जेक्ट को हैंडल करने के लिए कोड जोड़ें.

ObjectDetectorActivity क्लास में initViews तरीके पर जाएं और तरीके के आखिर में ये लाइनें जोड़ें: Android Studio आपको बताएगा कि उसे startProductImageSearch तरीका नहीं मिल रहा है. चिंता न करें, इसे कुछ समय बाद लागू किया जाएगा.)

// Callback received when the user taps on any of the detected objects.
ivPreview.setOnObjectClickListener { objectImage ->
    startProductImageSearch(objectImage)
}

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

9cac8458d0f326e6.png

काटी गई इमेज का उदाहरण, जिसे onObjectClickListener को पास किया गया है

काटी गई इमेज को, प्रॉडक्ट खोजने की गतिविधि के लिए भेजना

अब आपको क्वेरी इमेज को Vision API Product Search के बैकएंड में भेजने का लॉजिक, अलग गतिविधि (ProductSearchActivity) में लागू करना होगा.

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

25939f5a13eeb3c3.png

ProductSearchActivity पर यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट का स्क्रीनशॉट

उपयोगकर्ता ने जिस ऑब्जेक्ट की इमेज चुनी है उसे ProductSearchActivity पर भेजने के लिए कोड जोड़ें.

Android Studio पर वापस जाएं और इस startProductImageSearch तरीके को ObjectDetectorActivity क्लास में जोड़ें:

private fun startProductImageSearch(objectImage: Bitmap) {
    try {
        // Create file based Bitmap. We use PNG to preserve the image quality
        val savedFile = createImageFile(ProductSearchActivity.CROPPED_IMAGE_FILE_NAME)
        objectImage.compress(Bitmap.CompressFormat.PNG, 100, FileOutputStream(savedFile))

        // Start the product search activity (using Vision Product Search API.).
        startActivity(
            Intent(
                    this,
                    ProductSearchActivity::class.java
            ).apply {
                // As the size limit of a bundle is 1MB, we need to save the bitmap to a file
                // and reload it in the other activity to support large query images.
                putExtra(
                    ProductSearchActivity.REQUEST_TARGET_IMAGE_PATH,
                    savedFile.absolutePath
                )
            })
    } catch (e: Exception) {
        // IO Exception, Out Of memory ....
        Toast.makeText(this, e.message, Toast.LENGTH_SHORT).show()
        Log.e(TAG, "Error starting the product image search activity.", e)
    }
}

यह कोड स्निपेट तीन काम करता है:

  • यह काटी गई इमेज लेता है और उसे PNG फ़ाइल में बदलता है.
  • यह कुकी, प्रॉडक्ट खोजने की प्रोसेस को पूरा करने के लिए ProductSearchActivity को शुरू करती है.
  • इसमें स्टार्ट-ऐक्टिविटी इंटेंट में काटी गई इमेज का यूआरआई शामिल होता है, ताकि ProductSearchActivity इसे बाद में क्वेरी इमेज के तौर पर इस्तेमाल करने के लिए वापस पा सके.

आपको कुछ बातों का ध्यान रखना चाहिए, जैसे:

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

प्रॉडक्ट खोजने के लिए की गई गतिविधि में क्वेरी इमेज को वापस पाना

ProductSearchActivity में, क्वेरी इमेज को वापस पाने और उसे स्क्रीन पर दिखाने के लिए, कोड को स्टार्टर ऐप्लिकेशन में पहले ही लागू कर दिया गया है.

onCreate तरीके पर जाएं और पुष्टि करें कि यह कोड पहले से मौजूद है:

// Receive the query image and show it on the screen
intent.getStringExtra(REQUEST_TARGET_IMAGE_PATH)?.let { absolutePath ->
    viewBinding.ivQueryImage.setImageBitmap(BitmapFactory.decodeFile(absolutePath))
}

ऐप्लिकेशन चलाना

अब Android Studio टूलबार में, Run ( execute.png) पर क्लिक करें.

ऐप्लिकेशन लोड होने के बाद, किसी भी प्रीसेट इमेज पर टैप करें. इसके बाद, पता लगाए गए ऑब्जेक्ट में से किसी एक को चुनें.

पुष्टि करें कि आपने जिस इमेज पर टैप किया है उसके साथ ProductSearchActivity दिख रहा हो. खोजें बटन अभी काम नहीं करता, लेकिन हम इसे अगले चरण में लागू करेंगे.

fed40f81b8b43801.png

पहचाने गए किसी ऑब्जेक्ट पर टैप करने के बाद, आपको ऐसी ही स्क्रीन दिखेगी.

5. प्रॉडक्ट खोजने की सुविधा के बैकएंड के बारे में जानें

प्रॉडक्ट की इमेज से खोज करने की सुविधा के लिए बैकएंड बनाना

इस कोडलैब के लिए, Vision API Product Search का इस्तेमाल करके बनाया गया प्रॉडक्ट सर्च बैकएंड ज़रूरी है. ऐसा करने के लिए, आपके पास दो विकल्प हैं:

पहला विकल्प: आपके लिए डिप्लॉय किए गए डेमो बैकएंड का इस्तेमाल करना

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

दूसरा विकल्प: Vision API Product Search के क्विकस्टार्ट को फ़ॉलो करके, अपना बैकएंड बनाएं

हमारा सुझाव है कि इस विकल्प को उन लोगों के लिए चुना जाना चाहिए जिन्हें प्रॉडक्ट खोजने की सुविधा के लिए बैकएंड बनाने के बारे में ज़्यादा जानकारी चाहिए. इससे वे बाद में अपने प्रॉडक्ट कैटलॉग के लिए बैकएंड बना पाएंगे. आपके पास ये चीज़ें होनी चाहिए:

  • बिलिंग की सुविधा वाला Google Cloud खाता. (यह मुफ़्त में आज़माने की सुविधा वाला खाता हो सकता है.)
  • Google Cloud के कॉन्सेप्ट के बारे में कुछ जानकारी होनी चाहिए. जैसे, प्रोजेक्ट, सेवा खाते वगैरह.

इस बारे में ज़्यादा जानने के लिए, लर्निंग पाथवे पर जाएं.

ज़रूरी कॉन्सेप्ट के बारे में जानें

प्रॉडक्ट खोज के बैकएंड के साथ इंटरैक्ट करते समय, आपको इन कॉन्सेप्ट के बारे में पता चलेगा:

  • प्रॉडक्ट सेट: प्रॉडक्ट सेट, प्रॉडक्ट के ग्रुप के लिए एक सामान्य कंटेनर होता है. प्रॉडक्ट कैटलॉग को प्रॉडक्ट सेट और उसके प्रॉडक्ट के तौर पर दिखाया जा सकता है.
  • प्रॉडक्ट: प्रॉडक्ट सेट बनाने के बाद, प्रॉडक्ट बनाए जा सकते हैं और उन्हें प्रॉडक्ट सेट में जोड़ा जा सकता है.
  • प्रॉडक्ट की रेफ़रंस इमेज: ये ऐसी इमेज होती हैं जिनमें आपके प्रॉडक्ट के अलग-अलग व्यू दिखाए जाते हैं. रेफ़रंस इमेज का इस्तेमाल, दिखने में एक जैसे प्रॉडक्ट खोजने के लिए किया जाता है.
  • प्रॉडक्ट खोजना: प्रॉडक्ट सेट बनाने और उसे इंडेक्स करने के बाद, Cloud Vision API का इस्तेमाल करके प्रॉडक्ट सेट के बारे में क्वेरी की जा सकती है.

प्रीसेट किए गए प्रॉडक्ट कैटलॉग के बारे में जानकारी

इस कोडलैब में इस्तेमाल किया गया प्रॉडक्ट सर्च डेमो बैकएंड, Vision API Product Search का इस्तेमाल करके बनाया गया था. इसमें करीब सौ जूतों और कपड़ों की इमेज वाला प्रॉडक्ट कैटलॉग शामिल है. कैटलॉग की कुछ इमेज यहां दी गई हैं:

4f1a8507b74ab178.png 79a5fc6c829eca77.png 3528c872f813826e.png

प्रीसेट किए गए प्रॉडक्ट कैटलॉग के उदाहरण

प्रॉडक्ट खोजने के डेमो के बैकएंड को कॉल करना

Google Cloud API कुंजी सेट अप करके, Vision API Product Search को सीधे तौर पर किसी मोबाइल ऐप्लिकेशन से कॉल किया जा सकता है. साथ ही, एपीआई कुंजी के ऐक्सेस को सिर्फ़ अपने ऐप्लिकेशन तक सीमित किया जा सकता है.

इस कोडलैब को आसान बनाने के लिए, एक प्रॉक्सी एंडपॉइंट सेट अप किया गया है. इससे आपको एपीआई पासकोड और पुष्टि के बारे में चिंता किए बिना, डेमो बैकएंड को ऐक्सेस करने की अनुमति मिलती है. यह मोबाइल ऐप्लिकेशन से एचटीटीपी अनुरोध पाता है, एपीआई कुंजी जोड़ता है, और अनुरोध को Vision API Product Search के बैकएंड पर भेजता है. इसके बाद, प्रॉक्सी को बैकएंड से जवाब मिलता है और वह इसे मोबाइल ऐप्लिकेशन को भेज देता है.

इस कोडलैब में, Vision API Product Search के दो एपीआई का इस्तेमाल किया जाएगा:

  • projects.locations.images.annotate: इस स्कोप का इस्तेमाल, क्वेरी इमेज को सर्वर पर भेजने और पहले से सेट किए गए प्रॉडक्ट कैटलॉग से, क्वेरी इमेज से मिलते-जुलते प्रॉडक्ट की सूची पाने के लिए किया जाता है.
  • projects.locations.products.referenceImages.get: उपयोगकर्ताओं को दिखाने के लिए, ऊपर दिए गए एपीआई कॉल में मिले प्रॉडक्ट की इमेज के यूआरआई पाना.

6. एपीआई क्लाइंट को लागू करना

प्रॉडक्ट खोजने के वर्कफ़्लो को समझना

बैकएंड की मदद से प्रॉडक्ट खोजने के लिए, यह वर्कफ़्लो अपनाएं:

  • क्वेरी इमेज को base64 स्ट्रिंग के तौर पर एन्कोड करें
  • क्वेरी इमेज के साथ projects.locations.images.annotate एंडपॉइंट को कॉल करें
  • पिछले एपीआई कॉल से प्रॉडक्ट इमेज आईडी पाएं और उन्हें projects.locations.products.referenceImages.get एंडपॉइंट पर भेजें, ताकि खोज के नतीजों में प्रॉडक्ट इमेज के यूआरआई मिल सकें.

एपीआई क्लाइंट क्लास लागू करना

अब आपको ProductSearchAPIClient नाम की क्लास में, प्रॉडक्ट खोज के बैकएंड को कॉल करने के लिए कोड लागू करना होगा. स्टार्टर ऐप्लिकेशन में, आपके लिए कुछ बॉयलरप्लेट कोड लागू किया गया है:

  • class ProductSearchAPIClient: यह क्लास अब ज़्यादातर खाली है, लेकिन इसमें कुछ ऐसे तरीके हैं जिन्हें आपको इस कोडलैब में बाद में लागू करना होगा.
  • fun convertBitmapToBase64(bitmap: Bitmap): Bitmap इंस्टेंस को base64 फ़ॉर्मैट में बदलता है, ताकि उसे प्रॉडक्ट खोजने वाले बैकएंड को भेजा जा सके
  • fun annotateImage(image: Bitmap): Task<List<ProductSearchResult>>: projects.locations.images.annotate एपीआई को कॉल करें और जवाब को पार्स करें.
  • fun fetchReferenceImage(searchResult: ProductSearchResult): Task<ProductSearchResult>: projects.locations.products.referenceImages.get एपीआई को कॉल करें और जवाब को पार्स करें.
  • SearchResult.kt: इस फ़ाइल में कई डेटा क्लास शामिल हैं. ये Vision API Product Search के बैकएंड से मिले टाइप को दिखाती हैं.

एपीआई कॉन्फ़िगरेशन तय करना

ProductSearchAPIClient क्लास पर जाएं. आपको प्रॉडक्ट खोजने के लिए बैकएंड के कुछ कॉन्फ़िगरेशन पहले से ही तय किए गए दिखेंगे:

// Define the product search backend
// Option 1: Use the demo project that we have already deployed for you
const val VISION_API_URL =
    "https://us-central1-odml-codelabs.cloudfunctions.net/productSearch"
const val VISION_API_KEY = ""
const val VISION_API_PROJECT_ID = "odml-codelabs"
const val VISION_API_LOCATION_ID = "us-east1"
const val VISION_API_PRODUCT_SET_ID = "product_set0"
  • VISION_API_URL, Cloud Vision API का एपीआई एंडपॉइंट है. डेमो बैकएंड का इस्तेमाल करते समय, इसे प्रॉक्सी एंडपॉइंट पर सेट करें. हालांकि, अगर आपने अपना बैकएंड डिप्लॉय किया है, तो आपको इसे Cloud Vision API के एंडपॉइंट पर बदलना होगा. https://vision.googleapis.com/v1.
  • VISION_API_KEY आपके Cloud प्रोजेक्ट का एपीआई पासकोड है. प्रॉक्सी पहले से ही पुष्टि की प्रोसेस को मैनेज करती है. इसलिए, इसे खाली छोड़ा जा सकता है.
  • VISION_API_PROJECT_ID, Cloud प्रोजेक्ट का आईडी है. odml-codelabs वह Cloud प्रोजेक्ट है जहां डेमो बैकएंड को डिप्लॉय किया गया है.
  • VISION_API_LOCATION_ID, Cloud की वह जगह है जहां प्रॉडक्ट खोजने वाले बैकएंड को डिप्लॉय किया जाता है. us-east1 में हमने डेमो बैकएंड को डिप्लॉय किया है.
  • VISION_API_PRODUCT_SET_ID, प्रॉडक्ट कैटलॉग का आईडी होता है. इसे Vision API की भाषा में "प्रॉडक्ट सेट" भी कहा जाता है. इस कैटलॉग में, आपको दिखने में मिलते-जुलते प्रॉडक्ट खोजने होते हैं. एक Cloud प्रोजेक्ट में कई कैटलॉग हो सकते हैं. product_set0, डेमो बैकएंड का प्रीसेट प्रॉडक्ट कैटलॉग है.

7. प्रॉडक्ट खोजने वाले एपीआई को कॉल करना

एपीआई अनुरोध और रिस्पॉन्स के फ़ॉर्मैट के बारे में जानें

Vision API Product Search को इमेज का Google Cloud Storage यूआरआई, वेब यूआरएल या base64 एन्कोड की गई स्ट्रिंग भेजकर, किसी इमेज से मिलते-जुलते प्रॉडक्ट खोजे जा सकते हैं. इस कोडलैब में, base64 एन्कोड की गई स्ट्रिंग के विकल्प का इस्तेमाल किया जाएगा, क्योंकि हमारी क्वेरी इमेज सिर्फ़ उपयोगकर्ता के डिवाइस में मौजूद है.

आपको इस अनुरोध JSON बॉडी के साथ, projects.locations.images.annotate एंडपॉइंट पर एक POST अनुरोध भेजना होगा:

{
  "requests": [
    {
      "image": {
        "content": {base64-encoded-image}
      },
      "features": [
        {
          "type": "PRODUCT_SEARCH",
          "maxResults": 5
        }
      ],
      "imageContext": {
        "productSearchParams": {
          "productSet": "projects/{project-id}/locations/{location-id}/productSets/{product-set-id}",
          "productCategories": [
               "apparel-v2"
          ],
        }
      }
    }
  ]
}

कुछ ऐसे पैरामीटर हैं जिन्हें तय करना ज़रूरी है::

  • base64-encoded-image: क्वेरी इमेज के बाइनरी डेटा का base64 फ़ॉर्मैट (ASCII स्ट्रिंग).
  • project-id: यह आपके GCP प्रोजेक्ट का आईडी होता है.
  • location-id: जगह का मान्य आइडेंटिफ़ायर.
  • product-set-id: वह प्रॉडक्ट सेट आईडी जिस पर आपको कार्रवाई करनी है.

आपके प्रॉडक्ट कैटलॉग में सिर्फ़ जूते और ड्रेस की इमेज हैं. इसलिए, productCategories को apparel-v2 के तौर पर सेट करें. यहां v2 का मतलब है कि हम कपड़ों के प्रॉडक्ट खोजने के लिए, मशीन लर्निंग मॉडल के वर्शन 2 का इस्तेमाल करते हैं.

अनुरोध पूरा होने पर, सर्वर 200 OK एचटीटीपी स्टेटस कोड और JSON फ़ॉर्मैट में जवाब देता है. जवाब के JSON में, नतीजे के तौर पर ये दो तरह की जानकारी शामिल होती है:

  • productSearchResults - इसमें पूरी इमेज से मिलते-जुलते प्रॉडक्ट की सूची होती है.
  • productGroupedResults - इसमें इमेज में पहचाने गए हर प्रॉडक्ट के लिए, बाउंडिंग बॉक्स के कोऑर्डिनेट और मिलते-जुलते आइटम शामिल होते हैं.

प्रॉडक्ट को ओरिजनल इमेज से पहले ही काटा जा चुका है. इसलिए, आपको productSearchResults सूची में नतीजे पार्स करने होंगे.

प्रॉडक्ट खोज के नतीजे वाले ऑब्जेक्ट में मौजूद कुछ अहम फ़ील्ड यहां दिए गए हैं:

  • product.name: यह projects/{project-id}/locations/{location-id}/products/{product_id} फ़ॉर्मैट में, किसी प्रॉडक्ट का यूनीक आइडेंटिफ़ायर होता है
  • product.score: यह वैल्यू बताती है कि खोज नतीजा, क्वेरी इमेज से कितना मिलता-जुलता है. ज़्यादा वैल्यू का मतलब है कि दोनों इमेज ज़्यादा मिलती-जुलती हैं.
  • product.image: यह projects/{project-id}/locations/{location-id}/products/{product_id}/referenceImages/{image_id} फ़ॉर्मैट में, किसी प्रॉडक्ट की रेफ़रंस इमेज का यूनीक आइडेंटिफ़ायर होता है. आपको इस रेफ़रंस इमेज का यूआरएल पाने के लिए, projects.locations.products.referenceImages.get को एक और एपीआई अनुरोध भेजना होगा, ताकि यह स्क्रीन पर दिख सके.
  • product.labels: प्रॉडक्ट के पहले से तय किए गए टैग की सूची. अगर आपको खोज के नतीजों को फ़िल्टर करके, सिर्फ़ एक तरह के कपड़े दिखाने हैं, तो यह तरीका फ़ायदेमंद होता है. जैसे, सिर्फ़ ड्रेस दिखाना.

क्वेरी इमेज को base64 में बदलें

आपको क्वेरी इमेज को base64 स्ट्रिंग में बदलना होगा. इसके बाद, इस स्ट्रिंग को अनुरोध के मुख्य हिस्से में मौजूद JSON ऑब्जेक्ट से अटैच करना होगा.

ProductSearchAPIClient क्लास पर जाएं. इसके बाद, खाली convertBitmapToBase64 तरीका ढूंढें और उसे इस तरीके से बदलें:

private fun convertBitmapToBase64(bitmap: Bitmap): String {
    val byteArrayOutputStream = ByteArrayOutputStream()
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream)
    val byteArray: ByteArray = byteArrayOutputStream.toByteArray()
    return Base64.encodeToString(byteArray, Base64.DEFAULT)
}

एपीआई कॉल लागू करना

इसके बाद, प्रॉडक्ट खोजने के लिए एपीआई का अनुरोध तैयार करें और उसे बैकएंड पर भेजें. एपीआई अनुरोध करने के लिए, Volley का इस्तेमाल किया जाएगा. साथ ही, Task API का इस्तेमाल करके नतीजे दिखाए जाएंगे.

ProductSearchAPIClient क्लास पर वापस जाएं. इसके बाद, खाली annotateImage तरीका ढूंढें और उसे इस तरीके से बदलें:

fun annotateImage(image: Bitmap): Task<List<ProductSearchResult>> {
    // Initialization to use the Task API
    val apiSource = TaskCompletionSource<List<ProductSearchResult>>()
    val apiTask = apiSource.task

    // Convert the query image to its Base64 representation to call the Product Search API.
    val base64: String = convertBitmapToBase64(image)

    // Craft the request body JSON.
    val requestJson = """
        {
          "requests": [
            {
              "image": {
                "content": """".trimIndent() + base64 + """"
              },
              "features": [
                {
                  "type": "PRODUCT_SEARCH",
                  "maxResults": $VISION_API_PRODUCT_MAX_RESULT
                }
              ],
              "imageContext": {
                "productSearchParams": {
                  "productSet": "projects/${VISION_API_PROJECT_ID}/locations/${VISION_API_LOCATION_ID}/productSets/${VISION_API_PRODUCT_SET_ID}",
                  "productCategories": [
                       "apparel-v2"
                     ]
                }
              }
            }
          ]
        }
    """.trimIndent()

    // Add a new request to the queue
    requestQueue.add(object :
        JsonObjectRequest(
            Method.POST,
            "$VISION_API_URL/images:annotate?key=$VISION_API_KEY",
            JSONObject(requestJson),
            { response ->
                // Parse the API JSON response to a list of ProductSearchResult object/
                val productList = apiResponseToObject(response)

                // Return the list.
                apiSource.setResult(productList)
            },
            // Return the error
            { error -> apiSource.setException(error) }
        ) {
        override fun getBodyContentType() = "application/json"
    }.apply {
        setShouldCache(false)
    })

    return apiTask
}

यूज़र इंटरफ़ेस पर खोज के नतीजे दिखाना

अब ProductSearchAPIClient में एपीआई कोड तैयार है. यूज़र इंटरफ़ेस (यूआई) कोड लागू करने के लिए, गतिविधि ProductSearchActivity पर वापस जाएं.

गतिविधि में पहले से ही कुछ बॉयलरप्लेट कोड मौजूद है, जो searchByImage(queryImage: Bitmap) तरीके को ट्रिगर करता है. बैकएंड को कॉल करने और यूज़र इंटरफ़ेस (यूआई) पर नतीजे दिखाने के लिए, इस खाली तरीके में कोड जोड़ें.

apiClient.annotateImage(queryImage)
    .addOnSuccessListener { showSearchResult(it) }
    .addOnFailureListener { error ->
        Log.e(TAG, "Error calling Vision API Product Search.", error)
        showErrorResponse(error.localizedMessage)
    }

showSearchResult तरीके में कुछ बॉयलरप्लेट कोड होता है. यह एपीआई के जवाब को पार्स करता है और उसे आपकी स्क्रीन पर दिखाता है.

इसे चलाएं

अब Android Studio टूलबार में, Run ( execute.png) पर क्लिक करें. ऐप्लिकेशन लोड होने के बाद, पहले से सेट की गई किसी भी इमेज पर टैप करें. इसके बाद, पहचाना गया कोई ऑब्जेक्ट चुनें. अब खोजें बटन पर टैप करें और बैकएंड से मिले खोज के नतीजे देखें. आपको कुछ ऐसा दिखेगा:

bb5e7c27c283a2fe.png

प्रॉडक्ट के लिए खोज के नतीजों वाली स्क्रीन का स्क्रीनशॉट

बैकएंड, पहले से सेट किए गए प्रॉडक्ट कैटलॉग से, दिखने में मिलते-जुलते प्रॉडक्ट की सूची पहले ही दिखा देता है. हालांकि, आपको दिखेगा कि प्रॉडक्ट की इमेज अब भी खाली है. ऐसा इसलिए है, क्योंकि projects.locations.images.annotate एंडपॉइंट सिर्फ़ प्रॉडक्ट इमेज आईडी दिखाता है, जैसे कि projects/odml-codelabs/locations/us-east1/products/product_id77/referenceImages/image77. आपको projects.locations.products.referenceImages.get एंडपॉइंट पर एक और एपीआई कॉल करना होगा. साथ ही, इस रेफ़रंस इमेज का यूआरएल पाना होगा, ताकि इसे स्क्रीन पर दिखाया जा सके.

8. प्रॉडक्ट की रेफ़रंस इमेज पाना

एपीआई अनुरोध और रिस्पॉन्स के फ़ॉर्मैट के बारे में जानें

आपको projects.locations.products.referenceImages.get एंडपॉइंट पर, खाली अनुरोध बॉडी के साथ GET एचटीटीपी अनुरोध भेजना होगा. इससे आपको प्रॉडक्ट खोजने वाले एंडपॉइंट से मिली प्रॉडक्ट इमेज के यूआरआई मिलेंगे.

एचटीटीपी अनुरोध कुछ ऐसा दिखता है:

GET $VISION_API_URL/projects/odml-codelabs/locations/us-east1/products/product_id77/referenceImages/image77?key=$VISION_API_KEY

अनुरोध पूरा होने पर, सर्वर 200 OK एचटीटीपी स्टेटस कोड दिखाता है. साथ ही, JSON फ़ॉर्मैट में जवाब देता है. जवाब इस तरह दिखता है:

{
  "name":"projects/odml-codelabs/locations/us-east1/products/product_id77/referenceImages/image77",
  "uri":"gs://cloud-ai-vision-data/product-search-tutorial/images/46991e7370ba11e8a1bbd20059124800.jpg"
}
  • name: रेफ़रंस इमेज का आइडेंटिफ़ायर
  • uri: Google Cloud Storage (GCS) पर मौजूद इमेज का यूआरआई.

डेमो प्रॉडक्ट की खोज के लिए बैकएंड की रेफ़रंस इमेज को इस तरह सेट अप किया गया था कि उसे सार्वजनिक तौर पर पढ़ा जा सके. इसलिए, GCS यूआरआई को आसानी से एचटीटीपी यूआरएल में बदला जा सकता है और इसे ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) पर दिखाया जा सकता है. आपको सिर्फ़ gs:// प्रीफ़िक्स को https://storage.googleapis.com/ से बदलना है.

एपीआई कॉल लागू करना

इसके बाद, प्रॉडक्ट खोजने के लिए एपीआई का अनुरोध तैयार करें और उसे बैकएंड पर भेजें. आपको Volley और Task API का इस्तेमाल, प्रॉडक्ट सर्च एपीआई कॉल की तरह ही करना होगा.

ProductSearchAPIClient क्लास पर वापस जाएं. इसके बाद, खाली fetchReferenceImage तरीका ढूंढें और उसे इस तरीके से बदलें:

private fun fetchReferenceImage(searchResult: ProductSearchResult): Task<ProductSearchResult> {
    // Initialization to use the Task API
    val apiSource = TaskCompletionSource<ProductSearchResult>()
    val apiTask = apiSource.task

    // Craft the API request to get details about the reference image of the product
    val stringRequest = object : StringRequest(
        Method.GET,
        "$VISION_API_URL/${searchResult.imageId}?key=$VISION_API_KEY",
        { response ->
            val responseJson = JSONObject(response)
            val gcsUri = responseJson.getString("uri")

            // Convert the GCS URL to its HTTPS representation
            val httpUri = gcsUri.replace("gs://", "https://storage.googleapis.com/")

            // Save the HTTPS URL to the search result object
            searchResult.imageUri = httpUri

            // Invoke the listener to continue with processing the API response (eg. show on UI)
            apiSource.setResult(searchResult)
        },
        { error -> apiSource.setException(error) }
    ) {

        override fun getBodyContentType(): String {
            return "application/json; charset=utf-8"
        }
    }
    Log.d(ProductSearchActivity.TAG, "Sending API request.")

    // Add the request to the RequestQueue.
    requestQueue.add(stringRequest)

    return apiTask
}

यह तरीका, प्रॉडक्ट सर्च एंडपॉइंट से मिले searchResult: ProductSearchResult ऑब्जेक्ट को लेता है. इसके बाद, यह तरीका इन चरणों को पूरा करता है:

  1. यह कुकी, रेफ़रंस इमेज के एंडपॉइंट को कॉल करती है, ताकि रेफ़रंस इमेज का GCS यूआरआई मिल सके.
  2. यह फ़ंक्शन, GCS यूआरआई को एचटीटीपी यूआरएल में बदलता है.
  3. यह एचटीटीपी यूआरएल, searchResult ऑब्जेक्ट की httpUri प्रॉपर्टी को अपडेट करता है.

दोनों एपीआई अनुरोधों को कनेक्ट करना

annotateImage पर वापस जाएं और इसमें बदलाव करें, ताकि सभी रेफ़रंस इमेज के एचटीटीपी यूआरएल मिल सकें. इसके बाद, ProductSearchResult की सूची को कॉल करने वाले व्यक्ति को वापस भेजें.

यह लाइन ढूंढें:

// Return the list.
apiSource.setResult(productList)

इसके बाद, इसे इस कोड से बदलें:

// Loop through the product list and create tasks to load reference images.
// We will call the projects.locations.products.referenceImages.get endpoint
// for each product.
val fetchReferenceImageTasks = productList.map { fetchReferenceImage(it) }

// When all reference image fetches have completed,
// return the ProductSearchResult list
Tasks.whenAllComplete(fetchReferenceImageTasks)
    // Return the list of ProductSearchResult with product images' HTTP URLs.
    .addOnSuccessListener { apiSource.setResult(productList) }
    // An error occurred so returns it to the caller.
    .addOnFailureListener { apiSource.setException(it) }

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

इसे चलाएं

अब Android Studio टूलबार में, Run ( execute.png) पर क्लिक करें. ऐप्लिकेशन लोड होने के बाद, किसी भी प्रीसेट इमेज पर टैप करें. इसके बाद, खोजे गए किसी ऑब्जेक्ट को चुनें. अब खोज के नतीजे देखने के लिए, खोजें बटन पर टैप करें. इस बार, आपको प्रॉडक्ट की इमेज के साथ खोज के नतीजे दिखेंगे.

क्या आपको प्रॉडक्ट के खोज नतीजे समझ में आ रहे हैं?

25939f5a13eeb3c3.png

9. बधाई हो!

आपने Vision API की प्रॉडक्ट खोज के बैकएंड को कॉल करने का तरीका जान लिया है. इससे आपके Android ऐप्लिकेशन में, प्रॉडक्ट की इमेज खोज करने की सुविधा जोड़ी जा सकेगी. इसे चालू करने के लिए, आपको बस इतना ही करना है!

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

हमने क्या-क्या बताया

  • Android ऐप्लिकेशन से, Vision API Product Search के बैकएंड को कॉल करने का तरीका

अगले चरण

ज़्यादा जानें