Utiliser la reconnaissance d'images avec l'API Twilio WhatsApp

May 21, 2021
Rédigé par
Diane Phan
Twilion
Révisé par

Comment utiliser la reconnaissance d'images avec l'API Twilio WhatsApp

Le concept de reconnaissance des images peut sembler être un défi, mais avec l'aide de API de reconnaissance d'images de Clarifai, le code peut prédire le contenu d'une image donnée et déterminer les concepts pour décrire l'image, ainsi que la valeur de prédiction de la précision de la classification de l'image.

Dans cet article, nous allons vous expliquer comment développer un programme Python fonctionnel pour identifier le contenu multimédia à l'aide de l'API Twilio WhatsApp APIAPI Clarifai, et Flask.

Configuration requise pour le tutoriel

Pour créer ce projet, vous devez disposer des éléments suivants :

  • Python 3.6 ou version ultérieure. Si votre système d'exploitation ne fournit pas d'interpréteur Python, vous pouvez vous rendre sur python.org pour télécharger un programme d'installation.
  • ngrok est un utilitaire pratique pour connecter la version de développement de notre application Python exécutée sur votre système à une URL publique à laquelle Twilio peut se connecter. Cela est nécessaire pour la version de développement de l'application, car votre ordinateur est probablement derrière un routeur ou un pare-feu, et n'est donc pas directement accessible sur Internet. Vous pouvez également apprendre à automatiser ngrok.
  • Un compte Clarifai. Créez un compte gratuit pour générer une clé API.
  • Un compte Twilio gratuit ou payé. Si vous êtes nouveau sur Twilio, obtenez votre compte gratuit maintenant ! (Si vous vous inscrivez via ce lien, Twilio vous donnera un crédit de 10 $ lors de la mise à niveau.)

Configuration

Nous allons commencer par créer un répertoire pour stocker les fichiers de notre projet. À l'intérieur de votre terminal favori, saisissez :

$ mkdir image_recognition_whatsapp
$ cd image_recognition_whatsapp

Étant donné que nous allons installer des packages Python pour ce projet, nous devons créer un environnement virtuel.

Si vous utilisez un système Unix ou MacOS, ouvrez un terminal et entrez les commandes suivantes :

$ python -m venv venv
$ source venv/bin/activate
(venv) $ pip install flask twilio clarifai-grpc python-dotenv

REMARQUE : selon votre version active de Python, vous devrez peut-être spécifier python3.

Si vous utilisez une machine Windows, saisissez les commandes suivantes dans une fenêtre d'invite :

$ python -m venv venv
$ venv/Scripts/activate
(venv) $ pip install flask twilio clarifai-grpc python-dotenv

Consultez ici plus d'informations sur les packages :

  • Le framework Flask, pour créer l'application Web qui recevra les notifications de messages de Twilio.
  • Le package python-twilio, pour envoyer des messages via le service Twilio.
  • Clarifai Python gRPC Client pour interagir avec l'API Clarifai pour la reconnaissance d'images.
  • Le package python-dotenv, pour lire un fichier de configuration.

Configurer la sandbox WhatsApp Twilio

Connectez-vous au tableau de bord Twilio pour afficher votre tableau de bord Programmable Messaging. Regardez la barre latérale pour cliquer sur Try it Out (Essayer) et afficher l'entrée Try WhatsApp (Essayer WhatsApp). Sélectionnez-la pour savoir comment configurer votre sandbox.

La sandbox est fournie par Twilio. Cependant, une fois votre application terminée, vous pouvez demander un accès en production pour votre numéro de téléphone Twilio.

Configurer la sandbox WhatsApp

Pour activer la sandbox WhatsApp pour votre smartphone, envoyez un message WhatsApp avec le code indiqué au numéro attribué à votre compte. Le code commence par le mot « join », suivi d'une expression de deux mots générée de façon aléatoire. Peu après avoir envoyé le message, vous devriez recevoir une réponse de Twilio indiquant que votre numéro de téléphone mobile est connecté à la sandbox et que vous pouvez commencer à envoyer et recevoir des messages.

