使用Twilio WhatsApp API进行图像识别的详细指南

380 阅读4分钟

图像识别的概念似乎是一个挑战,但在Clarifai的图像识别API的帮助下,代码可以预测给定图像的内容并确定描述图像的概念,以及图像分类准确性的预测值

在这篇文章中,我们将解释如何使用Twilio WhatsApp APIClarifai APIFlask开发一个工作的Python程序来识别多媒体内容。

设置

我们将首先创建一个目录来存储我们的项目文件。在你喜欢的终端中,输入:

$ mkdir image_recognition_whatsapp
$ cd image_recognition_whatsapp

由于我们将为这个项目安装Python软件包,我们需要创建一个虚拟环境

如果你使用的是Unix或MacOS系统,打开终端并输入以下命令:

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

注意: 根据你所使用的Python版本,你可能需要指定 python3

如果你使用的是Windows机器,在一个提示窗口中输入以下命令:

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

配置Twilio WhatsApp沙箱

登录Twilio仪表板,查看你的可编程信息仪表板。看看侧边栏,点击试一试,看看TryWhatsApp条目。选择它来学习如何设置你的沙箱

该沙盒由Twilio提供。然而,一旦你的申请完成,你可以为你的Twilio电话号码申请生产权限

Configurer la sandbox WhatsApp

要激活您的智能手机的WhatsApp沙盒,请向分配给您的账户的号码发送一条WhatsApp信息和给出的代码。代码以 "加入 "一词开始,后面是一个随机生成的两个字的短语。发送消息后不久,你应该收到Twilio的回应,表明你的手机号码已经连接到沙盒,你可以开始发送和接收消息。

如果你打算用其他智能手机测试你的应用程序,你必须对每一部手机重复沙箱注册过程。

对Twilio和Clarifai服务进行认证

我们需要安全地存储用于验证Twilio和Clarifai服务的重要凭证。

在你的工作目录中创建一个名为*.env*的文件,并将以下文字与你自己从Twilio控制台获得的Twilio凭证一起粘贴:

TWILIO_ACCOUNT_SID=<YOUR_TWILIO_ACCOUNT_SID>
TWILIO_AUTH_TOKEN=<YOUR_TWILIO_AUTH_TOKEN>

Informations d'identification d'un compte Twilio

要使用Clarifai的API,你必须创建一个账户并创建一个应用程序,为你的项目生成一个API密钥。

在*.env*文件中添加以下一行,Clarifai API密钥将是一串随机的字母数字字符。在定义API密钥时,表达式 "Key "必须在字符串内,如下所示:

CLARIFAI_API_KEY="Key <YOUR_CLARIFAI_API_KEY>"

设置Flask开发服务器

确保你目前处于你的项目目录的虚拟环境中。由于我们将在整个项目中使用Flask,我们需要设置开发服务器。在你的项目中添加一个*.flaskenv*文件(确保你的点在开头),并有以下几行:

FLASK_APP=app.py
FLASK_ENV=development

在测试和调试你的项目时,这些令人难以置信的有用的行将节省你的时间:

  • FLASK_APP 告诉Flask框架我们的应用程序的位置
  • FLASK_ENV 将Flask配置为在调试模式下运行

这些行很有用,因为每次你保存源文件时,服务器都会重新加载并反映这些变化。

然后在终端输入flask run ,启动Flask框架:

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

上面的截图显示了运行flask run 命令后你的控制台应该是什么样子。该服务在你的计算机上的端口5000 上私下运行,并等待进入的连接。你还可以看到,调试模式是激活的。在这种模式下,Flask服务器会自动重新启动,以纳入对源代码的任何进一步修改。

用Twilio设置一个webhook

由于这是一个创建WhatsApp聊天机器人的教程,我们需要使用一个webhook(网络回调)来让Twilio向我们的应用程序提供实时数据。

在你的项目目录下打开另一个终端窗口。当Flask在终端窗口中运行时,用以下命令运行ngrok,在互联网上暂时公开启用Flask服务:

$ ngrok http 5000

