[PYTHON] Essayez de juger des photos de plats à l'aide de l'API Google Cloud Vision

Cet article est l'article du 12ème jour du Calendrier de l'avent de la technologie Web Fujitsu Systems. (Promesse) Le contenu de cet article est ma propre opinion et ne représente pas l'organisation à laquelle j'appartiens.

introduction

Cet article résume les étapes minimales pour utiliser l'API de reconnaissance d'images de Google "API Cloud Vision". Enfin, j'essaye de juger la photo culinaire.

De côté

Mon passe-temps personnel est Mesitello [^ 1], et je poste des photos de nourriture sur la chronologie LINE dans le but de me faire penser "j'ai faim". Je me demandais si je pouvais faire quelque chose avec l'API de reconnaissance d'image pour prendre des photos plus délicieuses et améliorer la qualité de Mesitello, alors cette fois j'ai commencé par essayer l'API Google Cloud Vision.

Ce que j'ai utilisé cette fois

Préparation à l'utilisation de l'API

Inscription à Google Cloud Platform

Tout d'abord, inscrivez-vous pour utiliser Google Cloud Platform afin d'utiliser l'API Cloud Vision.

Cliquez sur "Démarrer gratuitement" sur le site suivant pour lancer la procédure d'inscription. Disponible avec un compte Google.

Service Cloud Computing | Google Cloud

Créer un projet

Lorsque l'enregistrement est terminé, vous verrez un écran comme celui-ci et le projet par défaut a été créé. Vous pouvez créer un nouveau projet à partir du cadre rouge. L'API est également disponible dans le projet par défaut, mais ici j'ai créé un projet "Meshitero".

コンソールトップ.PNG

Activer l'API Cloud Vision

Si vous saisissez "Viso dans l'API" dans le formulaire de recherche, l'API Cloud Vision sera appelée, alors cliquez dessus. Sélectionnez "Activer" sur l'écran après la transition.

コンソールトップ_検索.png

Vision_API_トップ.PNG

À part: En passant, si vous sélectionnez "Essayer cette API", vous pouvez essayer la démo à l'écran.

Lorsqu'il est activé, vous verrez un écran comme celui-ci.

vision_API_on_top.PNG

Émission de la clé API

Cette fois, nous l'appellerons en Python, alors créez les informations d'identification. Cliquez sur "Créer des informations d'identification" sur l'écran de l'API Cloud Vision pour accéder à la page d'informations d'identification "API et services". Si vous sélectionnez "Clé API" dans le menu déroulant "Créer des informations d'identification", une clé API sera émise.

APIキー.PNG

APIキー作成.PNG

Restreignez les clés pour éviter toute utilisation non autorisée. Cliquez sur "Restreindre les clés" sur l'écran ci-dessus pour accéder à un écran où vous pouvez restreindre les clés. Définissez des restrictions au besoin. Cette fois, nous avons limité l'utilisation par adresse IP, et une fois restreint les API qui peuvent être utilisées pour l'API Cloud Vision.

キーを制限.PNG

Ceci termine les paramètres d'utilisation de l'API.

Appel API

Installation d'Anaconda

Pour appeler l'API en Python J'ai installé Anaconda en faisant référence à ce qui suit.

Installation d'Anaconda (Windows)

Créer une source

Créez la source en vous référant au contenu de Reference de l'API.

Création de données de demande à transmettre à l'API

Il semble que les données d'image doivent être passées sous la forme d'une chaîne encodée en base64. Précisez également le type d'analyse d'image et le nombre maximum de résultats à renvoyer dans les «fonctionnalités». Cette fois, spécifiez la détection d'étiquette (LABEL_DETECTION).

Lorsqu'il est transmis à l'API, il est également encodé au format Json afin qu'il soit au format Json.

img_request = []
with open(filename, 'rb') as f:
    ctxt = b64encode(f.read()).decode()
    img_requests.append({
            'image': {'content': ctxt},
            'features': [{
                'type': 'LABEL_DETECTION',
                'maxResults': 10
            }]
    })
request_data = json.dumps({"requests": img_request }).encode()

Partie appel API

Spécifiez les données de la demande et la sortie de la clé API à l'étape précédente, puis envoyez la demande d'API.

API_URL = 'https://vision.googleapis.com/v1/images:annotate'

response = requests.post(API_URL,
                         data=request_data ,
                         params={'key': api_key},
                         headers={'Content-Type': 'application/json'})

Sortie de résultat

