Appeler le backend de la recherche de produits de l'API Vision sur Android

1. Avant de commencer

bd8c01b2f8013c6d.png

Avez-vous vu la démo de Google Lens, qui vous permet de pointer l'appareil photo de votre téléphone sur un objet et de trouver où l'acheter en ligne ? Si vous souhaitez découvrir comment ajouter la même fonctionnalité à votre application, cet atelier de programmation est fait pour vous. Il fait partie d'un parcours de formation qui vous apprend à intégrer une fonctionnalité de recherche d'images de produits dans une application mobile.

Dans cet atelier de programmation, vous apprendrez à appeler un backend créé avec la recherche de produits de l'API Vision à partir d'une application mobile. Ce backend peut prendre une image de requête et rechercher des produits visuellement similaires dans un catalogue de produits.

Pour en savoir plus sur les étapes restantes de la création d'une fonctionnalité de recherche visuelle de produits, y compris sur l'utilisation de la détection et du suivi d'objets ML Kit pour détecter des objets dans l'image de requête et permettre aux utilisateurs de choisir le produit qu'ils souhaitent rechercher, consultez le parcours de formation.

Objectifs de l'atelier

  • Dans cet atelier de programmation, vous allez commencer avec l'application Android qui peut détecter des objets à partir d'une image d'entrée. Vous allez écrire du code pour récupérer l'objet choisi par l'utilisateur, l'envoyer au backend de recherche de produits et afficher le résultat de la recherche à l'écran.
  • Au final, vous devriez obtenir un résultat semblable à l'image de droite.

Points abordés

  • Appeler et analyser la réponse des API de recherche de produits de l'API Vision à partir d'une application Android

Prérequis

  • Une version récente d'Android Studio (v4.1.2 ou version ultérieure)
  • Émulateur Android Studio ou appareil Android physique
  • L'exemple de code
  • Connaissances de base du développement Android en Kotlin

Cet atelier de programmation est consacré à la recherche de produits de l'API Vision. Les concepts et les blocs de code non pertinents ne sont pas abordés, mais vous sont fournis afin que vous puissiez simplement les copier et les coller.

2. À propos de la recherche de produits de l'API Vision

La recherche de produits de l'API Vision est une fonctionnalité de Google Cloud qui permet aux utilisateurs de rechercher des produits visuellement similaires dans un catalogue de produits. Les marchands peuvent créer des produits, chacun contenant des images de référence qui décrivent visuellement le produit sous différents points de vue. Vous pouvez ensuite ajouter ces produits à des ensembles de produits (c'est-à-dire à votre catalogue de produits). Actuellement, la recherche de produits de l'API Vision accepte les catégories de produits suivantes : "homegoods" (articles de maison), "apparel" (vêtements), "toys" (jouets), "packaged goods" (biens de consommation courante) et "general" (général).

Lorsque les utilisateurs interrogent un ensemble de produits avec leurs propres images, la recherche de produits de l'API Vision se base sur ses fonctionnalités de machine learning pour comparer le produit représenté par l'image de l'utilisateur avec les images de l'ensemble de produits du revendeur, puis renvoie une liste classée de résultats visuellement et sémantiquement similaires.

3. Télécharger et exécuter l'application de démarrage

Télécharger le code

Cliquez sur le lien ci-dessous pour télécharger l'ensemble du code de cet atelier de programmation :

Décompressez le fichier ZIP téléchargé. Cela a pour effet de décompresser un dossier racine (odml-pathways-main) contenant toutes les ressources dont vous aurez besoin. Pour cet atelier de programmation, vous n'aurez besoin que des sources du sous-répertoire product-search/codelab2/android.

Le sous-répertoire codelab2 du dépôt odml-pathways contient deux répertoires :

  • android_studio_folder.pngstarter : code de démarrage sur lequel s'appuie cet atelier de programmation.
  • android_studio_folder.pngfinal : code complet de l'exemple d'application finalisée.

