الاتصال بواجهة برمجة تطبيقات البحث في منتج واجهة برمجة التطبيقات Vision API على نظام التشغيل Android

1. قبل البدء

bd8c01b2f8013c6d.png

هل رأيت الإصدار التجريبي من "عدسة Google" حيث يمكنك توجيه كاميرا هاتفك إلى عنصر والعثور على مكان شرائه على الإنترنت؟ إذا كنت تريد معرفة كيفية إضافة الميزة نفسها إلى تطبيقك، هذا الدرس التطبيقي هو الحل الأمثل لك. وهو جزء من مسار تعليمي يعلّمك كيفية إنشاء ميزة بحث عن صورة منتج في تطبيق متوافق مع الأجهزة الجوّالة.

في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية طلب واجهة خلفية تم إنشاؤها باستخدام Vision API Product Search من تطبيق متوافق مع الأجهزة الجوّالة. ويمكن لهذه الخلفية التقاط صورة لطلب البحث والبحث عن منتجات متشابهة مرئيًا من كتالوج منتجات.

يمكنك الاطّلاع على الخطوات المتبقية لإنشاء ميزة مرئية للبحث عن المنتجات، بما في ذلك كيفية استخدام ML Object Detection andTracking لاكتشاف العناصر في صورة طلب البحث والسماح للمستخدمين باختيار المنتج الذي يريدون البحث عنه، في مسار التعلّم.

العناصر التي سيتم إنشاؤها

  • في هذا الدرس التطبيقي حول الترميز، ستبدأ بتطبيق Android الذي يمكنه رصد الكائنات من صورة إدخال. ستكتب الرمز لأخذ الكائن الذي يختاره المستخدم، وإرساله إلى خلفية البحث عن المنتج، وعرض نتيجة البحث على الشاشة.
  • في النهاية، من المفترض أن ترى شيئًا مماثلاً للصورة على اليسار.

ما ستتعرّف عليه

  • كيفية طلب وتحليل استجابة واجهات برمجة تطبيقات البحث عن منتج Vision API من أحد تطبيقات Android

المتطلبات اللازمة

  • إصدار حديث من "استوديو Android" (الإصدار 4.1.2 أو الإصدارات الأحدث)
  • جهاز Android Studio Emulator أو جهاز فعلي يعمل بنظام التشغيل Android
  • نموذج الرمز
  • المعرفة الأساسية بتطوير نظام التشغيل Android بلغة Kotlin

يركز هذا الدرس التطبيقي على الترميز Vision API Product Search. ولا يتم استكشاف المفاهيم والرموز غير ذات الصلة، كما يتم توفير هذه النسخ للنسخ واللصق.

2. لمحة عن منتج Vision API Product Search

Vision API Product Search هي ميزة في Google Cloud تتيح للمستخدمين البحث عن المنتجات المشابهة من خلال كتالوج منتجات. يمكن لبائعي التجزئة إنشاء منتجات يتضمّن كلّ منها صورًا مرجعية تصف المنتج بشكل مرئي من مجموعة من وجهات النظر. يمكنك بعد ذلك إضافة هذه المنتجات إلى مجموعات المنتجات (أي كتالوج المنتج). في الوقت الحالي، تسمح واجهة برمجة تطبيقات المنتجات في Vision API بفئات المنتجات التالية: السلع المنزلية والملابس والألعاب والسلع المجمّعة والمنتجات العامة.

عندما يبحث المستخدمون عن مجموعة المنتجات بصورهم الخاصة، يطبِّق Vision API Product Search تكنولوجيا تعلُّم الآلة لمقارنة المنتج في صورة طلب بحث المستخدم مع الصور المعروضة في مجموعة منتجات بائع التجزئة، ثم يعرض قائمة مرتبة لنتائج مشابهة من الناحية المرئية ودلاليًا.

3- تنزيل تطبيق بدء التشغيل وتشغيله

تنزيل الرمز

انقر على الرابط التالي لتنزيل كل رموز هذا الدرس التطبيقي حول الترميز:

فك ضغط ملف zip الذي تم تنزيله. سيؤدي ذلك إلى تفريغ مجلد جذر (odml-pathways-main) يضم جميع الموارد التي تحتاجها. بالنسبة إلى هذا الدرس التطبيقي حول الترميز، ستحتاج إلى المصادر في الدليل الفرعي product-search/codelab2/android فقط.

يحتوي الدليل الفرعي codelab2 في المستودع odml-pathways على دليلَين:

  • Android_studio_folder.png Starter - الرمز الذي يتم استخدامه في هذا الدرس التطبيقي حول الترميز.
  • Android_studio_folder.pngنهائي - اكتمل رمز نموذج التطبيق المكتمل.

تطبيق المبتدئين هنا هو التطبيق الذي أنشأته في الدرس التطبيقي حول ترميز رصد الكائنات في الصور لإنشاء بحث منتجات مرئي: Android. وتستخدم هذه الأداة رصد كائنات ML Kit والتتبّع لاكتشاف العناصر من الصورة وعرضها على الشاشة.

استيراد التطبيق إلى "استوديو Android"

ابدأ باستيراد تطبيق Starter إلى "استوديو Android".

انتقل إلى "استوديو Android"، واختَر استيراد مشروع (Gradle أو Eclipse ADT وغير ذلك) واختَر المجلد starter من رمز المصدر الذي نزّلته في السابق.

7c0f27882a2698ac.png

تشغيل تطبيق إجراء التفعيل

الآن بعد أن قمت باستيراد المشروع إلى Android Studio، أنت مستعد لتشغيل التطبيق للمرة الأولى. يمكنك توصيل جهاز Android عبر USB بالمضيف أو بدء محاكي Android Studio والنقر على تشغيل ( تنفيذ) في شريط أدوات Android Studio.

(في حال إيقاف هذا الزر، تأكّد من استيراد Start/app/build.gradle فقط، وليس المستودع بالكامل).

من المفترض أن يتم إطلاق التطبيق على جهازك الذي يعمل بنظام التشغيل Android. وهو يحتوي فعلاً على إمكانية الكشف عن الأغراض: اكتشاف سلع الأزياء من الصورة وإظهار مكانها. يُرجى محاولة إضافة الصور المعدّة مسبقًا للتأكيد.

c6102a808fdfcb11.png

لقطة شاشة لتطبيق المبتدئين الذي يمكنه اكتشاف العناصر في الصورة

بعد ذلك، يمكنك توسيع التطبيق لإرسال العناصر التي تم اكتشافها إلى خلفية Vision API Product Search وعرض نتائج البحث على الشاشة.

4. تحديد اسم الكائن

السماح للمستخدمين بالنقر على عنصر تم اكتشافه لاختياره

والآن، ستضيف رمزًا للسماح للمستخدمين باختيار كائن من الصورة وبدء البحث عن المنتج. يمكن للتطبيق في وقت سابق رصد العناصر الظاهرة في الصورة. من الممكن أن تكون هناك كائنات متعددة في الصورة، أو أن العنصر الذي تم رصده لا يشغل سوى جزء صغير من الصورة. لذلك، يجب أن تطلب من المستخدم النقر على أحد العناصر التي تم اكتشافها لتوضيح العنصر الذي يريد استخدامه للبحث عن المنتجات.

9cdfcead6d95a87.png

لقطة شاشة لسلع الأزياء التي تم رصدها في الصورة

للحفاظ على بساطة الدرس التطبيقي والتركيز على تعلُّم الآلة، تم تنفيذ بعض رموز Android النموذجية في تطبيق "مساعد Google" لمساعدتك على اكتشاف العنصر الذي نقر عليه المستخدم. الملف الشخصي الذي يعرض الصورة في النشاط الرئيسي (ObjectDetectorActivity) هو في الواقع طريقة عرض مخصّصة (ImageClickableView) تعمل على تمديد ImageView التلقائي لنظام التشغيل Android. وتنفّذ بعض الطرق البديلة المناسبة، بما في ذلك:

  • fun setOnObjectClickListener(listener: ((objectImage: Bitmap) -> Unit)) هذه رسالة استدعاء لاستلام الصورة التي تم اقتصاصها والتي تحتوي فقط على العنصر الذي نقر عليه المستخدم. سترسل هذه الصورة التي تم اقتصاصها إلى خلفية البحث عن المنتجات.