Sort les données renvoyées par l'API.

for resp in enumerate(response.json()['responses']):
            print (json.dumps(resp, indent=2))

Courir

Transmettez la clé API émise par GCP et le chemin de l'image à la source créée et exécutez-la. Essayez quelques images de nourriture.

$ Python Meshitero.py [Clé API] [Chemin de l'image]

<détails>

Toute la source (Meshitero.py) </ summary>

Meshitero.py


from base64 import b64encode
from sys import argv
import json
import requests

API_URL = 'https://vision.googleapis.com/v1/images:annotate'

if __name__ == '__main__':
    api_key = argv[1]
    filename = argv[2]
    
    img_request = []
    with open(filename, 'rb') as f:
        ctxt = b64encode(f.read()).decode()
        img_request.append({
                'image': {'content': ctxt},
                'features': [{
                    'type': 'LABEL_DETECTION',
                    'maxResults': 10
                }]
        })

    request_data = json.dumps({"requests": img_request }).encode()
    
    response = requests.post(API_URL,
                            data=request_data,
                            params={'key': api_key},
                            headers={'Content-Type': 'application/json'})

    if response.status_code != 200 or response.json().get('error'):
        print(response.text)
    else:
        for resp in enumerate(response.json()['responses']):
            print (json.dumps(resp, indent=2))

DSC_1113.PNG Résultat de l'exécution (huître)
 {
    "labelAnnotations": [
      {
        "mid": "/m/0_cp5",
        "description": "Oyster",
        "score": 0.9910632,
        "topicality": 0.9910632
      },
      {
        "mid": "/m/02wbm",
        "description": "Food",
        "score": 0.9903261,
        "topicality": 0.9903261
      },
      {
        "mid": "/m/06nwz",
        "description": "Seafood",
        "score": 0.9609892,
        "topicality": 0.9609892
      },
      {
        "mid": "/m/01cqy9",
        "description": "Bivalve",
        "score": 0.9138548,
        "topicality": 0.9138548
      },
      {
        "mid": "/m/02q08p0",
        "description": "Dish",
        "score": 0.8472096,
        "topicality": 0.8472096
      },
      {
        "mid": "/m/01ykh",
        "description": "Cuisine",
        "score": 0.811229,
        "topicality": 0.811229
      },
      {
        "mid": "/m/07xgrh",
        "description": "Ingredient",
        "score": 0.8011539,
        "topicality": 0.8011539
      },
      {
        "mid": "/m/088kg2",
        "description": "Oysters rockefeller",
        "score": 0.70525026,
        "topicality": 0.70525026
      },
      {
        "mid": "/m/0fbdv",
        "description": "Shellfish",
        "score": 0.6510715,
        "topicality": 0.6510715
      },
      {
        "mid": "/m/0ffhy",
        "description": "Clam",
        "score": 0.6364975,
        "topicality": 0.6364975
      }
    ]
  }
DSC_1052.PNG Résultat de l'exécution (sushi)
  {
    "labelAnnotations": [
      {
        "mid": "/m/02q08p0",
        "description": "Dish",
        "score": 0.9934035,
        "topicality": 0.9934035
      },
      {
        "mid": "/m/01ykh",
        "description": "Cuisine",
        "score": 0.9864208,
        "topicality": 0.9864208
      },
      {
        "mid": "/m/02wbm",
        "description": "Food",
        "score": 0.97343695,
        "topicality": 0.97343695
      },
      {
        "mid": "/m/048wsd",
        "description": "Gimbap",
        "score": 0.96859926,
        "topicality": 0.96859926
      },
      {
        "mid": "/m/07030",
        "description": "Sushi",
        "score": 0.9650486,
        "topicality": 0.9650486
      },
      {
        "mid": "/m/0cjyd",
        "description": "Sashimi",
        "score": 0.9185767,
        "topicality": 0.9185767
      },
      {
        "mid": "/m/04q6ng",
        "description": "Comfort food",
        "score": 0.8544887,
        "topicality": 0.8544887
      },
      {
        "mid": "/m/07xgrh",
        "description": "Ingredient",
        "score": 0.8450334,
        "topicality": 0.8450334
      },
      {
        "mid": "/m/05jrv",
        "description": "Nori",
        "score": 0.8431285,
        "topicality": 0.8431285
      },
      {
        "mid": "/m/027lnr6",
        "description": "Sakana",
        "score": 0.8388547,
        "topicality": 0.8388547
      }
    ]
  }
DSC_0883.PNG Résultat de l'exécution (hamburger)
 {
    "labelAnnotations": [
      {
        "mid": "/m/02q08p0",
        "description": "Dish",
        "score": 0.9934035,
        "topicality": 0.9934035
      },
      {
        "mid": "/m/02wbm",
        "description": "Food",
        "score": 0.9903261,
        "topicality": 0.9903261
      },
      {
        "mid": "/m/01ykh",
        "description": "Cuisine",
        "score": 0.9864208,
        "topicality": 0.9864208
      },
      {
        "mid": "/m/0h55b",
        "description": "Junk food",
        "score": 0.9851551,
        "topicality": 0.9851551
      },
      {
        "mid": "/m/01_bhs",
        "description": "Fast food",
        "score": 0.97022384,
        "topicality": 0.97022384
      },
      {
        "mid": "/m/0cdn1",
        "description": "Hamburger",
        "score": 0.9571771,
        "topicality": 0.9571771
      },
      {
        "mid": "/m/0cc7bks",
        "description": "Buffalo burger",
        "score": 0.94575346,
        "topicality": 0.94575346
      },
      {
        "mid": "/m/03f476",
        "description": "Veggie burger",
        "score": 0.9283731,
        "topicality": 0.9283731
      },
      {
        "mid": "/m/0bp3f6m",
        "description": "Fried food",
        "score": 0.9257971,
        "topicality": 0.9257971
      },
      {
        "mid": "/m/02y6n",
        "description": "French fries",
        "score": 0.92217153,
        "topicality": 0.92217153
      }
    ]
  }
DSC_1050.PNG
Résultat de l'exécution (crevette)
  {
    "labelAnnotations": [
      {
        "mid": "/m/02q08p0",
        "description": "Dish",
        "score": 0.9934035,
        "topicality": 0.9934035
      },
      {
        "mid": "/m/02wbm",
        "description": "Food",
        "score": 0.9903261,
        "topicality": 0.9903261
      },
      {
        "mid": "/m/01ykh",
        "description": "Cuisine",
        "score": 0.9864208,
        "topicality": 0.9864208
      },
      {
        "mid": "/m/0g9vs81",
        "description": "Steamed rice",
        "score": 0.9271187,
        "topicality": 0.9271187
      },
      {
        "mid": "/m/07xgrh",
        "description": "Ingredient",
        "score": 0.9207317,
        "topicality": 0.9207317
      },
      {
        "mid": "/m/0bp3f6m",
        "description": "Fried food",
        "score": 0.9098738,
        "topicality": 0.9098738
      },
      {
        "mid": "/m/0dxjn",
        "description": "Deep frying",
        "score": 0.9049985,
        "topicality": 0.9049985
      },
      {
        "mid": "/m/0f99t",
        "description": "Tonkatsu",
        "score": 0.901048,
        "topicality": 0.901048
      },
      {
        "mid": "/m/0krfg",
        "description": "Meal",
        "score": 0.81980187,
        "topicality": 0.81980187
      },
      {
        "mid": "/m/04q6ng",
        "description": "Comfort food",
        "score": 0.8160322,
        "topicality": 0.8160322
      }
    ]
  }

Résultats de l'évaluation des photos culinaires avec l'API Cloud Vision

Non seulement les huîtres, les sushis et les hamburgers sont des aliments, mais les types sont également identifiés. On peut déterminer que la nourriture frite aux crevettes est frite, mais il semble qu'on ne puisse pas déterminer qu'il s'agit de "nourriture frite aux crevettes". Je l'ai essayé avec les photos non mentionnées dans cet article, mais en gros, il semblait être en mesure d'identifier le type de nourriture. Bien que le genre de nourriture frite soit facile à comprendre, il semble difficile d'identifier le type de photos avec les mêmes conditions que les crevettes frites, où les éléments de crevettes sont difficiles à comprendre sur l'image.

finalement

J'ai essayé la détection d'étiquettes cette fois, mais il semble que l'API Cloud Vision puisse également détecter la teinte de l'image. Si vous pouvez saisir la tendance de l'ombre des photos d'aliments, vous pourrez peut-être comprendre quel type d'ombre est délicieux. L'API de reconnaissance d'image elle-même est fournie par d'autres que Google, donc je pense qu'il est nécessaire de l'essayer également à l'avenir.

[^ 1]: Le fait de donner faim à ce que vous voyez en téléchargeant des photos de délicieux repas, par exemple à minuit

Recommended Posts