L'application de démarrage est celle que vous avez créée dans l'atelier de programmation Détecter des objets dans des images pour créer une recherche visuelle de produits : Android. Il utilise ML Kit Object Detection and Tracking pour détecter des objets à partir d'une image et les afficher à l'écran.

Importer l'application dans Android Studio

Commencez par importer l'application starter dans Android Studio.

Accédez à Android Studio, sélectionnez Import Project (Gradle, Eclipse ADT, etc.) (Importer un projet (Gradle, Eclipse ADT, etc.)), puis choisissez le dossier starter dans le code source que vous avez téléchargé précédemment.

7c0f27882a2698ac.png

Exécuter l'application de départ

Maintenant que vous avez importé le projet dans Android Studio, vous êtes prêt à exécuter l'application pour la première fois. Connectez votre appareil Android via USB à votre hôte ou démarrez l'émulateur Android Studio,puis cliquez sur Run ( Exécuter) execute.png dans la barre d'outils Android Studio.

(Si ce bouton est désactivé, assurez-vous d'importer uniquement starter/app/build.gradle, et non l'intégralité du dépôt.)

L'application devrait maintenant se lancer sur votre appareil Android. Il possède déjà la capacité de détection d'objets : il détecte les articles de mode dans l'image et vous indique où ils se trouvent. Essayez avec les photos prédéfinies pour confirmer.

c6102a808fdfcb11.png

Capture d'écran de l'application de démarrage, qui peut détecter des objets dans une image

Vous allez ensuite étendre l'application pour envoyer les objets détectés au backend de recherche de produits de l'API Vision et afficher les résultats de recherche à l'écran.

4. Gérer la sélection d'objets

Autoriser les utilisateurs à appuyer sur un objet détecté pour le sélectionner

Vous allez maintenant ajouter du code pour permettre aux utilisateurs de sélectionner un objet dans l'image et de lancer la recherche de produits. L'application de démarrage est déjà capable de détecter des objets dans l'image. Il est possible que l'image contienne plusieurs objets ou que l'objet détecté n'occupe qu'une petite partie de l'image. Par conséquent, l'utilisateur doit appuyer sur l'un des objets détectés pour indiquer celui qu'il souhaite utiliser pour la recherche de produits.

9cdfcead6d95a87.png

Capture d'écran des articles de mode détectés dans l'image

Pour que l'atelier de programmation reste simple et axé sur le machine learning, du code Android standard a été implémenté dans l'application de démarrage pour vous aider à détecter l'objet sur lequel l'utilisateur a appuyé. La vue qui affiche l'image dans l'activité principale (ObjectDetectorActivity) est en fait une vue personnalisée (ImageClickableView) qui étend le ImageView par défaut d'Android OS. Il implémente des méthodes utilitaires pratiques, y compris les suivantes :

  • fun setOnObjectClickListener(listener: ((objectImage: Bitmap) -> Unit)) Il s'agit d'un rappel permettant de recevoir l'image recadrée qui ne contient que l'objet sur lequel l'utilisateur a appuyé. Vous enverrez cette image recadrée au backend de recherche de produits.

Ajoutez du code pour gérer l'interaction de l'utilisateur avec les objets détectés.

Accédez à la méthode initViews dans la classe ObjectDetectorActivity et ajoutez les lignes suivantes à la fin de la méthode : (Android Studio vous indiquera qu'il ne trouve pas la méthode startProductImageSearch. Ne vous inquiétez pas, vous l'implémenterez un peu plus tard.)

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

onObjectClickListener est appelé chaque fois que l'utilisateur appuie sur l'un des objets détectés à l'écran. Il reçoit l'image recadrée qui ne contient que l'objet sélectionné. Par exemple, si l'utilisateur appuie sur la personne portant la robe à droite, l'écouteur est déclenché avec objectImage comme indiqué ci-dessous.

9cac8458d0f326e6.png

Exemple d'image recadrée transmise à onObjectClickListener

Envoyer l'image recadrée à l'activité de recherche de produits

Vous allez maintenant implémenter la logique d'envoi de l'image de requête au backend de recherche de produits de l'API Vision dans une activité distincte (ProductSearchActivity).