يمكنك إضافة رمز للتعامل مع مستخدم ينقر على العناصر التي تم رصدها.

انتقِل إلى طريقة initViews في الصف ObjectDetectorActivity وأضِف هذه الأسطر في نهاية هذه الطريقة: (سيخبرك "استوديو Android" بأنه لا يمكن العثور على طريقة startProductImageSearch . لا داعي للقلق، ستنفّذه بعد ذلك بقليل.)

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

يتم استدعاء onObjectClickListener عندما ينقر المستخدم على أي من العناصر التي تم اكتشافها على الشاشة. يتلقى الصورة التي تم اقتصاصها التي تحتوي على العنصر المحدد فقط. على سبيل المثال، إذا نقر المستخدم على المستخدم الذي يرتدي الفستان على اليسار، سيتم تشغيل المستمع مع objectImage كما يلي.

9cac8458d0f326e6.png

مثال على الصورة التي تم اقتصاصها وتمريرها إلى onObjectClickListener

إرسال الصورة التي تم اقتصاصها إلى نشاط البحث عن المنتجات

عليك الآن تنفيذ منطق إرسال صورة طلب البحث إلى خلفية منتج Product API في نشاط منفصل (ProductSearchActivity).

تم تنفيذ جميع مكوّنات واجهة المستخدم مسبقًا حتى تتمكّن من التركيز على كتابة الرمز للتواصل مع خلفية البحث عن المنتجات.

25939f5a13eeb3c3.png

لقطة شاشة لمكونات واجهة المستخدم في ProductSearchActivity

يمكنك إضافة رمز لإرسال صورة الكائن التي اختارها المستخدم إلى ProductSearchActivity.

ارجع إلى "استوديو Android" وأضِف طريقة 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)
    }
}

ينفّذ مقتطف الرمز 3 أمور:

  • تلتقط الصورة التي تم اقتصاصها ويتسلسلها إلى ملف بتنسيق PNG.
  • تبدأ ProductSearchActivity لتنفيذ تسلسل البحث عن المنتج.
  • يتضمّن معرّف الموارد المنتظم (URI) الذي تم اقتصاصه في هدف بدء النشاط حتى يتمكّن ProductSearchActivity من استرداده لاحقًا لاستخدامه كصورة طلب البحث.

وهناك بضعة أمور يجب وضعها في الاعتبار:

  • تم تقسيم منطق اكتشاف الكائنات وطلب البحث في الخلفية إلى نشاطَين فقط لتسهيل فهم الدرس التطبيقي حول الترميز. لك مطلق الحرية في تحديد كيفية تطبيقها في تطبيقك.
  • يجب كتابة صورة طلب البحث في ملف وتمرير معرّف الموارد المنتظم (URI) للصورة بين الأنشطة لأن صورة طلب البحث يمكن أن تكون أكبر من الحد المسموح به للحجم وهو 1 ميغابايت في هدف Android.
  • يمكنك تخزين صورة طلب البحث في 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".

بعد تحميل التطبيق، انقر على أي صور تم إعدادها مسبقًا واختَر أحد العناصر التي تم اكتشافها.

تأكّد من ظهور ProductSearchActivity مع الصورة التي نقرت عليها. لا ينفّذ الزر بحث أي إجراء حتى الآن ولكننا سنفعله بعد ذلك.

fed40f81b8b43801.png

من المفترَض أن تظهر شاشة مشابهة بعد النقر على أحد العناصر التي تم رصدها.

5. استكشاف خلفية البحث عن المنتجات

إنشاء خلفية البحث عن صورة المنتج

يتطلّب هذا الدرس التطبيقي حول الترميز واجهة خلفية للبحث عن المنتجات تمّ إنشاؤها باستخدام Vision API Product Search. وهناك خياران لتحقيق ذلك:

الخيار 1: استخدام الخلفية التجريبية التي تم نشرها لك

يمكنك المتابعة في هذا الدرس التطبيقي باستخدام الرموز الخلفية للبحث عن المنتجات التي سبق أن نشرتها Google لك. يمكن نسخ خلفية العرض التوضيحي من خلال اتباع Quickstart للبحث السريع عن منتجات واجهة برمجة التطبيقات Vision API.