Ngrok是一个伟大的工具,因为它允许你创建一个临时的公共域,将HTTP请求重定向到我们的本地端口5000

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

你的ngrok终端现在看起来就像上面的图片。正如你所看到的,在 "转发 "部分有一些URL。这些是ngrok用来重定向到我们Flask服务器的请求的公共URL。

将以https:// 开始的URL复制到剪贴板,然后返回Twilio控制台。进入可编程消息仪表板,查看可编程消息侧栏,在设置选项下找到*WhatsApp沙盒设置* 。这就是我们告诉Twilio将传入的消息通知发送到这个URL的地方。

把从ngrok会话中复制的URL粘贴到 "WHEN A MESSAGE COMES IN "字段中,并添加/webhook ,因为这是我们以后在Python应用程序中要写的端点。这里是我的参考例子:

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

在我的例子中,ngrok的URL是 "http://ad7e4814affe.ngrok.io/webhook"但同样,你的会有所不同。

在你点击页面底部的 "保存 "按钮之前,确保查询方法被设置为HTTP POST

将Clarifai API整合到您的应用程序中

这个项目是测试Clarifai API的绝佳机会,看看它是如何与用户输入一起工作的。利用计算机视觉和人工智能,Clarifai提取并分析图像,以返回与图像相关的标签或 "概念",如 "外面"、"云 "或 "天空",如果你发送一张天空的图像。这个API将被用来帮助我们的应用程序通过定义一个标签和一个预测值来识别图像中正在发生的事情,这个预测值是指相关的标签实际出现在图像中的概率。

现在让我们创建一个新的Python文件。我创建了image_classifier.py来存储使用Clarifai API的代码。将以下代码复制到你刚刚创建的文件中:

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

该函数get_tags ,向Clarifai API发送请求,解析通过WhatsApp发送的图片。元素response 被解析,因此只有图像的标签被记录在列表relevant_tags 中。这些描述性标签将有元素concept.value ,它与概念的预测值相对应。你也可以使用另一个数据结构来存储所有标签。使用字典可以让你在必要时扩展项目,特别是当你需要检测一个特定的单词时。

为了返回一个格式良好的标签列表,每个concept.value ,四舍五入到两位小数。请自由地对其进行相应的修改,以获得你想看到的结果。

用Twilio接收和回复信息

该应用程序的目的是通过WhatsApp发送一张照片,并让Clarifai API返回与图片相关的标签列表。

创建一个名为app.py的文件,复制并粘贴以下代码,以导入运行Flask应用程序所需的函数和模块,以及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.')

正如你所看到的,一个新的函数Respond() ,在整个项目中被创建和调用。这个函数向用户发送一个响应。通过调用这个函数,我们的应用程序也可以将输出结果返回给用户。

webhook很短:用户必须在图像中发送一个文本,以显示图像分类标签。元素url_pic ,并传递给文件image_classifier.py中定义的函数get_tags 。这个函数的结果被存储在relevant_tags 对象中,通过WhatsApp发回给用户。

运行WhatsApp图像识别应用程序

现在是总结和测试代码的时候了。确保你有一个运行flask 和一个运行ngrok 的选项卡。如果你因某种原因关闭了它,现在用以下命令在各自的标签中重新启动它:

(venv) $ flask run

而在第二个标签中:

$ ngrok http 5000

此外,确保Webhook URLngrok 在WhatsApp的Twilio沙盒中被更新。每次你重新启动ngrok,URL就会改变。因此,你将需要更换URL。不要忘记在ngrok转发URL的末尾添加/webhook

拿着您的支持WhatsApp的移动设备,发送一张图片到您的WhatsApp沙盒。等待一分钟,观察结果,如下图所示。

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!与您的图片相关的标签不仅显示在控制台,而且还将以WhatsApp信息的形式返回。看来Clarifai API在识别波特-罗宾逊第二届天空音乐节上的照片时没有遇到太多麻烦

图像识别项目的下一步是什么?

祝贺你!您已经使用Twilio WhatsApp API、Clarifai、Python和Flask成功识别了发送至您的WhatsApp沙盒号码的图像内容。