Tous les composants de l'UI ont été implémentés à l'avance pour que vous puissiez vous concentrer sur l'écriture du code permettant de communiquer avec le backend de recherche de produits.

25939f5a13eeb3c3.png

Capture d'écran des composants de l'UI sur ProductSearchActivity

Ajoutez le code permettant d'envoyer l'image de l'objet sélectionné par l'utilisateur à ProductSearchActivity.

Revenez à Android Studio et ajoutez cette méthode startProductImageSearch à la classe 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)
    }
}

L'extrait de code effectue trois opérations :

  • Prend l'image recadrée et la sérialise dans un fichier PNG.
  • Démarre le ProductSearchActivity pour exécuter la séquence de recherche de produits.
  • Inclut l'URI de l'image recadrée dans l'intent de démarrage d'activité afin que ProductSearchActivity puisse le récupérer ultérieurement pour l'utiliser comme image de requête.

Voici quelques points à garder à l'esprit :

  • La logique de détection des objets et d'interrogation du backend a été divisée en deux activités uniquement pour faciliter la compréhension de l'atelier de programmation. C'est à vous de décider comment les implémenter dans votre application.
  • Vous devez écrire l'image de la requête dans un fichier et transmettre l'URI de l'image entre les activités, car l'image de la requête peut être plus grande que la limite de taille de 1 Mo d'une intention Android.
  • Vous pouvez stocker l'image de requête au format PNG, car il s'agit d'un format sans perte.

Récupérer l'image de la requête dans l'activité de recherche de produits

Dans ProductSearchActivity, le code permettant de récupérer l'image de requête et de l'afficher à l'écran a déjà été implémenté dans l'application de démarrage.

Accédez à la méthode onCreate et vérifiez que ce code est déjà présent :

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

Exécuter l'application

Cliquez ensuite sur Run ( Exécuter) execute.png dans la barre d'outils Android Studio.

Une fois l'application chargée, appuyez sur l'une des images prédéfinies, puis sélectionnez l'un des objets détectés.

Vérifiez que l'icône ProductSearchActivity s'affiche avec l'image sur laquelle vous avez appuyé. Le bouton Search (Rechercher) n'est encore associé à aucune action, mais nous l'implémenterons ensuite.

fed40f81b8b43801.png

Un écran semblable à celui-ci devrait s'afficher après que vous aurez appuyé sur l'un des objets détectés.

5. Explorer le backend de la recherche de produits

Créer le backend de recherche d'images de produits

Cet atelier de programmation nécessite un backend de recherche de produits créé avec la recherche de produits de l'API Vision. Pour cela, deux options sont possibles :

Option 1 : Utiliser le backend de démonstration qui a été déployé pour vous

Vous pouvez suivre cet atelier de programmation en utilisant le backend de recherche de produits que Google a déjà déployé pour vous. Le backend de démonstration peut être répliqué en suivant le guide de démarrage rapide de la recherche de produits de l'API Vision.

Option 2 : Créez votre propre backend en suivant le guide de démarrage rapide de la recherche de produits de l'API Vision

