1. قبل البدء
هل شاهدت العرض التوضيحي لتطبيق "عدسة Google" الذي يتيح لك توجيه كاميرا هاتفك إلى منتج معيّن والعثور على الأماكن التي يمكنك شراؤه منها على الإنترنت؟ إذا كنت تريد معرفة كيفية إضافة الميزة نفسها إلى تطبيقك، فهذا الدرس التطبيقي حول الترميز مناسب لك. وهي جزء من مسار تعليمي يعلّمك كيفية إنشاء ميزة بحث عن صور المنتجات في تطبيق على الأجهزة الجوّالة.
في هذا الدرس التطبيقي حول الترميز، ستتعلّم كيفية طلب بيانات من خادم الخلفية الذي تم إنشاؤه باستخدام Vision API Product Search من تطبيق على الأجهزة الجوّالة. يمكن لخادم الخلفية هذا تلقّي صورة طلب بحث والبحث عن منتجات مشابهة بصريًا من كتالوج المنتجات.
يمكنك التعرّف على الخطوات المتبقية لإنشاء ميزة البحث المرئي عن المنتجات، بما في ذلك كيفية استخدام ميزة "رصد العناصر وتتبُّعها" في ML Kit لرصد العناصر في صورة طلب البحث والسماح للمستخدمين باختيار المنتج الذي يريدون البحث عنه، وذلك في مسار التعلّم.
ما ستنشئه
|
ما ستتعرّف عليه
- كيفية طلب الردود وتحليلها من واجهات برمجة التطبيقات Vision API Product Search في تطبيق Android
المتطلبات
- إصدار حديث من "استوديو Android" (الإصدار 4.1.2 أو إصدار أحدث)
- محاكي Android Studio أو جهاز Android فعلي
- الرمز النموذجي
- معرفة أساسية بتطوير تطبيقات Android باستخدام لغة Kotlin
يركّز هذا الدرس التطبيقي حول الترميز على ميزة "البحث عن المنتجات" في Vision API. لا يتم استكشاف المفاهيم وكتل الرموز البرمجية غير ذات الصلة، بل يتم توفيرها لك لنسخها ولصقها ببساطة.
2. لمحة عن ميزة "البحث في منتجات Vision"
Vision API Product Search هي ميزة في Google Cloud تتيح للمستخدمين البحث عن منتجات مشابهة بصريًا من كتالوج منتجات. يمكن لتجّار التجزئة إنشاء منتجات يحتوي كل منها على صور مرجعية تصف المنتج بصريًا من مجموعة من وجهات النظر. يمكنك بعد ذلك إضافة هذه المنتجات إلى مجموعات المنتجات (أي كتالوج المنتجات). تتيح خدمة Vision API Product Search حاليًا فئات المنتجات التالية: الأدوات المنزلية والملابس والألعاب والسلع المعبّأة والعامة.
عندما يبحث المستخدمون عن مجموعة المنتجات باستخدام صورهم الخاصة، تستخدم ميزة "البحث عن المنتجات" في Vision API تكنولوجيا تعلُّم الآلة لمقارنة المنتج في صورة طلب البحث التي يقدّمها المستخدم بالصور في مجموعة المنتجات الخاصة ببائع التجزئة، ثم تعرض قائمة مرتّبة بالنتائج المشابهة بصريًا ودلاليًا.
3- تنزيل تطبيق البداية وتشغيله
تنزيل الرمز
انقر على الرابط التالي لتنزيل كل الرموز البرمجية لهذا الدرس العملي:
فكّ ضغط ملف ZIP الذي تم تنزيله. سيؤدي ذلك إلى فك حزمة مجلد رئيسي (odml-pathways-main
) يحتوي على جميع الموارد التي ستحتاج إليها. في هذا الدرس العملي، لن تحتاج إلا إلى المصادر في الدليل الفرعي product-search/codelab2/android
.
يحتوي الدليل الفرعي codelab2
في مستودع odml-pathways
على دليلَين:
الرمز الأوّلي: الرمز الأوّلي الذي ستستند إليه في هذا الدرس التطبيقي حول الترميز.
final: رمز مكتمل لتطبيق العيّنة النهائي
التطبيق المبدئي هنا هو التطبيق الذي أنشأته في الدرس التطبيقي رصد العناصر في الصور لإنشاء بحث مرئي عن المنتجات: Android. يستخدم هذا التطبيق ميزة "رصد الأجسام وتتبُّعها" في ML Kit لرصد الأجسام من صورة وعرضها على الشاشة.
استيراد التطبيق إلى "استوديو Android"
ابدأ باستيراد تطبيق البدء إلى Android Studio.
انتقِل إلى "استوديو Android"، وانقر على استيراد مشروع (Gradle وEclipse ADT وما إلى ذلك) (Import Project (Gradle, Eclipse ADT, etc.))، ثم اختَر مجلد starter
من رمز المصدر الذي نزّلته سابقًا.
تشغيل تطبيق المبتدئين
بعد استيراد المشروع إلى "استوديو Android"، يمكنك تشغيل التطبيق للمرة الأولى. وصِّل جهاز Android بجهازك المضيف عبر USB أو ابدأ محاكي "استوديو Android"، ثم انقر على تشغيل ( ) في شريط أدوات "استوديو Android".
(إذا كان هذا الزر غير مفعّل، تأكَّد من استيراد الملف starter/app/build.gradle فقط، وليس المستودع بأكمله.)
من المفترض أن يكون التطبيق قد تم تشغيله الآن على جهاز Android. يتضمّن التطبيق حاليًا ميزة رصد الأجسام، أي رصد قطع الملابس من الصورة وعرض أماكن توفّرها. جرِّب استخدام الصور المُعدّة مسبقًا لتأكيد الحساب.
لقطة شاشة للتطبيق المبدئي الذي يمكنه رصد العناصر في صورة
بعد ذلك، ستوسّع نطاق التطبيق لإرسال العناصر التي تم رصدها إلى الخلفية الخاصة بخدمة "بحث المنتجات" في Vision API وعرض نتائج البحث على الشاشة.
4. التعامل مع اختيار العناصر
السماح للمستخدمين بالنقر على عنصر تم رصده لتحديده
ستضيف الآن رمزًا برمجيًا للسماح للمستخدمين باختيار عنصر من الصورة وبدء البحث عن المنتج. يتضمّن التطبيق المبدئي إمكانية رصد العناصر في الصورة. من المحتمل أن تكون هناك عناصر متعددة في الصورة، أو أنّ العنصر الذي تم رصده يشغل جزءًا صغيرًا فقط من الصورة. لذلك، عليك أن تطلب من المستخدم النقر على أحد العناصر التي تم رصدها لتحديد العنصر الذي يريد استخدامه للبحث عن المنتج.
لقطة شاشة لملابس تم رصدها من الصورة
لإبقاء الدرس التطبيقي حول الترميز بسيطًا ومركّزًا على التعلّم الآلي، تم تنفيذ بعض رموز Android النموذجية في تطبيق البداية لمساعدتك في رصد العنصر الذي نقر عليه المستخدم. إنّ طريقة العرض التي تعرض الصورة في النشاط الرئيسي (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
كما هو موضّح أدناه.
مثال على الصورة التي تم اقتصاصها والتي تم تمريرها إلى onObjectClickListener
إرسال الصورة التي تم اقتصاصها إلى نشاط البحث عن المنتجات
الآن، عليك تنفيذ منطق إرسال صورة طلب البحث إلى الخلفية الخاصة بميزة "البحث عن المنتجات" في Vision API في نشاط منفصل (ProductSearchActivity
).
تم تنفيذ جميع مكوّنات واجهة المستخدم مسبقًا حتى تتمكّن من التركيز على كتابة الرمز البرمجي للتواصل مع الخلفية الخاصة بالبحث عن المنتجات.
لقطة شاشة لعناصر واجهة المستخدم في 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)
}
}
ينفّذ مقتطف الرمز 3 إجراءات:
- يأخذ الصورة التي تم اقتصاصها ويحوّلها إلى ملف PNG.
- يبدأ
ProductSearchActivity
لتنفيذ تسلسل البحث عن المنتجات. - يتضمّن معرّف الموارد المنتظم (URI) للصورة التي تم اقتصاصها في هدف بدء النشاط حتى يتمكّن
ProductSearchActivity
من استردادها لاحقًا لاستخدامها كصورة طلب البحث.
في ما يلي بعض النقاط التي يجب أخذها بعين الاعتبار:
- تم تقسيم منطق رصد العناصر وإرسال طلبات البحث إلى الخلفية إلى نشاطَين فقط لتسهيل فهم الدرس العملي. ويعود إليك تحديد كيفية تنفيذها في تطبيقك.
- عليك كتابة صورة طلب البحث في ملف وتمرير معرّف الموارد المنتظم (URI) للصورة بين الأنشطة لأنّ حجم صورة طلب البحث يمكن أن يكون أكبر من الحدّ الأقصى لحجم Android intent البالغ 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".
بعد تحميل التطبيق، انقر على أي من الصور المضبوطة مسبقًا، ثم اختَر أحد العناصر التي تم رصدها.
تأكَّد من ظهور ProductSearchActivity
مع الصورة التي نقرت عليها. لا يؤدي زر البحث أي إجراء بعد، ولكننا سنضيف هذه الوظيفة في الخطوة التالية.
من المفترض أن تظهر لك شاشة مشابهة بعد النقر على أحد العناصر التي تم رصدها.
5- استكشاف الواجهة الخلفية للبحث عن المنتجات
إنشاء الخلفية الخاصة بميزة البحث عن صور المنتجات
يتطلّب هذا الدرس التطبيقي حول الترميز نظامًا خلفيًا للبحث عن المنتجات تم إنشاؤه باستخدام Vision API Product Search. تتوفّر طريقتان لتنفيذ هذا الإجراء:
الخيار 1: استخدام الخلفية التجريبية التي تم نشرها لك
يمكنك مواصلة هذا الدرس العملي باستخدام الخلفية التي سبق أن نشرتها Google للبحث عن المنتجات. يمكن تكرار الخلفية التجريبية باتّباع دليل البدء السريع الخاص بخدمة "البحث عن المنتجات" في Vision API.
الخيار 2: إنشاء الخلفية الخاصة بك باتّباع دليل البدء السريع الخاص بميزة "البحث عن المنتجات" في Vision API
ننصح بهذا الخيار المستخدمين الذين يريدون التعرّف بشكل معمّق على كيفية إنشاء نظام خلفي للبحث عن المنتجات، ما يتيح لهم إنشاء نظام مماثل خاص بكتالوج منتجاتهم لاحقًا. أنت بحاجة إلى:
- حساب على Google Cloud تم تفعيل الفوترة فيه (يمكن أن يكون حسابًا تجريبيًا مجانيًا).
- معرفة بعض مفاهيم Google Cloud، بما في ذلك المشاريع وحسابات الخدمة وما إلى ذلك
يمكنك الاطّلاع على كيفية إجراء ذلك لاحقًا في مسار التعلّم.
التعرّف على المفاهيم المهمة
ستصادف هذه المفاهيم عند التفاعل مع الخلفية الخاصة بالبحث عن المنتجات:
- مجموعة المنتجات: مجموعة المنتجات هي حاوية بسيطة لمجموعة من المنتجات. يمكن تمثيل كتالوج المنتجات كمجموعة منتجات ومنتجاتها.
- المنتج: بعد إنشاء مجموعة منتجات، يمكنك إنشاء منتجات وإضافتها إلى مجموعة المنتجات.
- الصور المرجعية للمنتج: هي صور تحتوي على طرق عرض مختلفة لمنتجاتك. تُستخدَم الصور المرجعية للبحث عن منتجات مشابهة من حيث الشكل.
- البحث عن المنتجات: بعد إنشاء مجموعة المنتجات وفهرستها، يمكنك طلب البحث في مجموعة المنتجات باستخدام Cloud Vision API.
التعرّف على كتالوج المنتجات المُعدّ مسبقًا
تم إنشاء الخلفية التجريبية لعملية البحث عن المنتجات المستخدَمة في هذا الدرس التطبيقي حول الترميز باستخدام Vision API Product Search وكتالوج منتجات يضمّ حوالي مئة صورة لأحذية وفساتين. في ما يلي بعض الصور من الكتالوج:
أمثلة من كتالوج المنتجات المُعدّ مسبقًا
استدعاء الخلفية للعرض التوضيحي الخاص بالبحث عن المنتجات
يمكنك طلب Vision API Product Search مباشرةً من تطبيق على الأجهزة الجوّالة من خلال إعداد مفتاح Google Cloud API وحصر الوصول إلى مفتاح واجهة برمجة التطبيقات على تطبيقك فقط.
لإبقاء هذا الدرس البرمجي بسيطًا، تم إعداد نقطة نهاية وكيل تتيح لك الوصول إلى الخلفية التجريبية بدون القلق بشأن مفتاح واجهة برمجة التطبيقات والمصادقة. يتلقّى الطلب عبر HTTP من تطبيق الأجهزة الجوّالة، ويضيف مفتاح واجهة برمجة التطبيقات، ثم يعيد توجيه الطلب إلى الخلفية الخاصة بـ Vision API Product Search. بعد ذلك، يتلقّى الخادم الوكيل الردّ من الخلفية ويعيده إلى تطبيق الأجهزة الجوّالة.
- نقطة نهاية الخادم الوكيل:
https://us-central1-odml-codelabs.cloudfunctions.net/productSearch
- سلوك الخادم الوكيل: أضِف عنوان مصادقة مناسبًا وأعِد توجيه طلبات البيانات من واجهة برمجة التطبيقات إلى الخلفية الخاصة بـ Vision API Product Search. على سبيل المثال، سيتم إعادة توجيه طلب إلى واجهة برمجة التطبيقات
https://us-central1-odml-codelabs.cloudfunctions.net/productSearch/images:annotate
إلىhttps://vision.googleapis.com/v1/images:annotate
في هذا الدرس التطبيقي حول الترميز، ستستخدم واجهتَي برمجة تطبيقات من 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.
تحديد إعدادات واجهة برمجة التطبيقات
انتقِل إلى فئة 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 هو مفتاح واجهة برمجة التطبيقات لمشروعك على السحابة الإلكترونية. بما أنّ الخادم الوكيل يتعامل مع المصادقة، يمكنك ترك هذا الحقل فارغًا.
- VISION_API_PROJECT_ID هو رقم تعريف مشروع Cloud.
odml-codelabs
هو مشروع Google Cloud الذي يتم فيه نشر الخلفية التجريبية. - VISION_API_LOCATION_ID هو موقع Cloud الجغرافي الذي يتم فيه نشر الخلفية الخاصة بالبحث عن المنتجات.
us-east1
هو المكان الذي نشرنا فيه الخلفية التجريبية. - VISION_API_PRODUCT_SET_ID هو معرّف كتالوج المنتجات (المعروف أيضًا باسم "مجموعة المنتجات" في مصطلح Vision API) الذي تريد البحث فيه عن منتجات مشابهة بصريًا. يمكنك الحصول على عدة كتالوجات في مشروع واحد على السحابة الإلكترونية.
product_set0
هو كتالوج المنتجات المُعدّ مسبقًا في الخلفية التجريبية.
7. استدعاء واجهة برمجة التطبيقات للبحث عن المنتجات
استكشاف تنسيق طلب البيانات من واجهة برمجة التطبيقات وردّها
يمكنك العثور على منتجات مشابهة لصورة معيّنة من خلال تمرير معرّف URI الخاص بالصورة في Google Cloud Storage أو عنوان URL على الويب أو سلسلة مشفّرة base64 إلى ميزة "البحث عن المنتجات" في Vision API. في هذا الدرس العملي، ستستخدم خيار السلسلة المشفرة 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 برقم تعريف مجموعة المنتجات التي تريد تنفيذ العملية عليها.
بما أنّ كتالوج المنتجات لا يحتوي إلا على صور أحذية وفساتين، حدِّد productCategories على أنّه apparel-v2
. يشير v2 هنا إلى أنّنا نستخدم الإصدار 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". بعد تحميل التطبيق، انقر على أي من الصور المُعدّة مسبقًا، واختَر أحد العناصر التي تم رصدها، ثم انقر على زر بحث واطّلِع على نتائج البحث التي تم إرجاعها من الخلفية. سيظهر لك ما يلي:
لقطة شاشة لصفحة نتائج البحث عن المنتج
يعرض الخلفية حاليًا قائمة بالمنتجات المشابهة ظاهريًا من كتالوج المنتجات المُعدّ مسبقًا. ومع ذلك، يمكنك ملاحظة أنّ صورة المنتج لا تزال فارغة. ذلك لأنّ نقطة النهاية 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.products.referenceImages.get للحصول على معرّفات الموارد الموحّدة لصور المنتجات التي تعرضها نقطة نهاية البحث عن المنتجات.
يبدو طلب 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) في "خدمة التخزين السحابي من Google" إلى عنوان URL بتنسيق HTTP وعرضه على واجهة مستخدم التطبيق. ما عليك سوى استبدال البادئة 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
تم إرجاعه من نقطة نهاية البحث عن المنتجات، ثم تتّبع الخطوات التالية:
- يتم استدعاء نقطة نهاية الصورة المرجعية للحصول على معرّف الموارد المنتظم (URI) الخاص بالصورة المرجعية في "خدمة التخزين السحابي من Google".
- تحويل معرّف الموارد المنتظم (URI) الخاص بخدمة "التخزين السحابي من Google" إلى عنوان URL بتنسيق HTTP
- تعدّل هذه السمة
httpUri
الكائنsearchResult
باستخدام عنوان URL الخاص ببروتوكول HTTP.
ربط طلبَي البيانات من واجهة برمجة التطبيقات
ارجع إلى annotateImage
وعدِّله للحصول على جميع عناوين 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". بعد تحميل التطبيق، انقر على أي من الصور المضبوطة مسبقًا، ثم اختَر أحد العناصر التي تم رصدها، وانقر على زر بحث للاطّلاع على نتائج البحث، ولكن هذه المرة مع صور المنتجات.
هل نتائج البحث عن المنتجات منطقية بالنسبة إليك؟
9- تهانينا!
لقد تعلّمت كيفية طلب بيانات من الخلفية في Vision API Product Search لإضافة إمكانية البحث عن صور المنتجات إلى تطبيق Android. هذا كل ما تحتاج إليه لتشغيل التطبيق.
أثناء المتابعة، قد تحتاج إلى إنشاء الخلفية الخاصة بك باستخدام كتالوج المنتجات. يمكنك الاطّلاع على الدرس التطبيقي التالي حول الترميز في المسار التعليمي البحث عن صور المنتجات لمعرفة كيفية إنشاء الخلفية الخاصة بك وإعداد مفتاح واجهة برمجة التطبيقات لاستدعائها من تطبيق على الأجهزة الجوّالة.
المواضيع التي تناولناها
- كيفية طلب بيانات من الخلفية الخاصة بخدمة "البحث عن المنتجات" في Vision API من تطبيق Android
الخطوات التالية
- يمكنك الاطّلاع على الدرس التطبيقي إنشاء خلفية للبحث عن صور المنتجات باستخدام Vision API Product Search للتعرّف على كيفية إنشاء الخلفية الخاصة بك.
- يمكنك الاطّلاع على مسارات التعلّم الأخرى في موقع "تعلُّم الآلة على الجهاز فقط" الإلكتروني.
- إنشاء ميزة البحث عن المنتجات في تطبيق Android الخاص بك