الخيار الثاني: إنشاء خلفية لك من خلال اتّباع البدء السريع للبحث عن منتجات واجهة برمجة التطبيقات Vision API

ننصح باستخدام هذا الخيار للمستخدمين الذين يريدون الحصول على معلومات تفصيلية حول كيفية إنشاء خلفية عملية البحث عن المنتج بحيث يمكنك إنشاء قائمة لكتالوج منتجاتك لاحقًا. أنت بحاجة إلى:

  • حساب Google Cloud مع تفعيل الفوترة. (يمكن أن يكون حساب فترة تجريبية مجانية.)
  • بعض المعلومات عن مفاهيم Google Cloud، بما في ذلك المشاريع وحسابات الخدمة وغيرها.

يمكنك التعرّف على كيفية إجراء ذلك لاحقًا في مسار التعلّم.

التعرّف على المفاهيم المهمة

ستصادف هذه المفاهيم عند التفاعل مع خلفية البحث عن المنتجات:

  • مجموعة المنتجات: مجموعة المنتجات هي حاوية بسيطة لمجموعة من المنتجات. يمكن تمثيل كتالوج المنتج كمجموعة منتجات ومنتجاتها.
  • المنتج: بعد إنشاء مجموعة منتجات، يمكنك إنشاء منتجات وإضافتها إلى مجموعة المنتجات.
  • صور مرجعية للمنتج: هي صور تحتوي على طرق عرض مختلفة لمنتجاتك. تُستخدم الصور المرجعية للبحث عن المنتجات المشابهة بصريًا.
  • البحث عن المنتجات: بعد إنشاء مجموعة المنتجات وتمت فهرسة مجموعة المنتجات، يمكنك طلب البحث عن مجموعة المنتجات باستخدام واجهة برمجة تطبيقات Cloud Vision.

فهم كتالوج المنتجات المُعدّ مسبقًا

تم إنشاء الخلفية التوضيحية للبحث عن المنتج المستخدمة في هذا الدرس التطبيقي باستخدام بحث المنتجات في واجهة برمجة التطبيقات Vision API وكتالوج المنتجات يضم مائة صورة لحذاء تقريبًا بالإضافة إلى صورة فستان. إليك بعض الصور من الكتالوج:

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

أمثلة من كتالوج المنتج المعدّ مسبقًا

استدعاء الخلفية التجريبية للبحث عن المنتجات

يمكنك استدعاء Vision API Product Search مباشرةً من تطبيق متوافق مع الأجهزة الجوّالة من خلال إعداد مفتاح Google Cloud API وقصر الوصول إلى مفتاح واجهة برمجة التطبيقات على تطبيقك فقط.

لتبسيط هذه الدروس التطبيقية، تم إعداد نقطة نهاية خادم وكيل تتيح لك الوصول إلى الخلفية التجريبية بدون القلق بشأن مفتاح واجهة برمجة التطبيقات والمصادقة. وتتلقّى طلب HTTP من التطبيق المتوافق مع الأجهزة الجوّالة وتُلحِق مفتاح واجهة برمجة التطبيقات، ثم تُعيد توجيه الطلب إلى خلفية منتج Product API في الخلفية. بعد ذلك، يتلقى الخادم الوكيل الاستجابة من الخلفية ويعيدها إلى التطبيق المتوافق مع الأجهزة الجوّالة.

في هذا الدرس التطبيقي حول الترميز، ستستخدم تذكرتين لواجهة برمجة التطبيقات للبحث عن منتج واجهة برمجة التطبيقات Vision API:

  • projects.locations.images.annotate: يتم إرسال صورة طلب البحث إلى الخادم وتلقّي قائمة منتجات من كتالوج منتجات تم إعداده مسبقًا يكون مشابهًا لصورة طلب البحث.
  • projects.locations.products.referenceImages.get: الحصول على معرفات الموارد المنتظمة (URI) لصور المنتجات المعروضة في طلب البيانات من واجهة برمجة التطبيقات أعلاه لعرضها للمستخدمين.

6- تنفيذ عميل واجهة برمجة التطبيقات

فهم خطوات عمل البحث عن المنتجات