Cette option est recommandée pour ceux qui souhaitent en savoir plus sur la création d'un backend de recherche de produits afin de pouvoir en créer un pour leur propre catalogue de produits ultérieurement. Vous devez disposer des éléments suivants :

  • Un compte Google Cloud pour lequel la facturation est activée. (Il peut s'agir d'un compte d'essai sans frais.)
  • Connaissances de base des concepts Google Cloud, y compris les projets, les comptes de service, etc.

Vous découvrirez comment procéder dans le parcours de formation.

Découvrez les concepts importants

Vous rencontrerez ces concepts lorsque vous interagirez avec le backend de recherche de produits :

  • Ensemble de produits : un ensemble de produits est un conteneur simple pour un groupe de produits. Un catalogue de produits peut être représenté sous la forme d'un ensemble de produits et de ses produits.
  • Produit : une fois que vous avez créé un ensemble de produits, vous pouvez créer des produits et les ajouter à l'ensemble de produits.
  • Images de référence du produit : il s'agit d'images contenant différentes vues de vos produits. Les images de référence permettent de rechercher des produits visuellement similaires.
  • Rechercher des produits : une fois que vous avez créé votre ensemble de produits et que celui-ci a été indexé, vous pouvez l'interroger à l'aide de l'API Cloud Vision.

Comprendre le catalogue de produits prédéfini

Le backend de démonstration de recherche de produits utilisé dans cet atelier de programmation a été créé à l'aide de la recherche de produits de l'API Vision et d'un catalogue de produits contenant une centaine d'images de chaussures et de robes. Voici quelques images du catalogue :

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

Exemples tirés du catalogue de produits prédéfini

Appeler le backend de démonstration de la recherche de produits

Vous pouvez appeler la recherche de produits de l'API Vision directement depuis une application mobile en configurant une clé API Google Cloud et en limitant l'accès à cette clé à votre application uniquement.

Pour simplifier cet atelier de programmation, un point de terminaison de proxy a été configuré pour vous permettre d'accéder au backend de démonstration sans vous soucier de la clé API ni de l'authentification. Il reçoit la requête HTTP de l'application mobile, ajoute la clé API et transmet la requête au backend de recherche de produits de l'API Vision. Le proxy reçoit ensuite la réponse du backend et la renvoie à l'application mobile.

Dans cet atelier de programmation, vous utiliserez deux API de la recherche de produits de l'API Vision :

6. Implémenter le client API

Comprendre le workflow de recherche de produits

Suivez ce workflow pour effectuer une recherche de produits avec le backend :

Implémenter la classe du client API

Vous allez maintenant implémenter du code pour appeler le backend de recherche de produits dans une classe dédiée appelée ProductSearchAPIClient. Du code standard a été implémenté pour vous dans l'application de démarrage :

  • class ProductSearchAPIClient : cette classe est presque vide pour le moment, mais elle contient des méthodes que vous implémenterez plus tard dans cet atelier de programmation.
  • fun convertBitmapToBase64(bitmap: Bitmap) : convertissez une instance Bitmap en représentation base64 pour l'envoyer au backend de recherche de produits.
  • fun annotateImage(image: Bitmap): Task<List<ProductSearchResult>> : appelez l'API projects.locations.images.annotate et analysez la réponse.
  • fun fetchReferenceImage(searchResult: ProductSearchResult): Task<ProductSearchResult> : appelez l'API projects.locations.products.referenceImages.get et analysez la réponse.
  • SearchResult.kt : ce fichier contient plusieurs classes de données pour représenter les types renvoyés par le backend de la recherche de produits de l'API Vision.

Spécifier les configurations de l'API

Accédez à la classe ProductSearchAPIClient. Vous verrez que certaines configurations du backend de recherche de produits sont déjà définies :

// 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 est le point de terminaison de l'API Cloud Vision. Lorsque vous poursuivez avec le backend de démonstration, définissez-le sur le point de terminaison du proxy. Toutefois, si vous déployez votre propre backend, vous devrez le remplacer par le point de terminaison de l'API Cloud Vision. https://vision.googleapis.com/v1.
  • VISION_API_KEY correspond à la clé API de votre projet Cloud. Étant donné que le proxy gère déjà l'authentification, vous pouvez laisser ce champ vide.
  • VISION_API_PROJECT_ID est l'ID du projet Cloud. odml-codelabs est le projet Cloud dans lequel le backend de démonstration est déployé.
  • VISION_API_LOCATION_ID est l'emplacement Cloud où le backend de recherche de produits est déployé. us-east1 correspond à l'emplacement où nous avons déployé le backend de démonstration.
  • VISION_API_PRODUCT_SET_ID correspond à l'ID du catalogue de produits (également appelé "ensemble de produits" dans l'API Vision) dans lequel vous souhaitez rechercher des produits visuellement similaires. Vous pouvez disposer de plusieurs catalogues dans un même projet Cloud. product_set0 est le catalogue de produits prédéfini du backend de démonstration.

7. Appeler l'API Product Search

Explorer le format des requêtes et des réponses de l'API

