1. Прежде чем начать
Вы видели демоверсию Google Lens, где можно навести камеру телефона на объект и найти, где его можно купить онлайн? Если вы хотите узнать, как добавить такую же функцию в своё приложение, то эта лабораторная работа для вас. Она является частью обучающего курса по внедрению функции поиска по изображениям товаров в мобильное приложение.
В этой лабораторной работе вы узнаете, как вызвать бэкенд, созданный с помощью Vision API Product Search, из мобильного приложения. Этот бэкенд может принимать изображение запроса и искать визуально похожие товары из каталога.
Вы можете узнать об оставшихся этапах создания функции визуального поиска продуктов, в том числе о том, как использовать ML Kit Object Detection and Tracking для обнаружения объектов на запрашиваемом изображении и предоставить пользователям возможность выбирать, какой продукт они хотят искать, в учебном плане .
Что вы построите
|
Чему вы научитесь
- Как вызывать и анализировать ответ API поиска продуктов Vision API из приложения Android
Что вам понадобится
- Последняя версия Android Studio (v4.1.2+)
- Эмулятор Android Studio или физическое устройство Android
- Пример кода
- Базовые знания разработки Android на Kotlin
Эта практическая работа посвящена поиску продуктов Vision API. Нерелевантные концепции и блоки кода не рассматриваются и предоставляются для простого копирования и вставки.
2. О поиске продуктов Vision API
Поиск товаров Vision API — это функция Google Cloud, которая позволяет пользователям искать визуально похожие товары в каталоге. Розничные продавцы могут создавать товары, каждый из которых содержит референсные изображения, визуально описывающие товар с разных точек зрения. Затем эти товары можно добавлять в наборы товаров (например, в каталог товаров). В настоящее время поиск товаров Vision API поддерживает следующие категории товаров: товары для дома, одежда, игрушки, упакованные товары и товары общего назначения.
Когда пользователи запрашивают набор продуктов с помощью собственных изображений, Vision API Product Search применяет машинное обучение для сравнения продукта на изображении запроса пользователя с изображениями в наборе продуктов розничного продавца, а затем возвращает ранжированный список визуально и семантически схожих результатов.
3. Загрузите и запустите стартовое приложение.
Загрузить код
Чтобы загрузить весь код для этой лабораторной работы, щелкните следующую ссылку:
Распакуйте скачанный zip-архив. Будет распакована корневая папка ( odml-pathways-main
) со всеми необходимыми ресурсами. Для этой практической работы вам понадобятся только исходные коды из подкаталога product-search/codelab2/android
.
Подкаталог codelab2
в репозитории odml-pathways
содержит два каталога:
starter — начальный код, на основе которого вы будете строить эту лабораторную работу.
final — готовый код для готового примера приложения.
Стартовое приложение, которое вы создали в разделе «Обнаружение объектов на изображениях для визуального поиска товаров» (Android codelab), использует функцию обнаружения и отслеживания объектов из ML Kit для обнаружения объектов на изображениях и отображения их на экране.
Импортируйте приложение в Android Studio
Начните с импорта стартового приложения в Android Studio.
Перейдите в Android Studio, выберите «Импорт проекта» (Gradle, Eclipse ADT и т. д.) и выберите starter
папку из исходного кода, который вы скачали ранее.
Запустите стартовое приложение
Теперь, когда вы импортировали проект в Android Studio, вы готовы к первому запуску приложения. Подключите Android-устройство через USB к хосту или запустите эмулятор Android Studio и нажмите «Запустить» ( ) на панели инструментов Android Studio.
(Если эта кнопка отключена, убедитесь, что вы импортируете только starter/app/build.gradle, а не весь репозиторий.)
Теперь приложение должно запуститься на вашем Android-устройстве. Оно уже поддерживает функцию обнаружения объектов: распознаёт предметы одежды на изображении и показывает их местоположение. Для проверки попробуйте использовать предустановленные фотографии.
Скриншот стартового приложения, которое может обнаруживать объекты на изображении
Далее вы расширите возможности приложения для отправки обнаруженных объектов в бэкэнд Vision API Product Search и отображения результатов поиска на экране.
4. Выбор объекта обработки
Разрешить пользователям нажимать на обнаруженный объект, чтобы выбрать
Теперь вам нужно добавить код, который позволит пользователям выбирать объект на изображении и начинать поиск товара. Стартовое приложение уже умеет обнаруживать объекты на изображении. Возможно, на изображении присутствует несколько объектов, или обнаруженный объект занимает лишь небольшую часть изображения. Поэтому вам нужно, чтобы пользователь нажал на один из обнаруженных объектов, чтобы указать, какой объект он хочет использовать для поиска товара.
Скриншот предметов одежды, обнаруженных на изображении
Чтобы упростить кодовую лабораторию и сфокусировать её на машинном обучении, в стартовое приложение был внедрён шаблонный код Android, помогающий определить, какой объект нажал пользователь. Представление, отображающее изображение в основной активности ( ObjectDetectorActivity
), на самом деле является пользовательским представлением ( ImageClickableView
), расширяющим стандартный ImageView
ОС Android. Оно реализует несколько удобных вспомогательных методов, включая:
-
fun setOnObjectClickListener(listener: ((objectImage: Bitmap) -> Unit))
Это обратный вызов для получения обрезанного изображения, содержащего только объект, на который нажал пользователь. Вы отправите это обрезанное изображение в бэкэнд поиска товаров.
Добавьте код для обработки нажатий пользователем на обнаруженные объекты.
Перейдите к методу initViews
в классе ObjectDetectorActivity
и добавьте следующие строки в конец метода: (Android Studio сообщит вам, что не может найти метод startProductImageSearch
. Не волнуйтесь, вы реализуете его немного позже.)
// Callback received when the user taps on any of the detected objects.
ivPreview.setOnObjectClickListener { objectImage ->
startProductImageSearch(objectImage)
}
Слушатель onObjectClickListener
вызывается каждый раз, когда пользователь нажимает на любой из обнаруженных объектов на экране. Он получает обрезанное изображение, содержащее только выбранный объект. Например, если пользователь нажимает на человека в платье справа, сработает прослушиватель с objectImage
как показано ниже.
Пример обрезанного изображения, переданного в onObjectClickListener
Отправьте обрезанное изображение в поле поиска товара.
Теперь вы реализуете логику отправки запрашиваемого изображения в бэкэнд Vision API Product Search в отдельном действии ( 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)
}
}
Фрагмент кода выполняет три функции:
- Берет обрезанное изображение и сериализует его в файл 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 Studio.
После загрузки приложения нажмите на любое предустановленное изображение и выберите один из обнаруженных объектов.
Убедитесь, что действие ProductSearchActivity
отображается с изображением, на которое вы нажали. Кнопка «Поиск» пока ничего не делает, но мы добавим её в будущем.
После нажатия на один из обнаруженных объектов вы увидите аналогичный экран.
5. Изучите интерфейс поиска товаров
Создайте бэкэнд поиска изображений продукта
Для этой лабораторной работы требуется бэкенд поиска товаров, созданный с помощью Vision API Product Search . Есть два способа это реализовать:
Вариант 1: использование демонстрационной версии бэкэнда, которая была развернута для вас
Вы можете продолжить работу над этой практической работой, используя бэкенд поиска товаров, который Google уже развернул для вас. Демонстрационный бэкенд можно воспроизвести, следуя краткому руководству по поиску товаров Vision API.
Вариант 2: Создайте свой собственный бэкэнд, следуя краткому руководству по поиску продуктов Vision API
Этот вариант рекомендуется тем, кто хочет подробно изучить создание бэкэнда для поиска товаров, чтобы впоследствии создать его для своего собственного каталога. Вам потребуется:
- Учетная запись Google Cloud с включенной функцией выставления счетов. (Это может быть бесплатная пробная учетная запись.)
- Некоторые знания о концепциях Google Cloud, включая проекты, учетные записи служб и т. д.
Вы сможете узнать, как это сделать, позже в ходе обучения .
Изучите важные концепции
При взаимодействии с бэкэндом поиска товаров вы столкнетесь со следующими концепциями:
- Набор продуктов : Набор продуктов — это простой контейнер для группы продуктов. Каталог продуктов можно представить в виде набора продуктов и его продуктов.
- Продукт : После создания набора продуктов вы можете создавать продукты и добавлять их в набор продуктов.
- Изображения товаров: это изображения, содержащие различные ракурсы ваших товаров. Изображения используются для поиска визуально похожих товаров.
- Поиск продуктов : после того как вы создали набор продуктов и проиндексировали его, вы можете выполнить запрос к набору продуктов с помощью API Cloud Vision.
Понять предустановленный каталог продукции
Демонстрационная версия поиска товаров, использованная в этой лабораторной работе, была создана с использованием Vision API Product Search и каталога товаров, содержащего около сотни изображений обуви и платьев. Вот несколько изображений из каталога:
Примеры из предустановленного каталога продукции
Вызовите демонстрационную версию поиска товаров
Вы можете вызвать функцию поиска продуктов Vision API непосредственно из мобильного приложения, настроив ключ API Google Cloud и ограничив доступ к ключу API только вашим приложением.
Для упрощения этой практической работы была настроена конечная точка прокси-сервера, которая позволяет получить доступ к демонстрационному бэкенду, не беспокоясь о ключе API и аутентификации. Он получает HTTP-запрос от мобильного приложения, добавляет ключ API и перенаправляет запрос в бэкенд Vision API Product Search. Затем прокси-сервер получает ответ от бэкенда и возвращает его мобильному приложению.
- Конечная точка прокси:
https://us-central1-odml-codelabs.cloudfunctions.net/productSearch
- Поведение прокси: добавьте соответствующий заголовок аутентификации и перенаправьте запросы API в бэкенд Vision API Product Search. Например, вызов API к
https://us-central1-odml-codelabs.cloudfunctions.net/productSearch/images:annotate
будет перенаправлен наhttps://vision.googleapis.com/v1/images:annotate
В этой лабораторной работе вы будете использовать два API поиска продуктов Vision API :
- projects.locations.images.annotate : Отправка изображения запроса на сервер и получение списка продуктов из предустановленного каталога продуктов, визуально похожих на изображение запроса.
- projects.locations.products.referenceImages.get : получение URI изображений продуктов, возвращенных в вызове API выше, для отображения пользователям.
6. Реализуйте API-клиент
Понять рабочий процесс поиска продукта
Для поиска продукта с помощью бэкэнда следуйте этой схеме:
- Кодируйте изображение запроса как строку base64
- Вызовите конечную точку projects.locations.images.annotate с изображением запроса.
- Получите идентификаторы изображений продуктов из предыдущего вызова API и отправьте их в конечные точки projects.locations.products.referenceImages.get , чтобы получить URI изображений продуктов в результатах поиска.
Реализовать клиентский класс API
Теперь вам нужно реализовать код для вызова бэкэнда поиска товаров в выделенном классе ProductSearchAPIClient
. В стартовом приложении уже реализован шаблонный код:
-
class ProductSearchAPIClient
: этот класс сейчас почти пуст, но в нем есть несколько методов, которые вы реализуете позже в этой лабораторной работе. -
fun convertBitmapToBase64(bitmap: Bitmap)
: преобразует экземпляр Bitmap в его представление base64 для отправки в бэкэнд поиска товаров. -
fun annotateImage(image: Bitmap): Task<List<ProductSearchResult>>
: вызвать API projects.locations.images.annotate и проанализировать ответ. -
fun fetchReferenceImage(searchResult: ProductSearchResult): Task<ProductSearchResult>
: вызвать API projects.locations.products.referenceImages.get и проанализировать ответ. -
SearchResult.kt
: этот файл содержит несколько классов данных, представляющих типы, возвращаемые бэкэндом Vision API Product Search.
Укажите конфигурации 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 — это конечная точка API Cloud Vision. При работе с демонстрационной версией бэкенда укажите в качестве неё конечную точку прокси-сервера. Однако при развертывании собственной бэкенда необходимо указать конечную точку Cloud Vision API.
https://vision.googleapis.com/v1
. - VISION_API_KEY — это ключ API вашего облачного проекта. Поскольку прокси-сервер уже отвечает за аутентификацию, вы можете оставить это поле пустым.
- VISION_API_PROJECT_ID — идентификатор облачного проекта.
odml-codelabs
— облачный проект, в котором развернут демонстрационный бэкэнд. - VISION_API_LOCATION_ID — это местоположение в облаке, где развернут бэкэнд поиска товаров.
us-east1
— это место, где мы развернули демонстрационный бэкэнд. - VISION_API_PRODUCT_SET_ID — это идентификатор каталога товаров (или «набора товаров» в терминологии Vision API), в котором вы хотите искать визуально похожие товары. В одном проекте Cloud может быть несколько каталогов.
product_set0
— это предустановленный каталог товаров демонстрационной версии.
7. Вызовите API поиска товаров.
Изучите формат запроса и ответа API
Вы можете найти похожие товары по заданному изображению, передав 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 : идентификатор вашего проекта GCP.
- 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}
. Вам потребуется отправить ещё один запрос API к 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)
}
Реализовать вызов API
Затем создайте запрос к API поиска товаров и отправьте его в бэкенд. Для создания запроса к API вам понадобится 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
}
Показать результат поиска в пользовательском интерфейсе
Теперь код API в 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
содержит шаблонный код, который анализирует ответ API и отображает его на экране.
Запусти это
Теперь нажмите «Выполнить» ( ) на панели инструментов Android Studio. После загрузки приложения коснитесь любого предустановленного изображения, выберите обнаруженный объект, нажмите кнопку «Поиск» и просмотрите результаты поиска, возвращенные серверной частью. Вы увидите что-то вроде этого:
Скриншот экрана результатов поиска товара
Бэкенд уже возвращает список визуально похожих товаров из предустановленного каталога. Однако вы видите, что изображение товара всё ещё пустое. Это связано с тем, что конечная точка projects.locations.images.annotate возвращает только идентификаторы изображений товаров, например projects/odml-codelabs/locations/us-east1/products/product_id77/referenceImages/image77
. Вам потребуется выполнить ещё один вызов API к конечной точке projects.locations.products.referenceImages.get и получить URL-адрес этого изображения, чтобы отобразить его на экране.
8. Получите изображения продукта.
Изучите формат запроса и ответа API
Вы отправите HTTP-запрос GET с пустым телом запроса в конечную точку projects.locations.products.referenceImages.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"
}
- Имя : Идентификатор эталонного изображения
- uri : URI изображения в Google Cloud Storage (GCS).
Изображения для демонстрационного бэкэнда поиска товаров были настроены на публичное чтение. Поэтому вы можете легко преобразовать URI GCS в HTTP-URL и отобразить его в пользовательском интерфейсе приложения. Вам нужно лишь заменить префикс gs://
на https://storage.googleapis.com/
.
Реализовать вызов API
Затем создайте запрос к API поиска товаров и отправьте его в бэкенд. API 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
, который был возвращен конечной точкой поиска продукта, а затем выполняет следующие шаги:
- Вызывает конечную точку эталонного изображения для получения GCS URI эталонного изображения.
- Преобразует GCS URI в HTTP URL.
- Обновляет свойство
httpUri
объектаsearchResult
с помощью этого HTTP URL.
Соедините два API-запроса
Вернитесь к annotateImage
и измените его так, чтобы получить 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 Studio. После загрузки приложения нажмите на любое предустановленное изображение, выберите обнаруженный объект и нажмите кнопку «Поиск» , чтобы увидеть результаты поиска, на этот раз с изображениями продукта.
Понятны ли вам результаты поиска товаров?
9. Поздравляем!
Вы узнали, как вызывать бэкенд Vision API Product Search, чтобы добавить функцию поиска изображений товаров в ваше Android-приложение. Это всё, что вам нужно для его запуска!
По мере продолжения работы вам, возможно, захочется создать собственный бэкенд, используя каталог товаров. Ознакомьтесь со следующей практической работой в рамках учебного курса «Поиск изображений товаров», чтобы узнать, как создать собственный бэкенд и настроить ключ API для его вызова из мобильного приложения.
Что мы рассмотрели
- Как вызвать бэкэнд Vision API Product Search из приложения Android
Следующие шаги
- Ознакомьтесь с практической работой по созданию бэкенда поиска изображений товаров с помощью Vision API Product Search, чтобы узнать, как создать свой собственный бэкенд.
- Ознакомьтесь с другими путями обучения на сайте On-device Machine Learning.
- Встройте функцию поиска товаров в свое собственное приложение для Android