Si vous avez l'intention de tester votre application avec d'autres smartphones, vous devez répéter le processus d'enregistrement sandbox avec chacun d'eux.

S'authentifier auprès des services Twilio et Clarifai

Nous devons stocker en toute sécurité des informations d'identification importantes qui seront utilisées pour nous authentifier auprès des services Twilio et Clarifai.

Créez un fichier nommé .env dans votre répertoire de travail et collez le texte suivant avec vos propres informations d'identification Twilio obtenues à partir de votre console Twilio:

TWILIO_ACCOUNT_SID=<YOUR_TWILIO_ACCOUNT_SID>
TWILIO_AUTH_TOKEN=<YOUR_TWILIO_AUTH_TOKEN>

Informations d'identification d'un compte Twilio

Pour utiliser l'API Clarifai, vous devez créer un compte et créer une application pour générer une clé API pour votre projet.

Ajoutez la ligne suivante au fichier .env. La clé API Clarifai sera une chaîne aléatoire de caractères alphanumériques. Il est essentiel que l'expression « Key » se trouve à l'intérieur de la chaîne lors de la définition de la clé API, comme indiqué ci-dessous.

CLARIFAI_API_KEY="Key <YOUR_CLARIFAI_API_KEY>"

Configurer un serveur de développement Flask

Assurez-vous que vous vous trouvez actuellement dans l'environnement virtuel de votre répertoire de projet. Étant donné que nous allons utiliser Flask tout au long du projet, nous devons configurer le serveur de développement. Ajoutez un fichier .flaskenv (assurez-vous que vous disposez du point au début) à votre projet avec les lignes suivantes :

FLASK_APP=app.py
FLASK_ENV=development

Ces lignes incroyablement utiles vous feront gagner du temps lors du test et du débogage de votre projet.

  • FLASK_APP indique au framework Flask où se trouve notre application
  • FLASK_ENV configure Flask pour qu'il fonctionne en mode débogage

Ces lignes sont pratiques, car chaque fois que vous enregistrez le fichier source, le serveur se recharge et reflète les modifications.

Saisissez ensuite flask run dans votre terminal pour démarrer le framework Flask.

Terminal affichant la sortie de la commande « flask run ». flask fonctionne avec un environnement en cours de développement

La capture d'écran ci-dessus montre à quoi doit ressembler votre console après l'exécution de la commande flask run. Le service s'exécute en privé sur le port 5000 de votre ordinateur et attend les connexions entrantes. Vous pouvez également remarquer que le mode débogage est actif. Dans ce mode, le serveur Flask redémarre automatiquement pour incorporer toute autre modification apportée au code source.

Configurer un webhook avec Twilio

Comme il s'agit d'un tutoriel pour créer un chatbot WhatsApp, nous devrons utiliser un webhook (rappel Web) pour permettre à Twilio de fournir des données en temps réel à notre application.

Ouvrez une autre fenêtre de terminal dans le répertoire de votre projet. Lorsque Flask est exécuté dans une fenêtre de terminal, lancez ngrok à l'aide de la commande suivante pour activer temporairement le service Flask publiquement sur Internet :

$ ngrok http 5000

Ngrok est un excellent outil, car il vous permet de créer un domaine public temporaire qui redirige les requêtes HTTP vers notre port local 5000.

Image montrant le résultat de l'exécution de la commande « ngrok http 5000 » avec des URL de transfert

Votre terminal ngrok va maintenant ressembler à l'image ci-dessus. Comme vous pouvez le voir, il existe des URL dans la section « Forwarding ». Il s'agit d'URL publiques que ngrok utilise pour rediriger les requêtes vers notre serveur Flask.

Copiez l'URL commençant par https:// dans le presse-papiers, puis revenez à la console Twilio. Accédez au tableau de bord Programmable Messaging et consultez la barre latérale de Programmable Messaging pour trouver les paramètres de la sandbox WhatsApp sous l'option Settings (Paramètres). C'est là que nous indiquons à Twilio d'envoyer des notifications de messages entrants à cette URL.