Pour rechercher des produits semblables à une image donnée, transmettez l'URI Google Cloud Storage, l'URL Web ou la chaîne encodée en base64 de l'image à la fonctionnalité de recherche de produits de l'API Vision. Dans cet atelier de programmation, vous allez utiliser l'option de chaîne encodée en base64, car notre image de requête n'existe que sur l'appareil de l'utilisateur.

Vous devez envoyer une requête POST au point de terminaison projects.locations.images.annotate avec le corps JSON de la requête suivant :

{
  "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"
          ],
        }
      }
    }
  ]
}

Certains paramètres doivent être spécifiés :

  • base64-encoded-image : représentation en base64 (chaîne ASCII) des données binaires de l'image de la requête.
  • project-id : ID du projet GCP
  • location-id : indicateur d'emplacement valide.
  • product-set-id : ID de l'ensemble de produits sur lequel vous souhaitez exécuter l'opération.

Étant donné que votre catalogue de produits ne contient que des images de chaussures et de robes, spécifiez que productCategories doit être défini sur apparel-v2. v2 signifie que nous utilisons la version 2 du modèle de machine learning pour la recherche de produits vestimentaires.

Si la requête aboutit, le serveur renvoie un code d'état HTTP 200 OK ainsi que la réponse au format JSON. La réponse JSON inclut les deux types de résultats suivants :

  • productSearchResults : contient une liste de produits correspondants pour l'image entière.
  • productGroupedResults : contient les coordonnées du cadre de sélection et les éléments correspondants pour chaque produit identifié dans l'image.

Étant donné que le produit a déjà été recadré à partir de l'image d'origine, vous analyserez les résultats dans la liste productSearchResults.

Voici quelques champs importants de l'objet de résultat de recherche de produits :

  • product.name : identifiant unique d'un produit au format projects/{project-id}/locations/{location-id}/products/{product_id}
  • product.score : valeur indiquant la similitude entre le résultat de recherche et l'image de la requête. Plus la valeur est élevée, plus la similarité est importante.
  • product.image : identifiant unique de l'image de référence d'un produit au format projects/{project-id}/locations/{location-id}/products/{product_id}/referenceImages/{image_id}. Vous devrez envoyer une autre requête API à projects.locations.products.referenceImages.get pour obtenir l'URL de cette image de référence afin qu'elle s'affiche à l'écran.
  • product.labels : liste des tags prédéfinis du produit. Cela peut être utile si vous souhaitez filtrer les résultats de recherche pour n'afficher qu'une seule catégorie de vêtements, comme les robes.

Convertir l'image de requête en base64

Vous devez convertir l'image de requête en chaîne base64 et joindre cette chaîne à l'objet JSON dans le corps de la requête.

Accédez à la classe ProductSearchAPIClient, recherchez la méthode convertBitmapToBase64 vide et remplacez-la par cette implémentation :

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)
}

Implémenter l'appel d'API

Ensuite, créez une requête d'API de recherche de produits et envoyez-la au backend. Vous utiliserez Volley pour envoyer la requête API et renverrez le résultat à l'aide de l'API Task.

Revenez à la classe ProductSearchAPIClient, recherchez la méthode annotateImage vide et remplacez-la par cette implémentation :

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
}

Afficher le résultat de la recherche dans l'UI

Le code de l'API dans ProductSearchAPIClient est maintenant prêt. Revenez à l'activité ProductSearchActivity pour implémenter le code de l'UI.

L'activité comporte déjà du code passe-partout qui déclenche la méthode searchByImage(queryImage: Bitmap). Ajoutez du code pour appeler le backend et afficher les résultats dans l'UI dans cette méthode actuellement vide.

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

La méthode showSearchResult contient du code passe-partout qui analyse la réponse de l'API et l'affiche à l'écran.

Exécuter le code

Cliquez ensuite sur Run ( Exécuter) execute.png dans la barre d'outils Android Studio. Une fois l'application chargée, appuyez sur l'une des images prédéfinies, sélectionnez un objet détecté, appuyez sur le bouton Rechercher et consultez les résultats de recherche renvoyés par le backend. Le résultat qui s'affiche doit ressembler à ceci :