اتّبِع خطوات العمل هذه لإجراء بحث عن المنتجات في الخلفية:

  • ترميز صورة طلب البحث كسلسلة base64
  • طلب نقطة نهاية projects.locations.images.annotate مع صورة طلب البحث
  • يمكنك تلقّي معرّفات صور المنتجات من طلب البيانات السابق من واجهة برمجة التطبيقات وإرسالها إلى نقاط نهاية projects.locations.products.referenceImages.get للحصول على معرّفات الموارد المنتظمة (URI) لصور المنتج في نتيجة البحث.

تنفيذ فئة عميل واجهة برمجة التطبيقات

والآن، ستنفِّذ رمزًا للاتصال بخلفية البحث عن المنتجات في صف مخصّص باسم 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. أثناء المتابعة في خلفية العرض التوضيحي، اضبط هذه القيمة على نقطة نهاية الخادم الوكيل. ولكن في حال نشر خلفيتك، عليك تغييرها إلى نقطة نهاية واجهة برمجة التطبيقات في Cloud Vision. https://vision.googleapis.com/v1.
  • VISION_API_KEY هو مفتاح واجهة برمجة التطبيقات في Cloud Project. نظرًا لأن الخادم الوكيل يعالج عملية المصادقة فعلاً، يمكنك ترك هذا الحقل فارغًا.
  • VISION_API_PROJECT_ID هو رقم تعريف مشروع Cloud. odml-codelabs هو المشروع على السحابة الإلكترونية حيث يتم نشر الخلفية التجريبية.
  • VISION_API_LOCATION_ID هو موقع السحابة الإلكترونية الذي يتم فيه نشر خلفية البحث عن المنتجات. us-east1 هي المكان الذي نشرنا فيه الخلفية التجريبية.
  • VISION_API_PRODUCT_SET_ID هو معرّف كتالوج المنتج (المعروف أيضًا باسم "معرّف مجموعة المنتجات" في عبارة واجهة برمجة التطبيقات Vision API) الذي تريد البحث عن منتجات مشابهة بصريًا فيه. يمكنك الحصول على كتالوجات متعددة في مشروع واحد على السحابة الإلكترونية. product_set0 هو كتالوج المنتج المُعدّ مسبقًا للخلفية التجريبية.

7- الاتصال بواجهة برمجة تطبيقات البحث عن المنتجات

استكشاف طلب البيانات من واجهة برمجة التطبيقات وتنسيق الاستجابة

يمكنك العثور على منتجات مشابهة لصورة معيّنة من خلال تمرير معرِّف الموارد المنتظم (URI) الخاص بخدمة Google Cloud Storage أو عنوان URL على الويب أو السلسلة base64 المشفّرة إلى Vision API Product Search. في هذا الدرس التطبيقي حول الترميز، ستستخدم خيار السلسلة المشفّرة base64، لأن صورة طلب البحث تتوفّر فقط على جهاز المستخدم.

عليك إرسال طلب POST إلى نقطة نهاية projects.locations.images.annotate مع نص JSON هذا للطلب:

{
  "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: رقم تعريف مشروع Google Cloud Platform.
  • location-id: معرّف موقع جغرافي صالح.
  • product-set-id: معرّف مجموعة المنتجات التي تريد تشغيل العملية عليها.

بما أنّ كتالوج المنتج يحتوي على صور للأحذية والملابس فقط، حدِّد سمات productcategory (فئات المنتجات) لتكون apparel-v2. ويعني الإصدار 2 هنا أننا نستخدم الإصدار 2 من نموذج تعلُّم الآلة للبحث عن منتجات الملابس.

إذا نجح الطلب، يعرض الخادم رمز حالة HTTP 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 للحصول على عنوان URL لهذه الصورة المرجعية حتى يتم عرضه على الشاشة.
  • 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". بعد تحميل التطبيق، انقر على أي صور تم إعدادها مسبقًا واختَر كائنًا تم التعرّف عليه ثم انقر على الزر بحث واطّلِع على نتائج البحث التي يتم عرضها من الخلفية. ستظهر لك رسالة كالتالية:

bb5e7c27c283a2fe.png

لقطة شاشة لشاشة نتيجة البحث عن منتج

تعرض الواجهة الخلفية قائمة بالمنتجات المشابهة بصريًا من كتالوج المنتجات المعد مسبقًا. ومع ذلك، يمكنك ملاحظة أنّ صورة المنتج لا تزال فارغة. ويرجع ذلك إلى أن نقطة نهاية projects.locations.images.annotate لا تعرض سوى معرّفات صور المنتجات مثل projects/odml-codelabs/locations/us-east1/products/product_id77/referenceImages/image77. عليك إجراء طلب آخر لواجهة برمجة التطبيقات إلى نقطة نهاية projects.locations.products.referenceImages.get والحصول على عنوان URL لهذه الصورة المرجعية لعرضها على الشاشة.

8- الحصول على الصور المرجعية للمنتج

استكشاف طلب البيانات من واجهة برمجة التطبيقات وتنسيق الاستجابة

يجب إرسال طلب استرداد بيانات باستخدام GET HTTP مع نص طلب فارغ إلى نقطة نهاية projects.locations.reference.getImages.get للحصول على معرفات الموارد المنتظمة (URI) لصور المنتج التي تعرضها نقطة نهاية البحث عن المنتج.

ويبدو طلب HTTP على النحو التالي:

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

إذا نجح الطلب، يعرض الخادم رمز حالة HTTP لـ 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: معرف الموارد المنتظم (URI) للصورة في Google Cloud Storage (GCS)

تم إعداد الصور المرجعية لخلفية البحث عن المنتجات التجريبية بحيث تحصل على إذن بالقراءة بشكل علني. لذلك، يمكنك بسهولة تحويل معرف الموارد المنتظم (URI) لـ GCS إلى عنوان URL يستخدم HTTP وعرضه على واجهة مستخدم التطبيق. ما عليك سوى استبدال البادئة gs:// بـ https://storage.googleapis.com/.

تنفيذ طلب البيانات من واجهة برمجة التطبيقات

بعد ذلك، أنشئ طلب بحث في واجهة برمجة التطبيقات للمنتج وأرسله إلى الخلفية. لن تحتاج إلى استخدام فولي وواجهة برمجة تطبيقات المهام بشكل مماثل لطلب واجهة برمجة تطبيقات البحث عن المنتجات.

ارجع إلى الصف 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. يجب استدعاء نقطة نهاية الصورة المرجعية للحصول على معرف الموارد المنتظم (URI) لـ GCS للصورة المرجعية.
  2. لتحويل معرف الموارد المنتظم (URI) لـ GCS إلى عنوان URL يستخدم HTTP.
  3. يتم تحديث الخاصية httpUri للعنصر searchResult باستخدام عنوان URL الذي يستخدم HTTP.

ربط طلبي واجهة برمجة التطبيقات

ارجع إلى annotateImage وعدّله للحصول على جميع الصور المرجعية&#39؛ وعناوين URL التي تستخدم HTTP قبل عرض قائمة 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". بعد تحميل التطبيق، انقر على أي صور تم إعدادها مسبقًا، واختَر كائنًا تم اكتشافه، ثم انقر على الزر بحث لعرض نتائج البحث هذه المرة مع صور المنتج.

هل نتائج البحث عن منتجات مفيدة بالنسبة إليك؟

25939f5a13eeb3c3.png

9- تهانينا.

لقد تعلمت كيفية الاتصال بواجهة برمجة تطبيقات البحث عن المنتجات في Vision API لإضافة إمكانية البحث عن صورة المنتج إلى تطبيقك المتوافق مع Android. هذا كل ما تحتاج إليه لإعداد هذه الأداة وتشغيلها.

أثناء المتابعة، قد ترغب في إنشاء خلفية لك باستخدام كتالوج منتجاتك. يمكنك الاطّلاع على الدرس التطبيقي التالي حول الترميز في مسار التعلّم بحث صور المنتجات للتعرّف على كيفية إنشاء خلفيتك الخاصة وإعداد مفتاح واجهة برمجة التطبيقات لطلبها من تطبيق متوافق مع الأجهزة الجوّالة.

المواضيع التي تناولناها

  • كيفية استدعاء خلفية منتج Product API من تطبيق Android

الخطوات التالية

مزيد من المعلومات