Collez l'URL copiée de la session ngrok dans le champ « WHEN A MESSAGE COMES IN » (LORSQU'UN MESSAGE ARRIVE) et ajoutez /webhook, car il s'agit du point de terminaison que nous allons écrire ultérieurement dans l'application Python. Voici mon exemple de référence :

capture d'écran de l'URL ngrok dans le champ de texte pour la sandbox Twilio WhatsApp

L'URL de ngrok dans mon exemple est « http://ad7e4814affe.ngrok.io/webhook », mais là encore, le vôtre sera différent.

Avant de cliquer sur le bouton « Save » (Enregistrer) en bas de la page, assurez-vous que la méthode de requête est définie sur HTTP POST.

Intégrer l'API Clarifai à votre application

Ce projet est une excellente occasion de tester l'API Clarifai et de voir comment elle fonctionne par rapport aux entrées des utilisateurs. À l'aide de la vision par ordinateur et de l'intelligence artificielle, Clarifai procède à l'extraction et à l'analyse de l'image pour renvoyer des tags ou des « concepts » associés à l'image, tels que « extérieur », « nuage » ou « ciel » si vous envoyez une image du ciel. Cette API sera utilisée pour aider notre application à identifier ce qui se passe sur l'image en définissant un tag et une valeur de prédiction de la probabilité qu'un tag associé soit vraiment sur l'image.  

Maintenant, créons un nouveau fichier Python. J'ai créé image_classifier.py pour stocker le code qui utilise l'API Clarifai. Copiez le code suivant dans le fichier que vous venez de créer :

import os
from dotenv import load_dotenv
from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_pb2, status_code_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

load_dotenv()
CLARIFAI_API_KEY = os.environ.get('CLARIFAI_API_KEY')
metadata = (('authorization', CLARIFAI_API_KEY),)

def get_tags(image_url):
    relevant_tags = {}   
    request = service_pb2.PostModelOutputsRequest(
      model_id='aaa03c23b3724a16a56b629203edc62c',
      inputs=[
        resources_pb2.Input(data=resources_pb2.Data(image=resources_pb2.Image(url=image_url)))
    ])
    response = stub.PostModelOutputs(request, metadata=metadata)
    if response.status.code != status_code_pb2.SUCCESS:
        raise Exception("Request failed, status code: " + str(response.status.code))
    for concept in response.outputs[0].data.concepts:
        print('%12s: %.2f' % (concept.name, concept.value), "\n")
        relevant_tags[concept.name] = round(concept.value, 2)
    return relevant_tags

La fonction get_tags envoie une requête à l'API Clarifai pour analyser l'image envoyée via WhatsApp. L'élément response est analysé afin que seules les tags de l'image soient enregistrés dans la liste relevant_tags. Ces tags descriptifs auront l'élément concept.value défini, qui correspond aux valeurs de prédiction des concepts. Vous pouvez également utiliser une autre structure de données pour stocker tous les tags. L'utilisation d'un dictionnaire vous permet de développer le projet si nécessaire, en particulier si vous devez détecter un mot particulier.

Pour renvoyer une liste de tags bien mise en forme, chaque concept.value est arrondie à deux décimales. N'hésitez pas à la modifier en conséquence pour obtenir les résultats que vous souhaitez voir.

Recevoir et répondre à des messages avec Twilio

L'objectif de l'application est d'envoyer une photo via WhatsApp et que l'API Clarifai renvoie une la liste des tags associées à l'image.

Créez un fichier nommé app.py et copiez et collez le code suivant afin d'importer les fonctions et les modules nécessaires pour exécuter l'application Flask, ainsi que le webhook :

import os
from dotenv import load_dotenv
from flask import Flask, request
from twilio.rest import Client
from twilio.twiml.messaging_response import Message, MessagingResponse
from image_classifier import get_tags

load_dotenv()
TWILIO_ACCOUNT_SID = os.environ.get('TWILIO_ACCOUNT_SID')
TWILIO_AUTH_TOKEN= os.environ.get('TWILIO_AUTH_TOKEN')