bb5e7c27c283a2fe.png

Capture d'écran de la page de résultats de recherche de produits

Le backend renvoie déjà une liste de produits visuellement similaires à partir du catalogue de produits prédéfini. Toutefois, vous pouvez constater que l'image du produit est toujours vide. En effet, le point de terminaison projects.locations.images.annotate ne renvoie que des ID d'images de produits, comme projects/odml-codelabs/locations/us-east1/products/product_id77/referenceImages/image77. Vous devrez effectuer un autre appel d'API au point de terminaison projects.locations.products.referenceImages.get et obtenir l'URL de cette image de référence pour l'afficher à l'écran.

8. Obtenir les images de référence du produit

Explorer le format des requêtes et des réponses de l'API

Vous enverrez une requête HTTP GET avec un corps de requête vide au point de terminaison projects.locations.products.referenceImages.get pour obtenir les URI des images de produits renvoyées par le point de terminaison de recherche de produits.

La requête HTTP se présente comme suit :

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

Si la requête aboutit, le serveur renvoie un code d'état HTTP 200 OK ainsi que la réponse au format JSON, comme indiqué ci-dessous :

{
  "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 : identifiant de l'image de référence
  • uri : URI de l'image sur Google Cloud Storage (GCS).

Les images de référence du backend de recherche de produits de démonstration ont été configurées avec l'autorisation "lecture publique". Vous pouvez donc facilement convertir l'URI GCS en URL HTTP et l'afficher dans l'UI de l'application. Il vous suffit de remplacer le préfixe gs:// par https://storage.googleapis.com/.

Implémenter l'appel d'API

Ensuite, créez une requête d'API de recherche de produits et envoyez-la au backend. Vous utiliserez Volley et l'API Task de la même manière que l'appel d'API de recherche de produits.

Revenez à la classe ProductSearchAPIClient, recherchez la méthode fetchReferenceImage vide et remplacez-la par cette implémentation :

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
}

Cette méthode prend un objet searchResult: ProductSearchResult renvoyé par le point de terminaison de recherche de produits, puis suit les étapes suivantes :

  1. Appelle le point de terminaison de l'image de référence pour obtenir l'URI GCS de l'image de référence.
  2. Convertit l'URI GCS en URL HTTP.
  3. Mettez à jour la propriété httpUri de l'objet searchResult avec cette URL HTTP.

Associer les deux requêtes API

Retournez à annotateImage et modifiez-le pour obtenir toutes les URL HTTP des images de référence avant de renvoyer la liste ProductSearchResult à son appelant.

Localisez la ligne suivante :

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

Remplacez-le ensuite par cette implémentation :

// 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) }

Le code standard permettant d'afficher les images de référence à l'écran est déjà implémenté pour vous dans la classe ProductSearchAdapter. Vous pouvez donc passer à la réexécution de l'application.

Exécuter le code

Cliquez ensuite sur Run ( Exécuter) execute.png dans la barre d'outils Android Studio. Une fois l'application chargée, appuyez sur l'une des images prédéfinies, sélectionnez un objet détecté, puis appuyez sur le bouton Rechercher pour afficher les résultats de recherche, cette fois avec les images des produits.

Les résultats de recherche de produits vous semblent-ils pertinents ?

25939f5a13eeb3c3.png

9. Félicitations !

Vous avez appris à appeler un backend de recherche de produits de l'API Vision pour ajouter une fonctionnalité de recherche d'images de produits à votre application Android. C'est tout ce dont vous avez besoin pour la faire fonctionner.

Au fur et à mesure, vous pouvez créer votre propre backend à l'aide de votre catalogue de produits. Consultez le prochain atelier de programmation du parcours de formation Recherche d'images de produits pour découvrir comment créer votre propre backend et configurer la clé API pour l'appeler depuis une application mobile.

Points abordés

  • Appeler le backend de la recherche de produits de l'API Vision à partir d'une application Android

Étapes suivantes

En savoir plus