app = Flask(__name__)
client = Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN)

from_whatsapp_number = 'whatsapp:+<YOUR_WHATSAPP_SANDBOX_PHONE_NUMBER>'
to_whatsapp_number = 'whatsapp:+<YOUR_WHATSAPP_PHONE_NUMBER>'

def respond(message):
    response = MessagingResponse()
    response.message(message)
    return str(response)

@app.route('/webhook', methods=['POST'])
def reply():
    sender = request.form.get('From')
    media_msg = request.form.get('NumMedia')    # 1 si true - c'est un media message (photo)
    message = request.form.get('Body').lower()
    if media_msg == '1':
        pic_url = request.form.get('MediaUrl0')  # URL du media de la personne
        relevant_tags = get_tags(pic_url)
        print(relevant_tags)
        
        tag_string = ""
        for k, v in relevant_tags.items():
            tag_string += (k + " : " + str(v) + "\n")
            print(k, v, "\n")
        mms = client.messages.create(
                    body='Les tags de votre image sont: \n' + tag_string,
                        from_=from_whatsapp_number,
                        to=to_whatsapp_number
            )
    else:
        return respond(f'Envoyez une image.')

Comme vous pouvez le voir, une nouvelle fonction Respond() est créée et appelée tout au long du projet. Cette fonction envoie une réponse à l'utilisateur. En appelant cette fonction, notre application peut également renvoyer la sortie à l'utilisateur.

Le webhook est court : l'utilisateur doit envoyer un texte dans une image pour afficher les tags de classification d'image. L'élément url_pic est transmis à la fonction get_tags définie à partir du fichier image_classifier.py. Le résultat de cette fonction est stocké dans l'objet relevant_tags pour être renvoyé à l'utilisateur via WhatsApp.

Exécuter l'application de reconnaissance d'images WhatsApp

Il est temps de conclure et de tester le code. Assurez-vous que vous disposez d'un onglet exécutant flask et d'un onglet exécutant ngrok. Si vous l'avez fermé pour une raison quelconque, redémarrez-le maintenant avec les commandes suivantes dans leurs onglets respectifs.

(venv) $ flask run

Et dans le deuxième onglet :

$ ngrok http 5000

De plus, assurez-vous que l'URL du webhook ngrok est mise à jour dans la sandbox Twilio pour WhatsApp. Chaque fois que vous redémarrez ngrok, l'URL change. Vous devrez donc remplacer l'URL. N'oubliez pas d'ajouter le /webhook à la fin de l'URL de transfert ngrok.

Prenez votre appareil mobile compatible WhatsApp et envoyez une image à votre sandbox WhatsApp. Attendez une minute et observez les résultats comme indiqué ci-dessous :

Capture d'écran WhatsApp des valeurs de prédiction et des étiquettes de concept pour une photo de diane lors du second sky music festival

Tada ! Les tags associées à votre image sont non seulement affichées sur la console, mais elles sont également renvoyées sous forme de message WhatsApp. On dirait que l'API Clarifai n'a pas eu trop de mal à identifier la photo de moi au second Sky Music Festival de Porter Robinson !

Quelles sont les prochaines étapes pour les projets de reconnaissance d'images ?

Félicitations ! Vous avez réussi à identifier le contenu d'une image envoyée à votre numéro de sandbox WhatsApp à l'aide de l'API Twilio WhatsApp, Clarifai, Python et Flask.

Dans quelle mesure les prédictions étaient-elles précises et que faites-vous de ces nouvelles informations que vous pouvez récupérer à partir d'images multimédias WhatsApp ? Si vous recherchez d'autres projets de reconnaissance d'images, consultez les documents suivants :

Dites-moi ce que vous allez construire par la suite en me contactant par e-mail !

Diane Phan est développeuse de contenu technique au sein de l'équipe Twilio Voice. Elle adore aider les programmeurs débutants à se lancer dans des projets créatifs qui impliquent des références amusantes à la pop culture. Elle est joignable à dphan [at] twilio.com ou sur LinkedIn.