Didacticiel de détection de thèmes

Cible

Ce tutoriel est conçu pour vous aider à explorer et à développer des applications avec l'API Video Intelligence. Elle est destinée aux personnes qui maîtrisent les bases en Python. Vous devez également être capable de suivre ce tutoriel avec des connaissances limitées en programmation. Après avoir parcouru ce tutoriel, vous devriez pouvoir créer vos propres applications de base à l'aide de la documentation de référence.

Ce tutoriel vous présente une application de l'API Video Intelligence avec du code Python. Il ne s'agit pas ici d'expliquer les bibliothèques clientes Python, mais d'expliquer comment effectuer des appels à l'API Video Intelligence à l'aide de la fonctionnalité de détection de thèmes vidéo. Les applications Java et Node.js sont similaires pour l'essentiel.

Si vous recherchez uniquement un exemple de code ou un exemple dans un autre langage, consultez le guide pratique associé.

Prérequis

Les prérequis de ce tutoriel sont les suivants :

Annoter une vidéo à l'aide de la détection de thèmes

Ce tutoriel vous présente une application de base de l'API Video à l'aide d'une requête LABEL_DETECTION. Une requête LABEL_DETECTION annote une vidéo avec des thèmes (ou "tags") sélectionnés en fonction du contenu de l'image. Par exemple, la vidéo d'un train à un passage à niveau peut produire des thèmes tels que "train", "transports", "passage à niveau".

Vous trouverez ci-dessous l'intégralité du code nécessaire à la réalisation de ce tutoriel. La plupart des commentaires ont été supprimés de ce code pour mettre en évidence son caractère bref. Au lieu de cela, nous les commentons plus tard, lorsque nous passons en revue le code.

import argparse

from google.cloud import videointelligence

def analyze_labels(path):
    """ Detects labels given a GCS path. """
    video_client = videointelligence.VideoIntelligenceServiceClient()
    features = [videointelligence.Feature.LABEL_DETECTION]
    operation = video_client.annotate_video(
        request={"features": features, "input_uri": path}
    )
    print("\nProcessing video for label annotations:")

    result = operation.result(timeout=90)
    print("\nFinished processing.")

    segment_labels = result.annotation_results[0].segment_label_annotations
    for i, segment_label in enumerate(segment_labels):
        print("Video label description: {}".format(segment_label.entity.description))
        for category_entity in segment_label.category_entities:
            print(
                "\tLabel category description: {}".format(category_entity.description)
            )

        for i, segment in enumerate(segment_label.segments):
            start_time = (
                segment.segment.start_time_offset.seconds
                + segment.segment.start_time_offset.microseconds / 1e6
            )
            end_time = (
                segment.segment.end_time_offset.seconds
                + segment.segment.end_time_offset.microseconds / 1e6
            )
            positions = "{}s to {}s".format(start_time, end_time)
            confidence = segment.confidence
            print("\tSegment {}: {}".format(i, positions))
            print("\tConfidence: {}".format(confidence))
        print("\n")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
    )
    parser.add_argument("path", help="GCS file path for label detection.")
    args = parser.parse_args()

    analyze_labels(args.path)

Cette application simple effectue les tâches suivantes :

  1. Elle importe les bibliothèques nécessaires pour exécuter l'application.
  2. Elle utilise un fichier vidéo stocké dans l'URI Cloud Storage en tant qu'argument et le transmet à la fonction main().
  3. Elle obtient les identifiants permettant d'exécuter le service de l'API Video Intelligence.
  4. Elle crée une requête d'annotation vidéo à destination du service vidéo.
  5. Elle envoie la requête et renvoie une opération de longue durée.
  6. Elle boucle sur l'opération de longue durée jusqu'à ce que la vidéo soit traitée et renvoie les valeurs disponibles.
  7. Elle analyse la réponse du service et envoie la réponse à l'utilisateur.

Importer des bibliothèques

import argparse

from google.cloud import videointelligence

Certaines bibliothèques standards sont importées : argparse pour permettre à l'application d'accepter les noms de fichiers d'entrée en tant qu'arguments et sys pour formater la sortie en attendant les réponses de l'API. Le package time est importé pour exécuter des boucles d'attente simples.

Lorsque vous utilisez l'API Video Intelligence, vous devez également importer google.cloud.videointelligence_v1 et sa classe d'énumération, qui contient le répertoire de nos appels d'API.

Exécuter l'application

parser = argparse.ArgumentParser(
    description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument("path", help="GCS file path for label detection.")
args = parser.parse_args()

analyze_labels(args.path)

Ici, l'argument transmis est analysé pour l'URI Cloud Storage du nom du fichier vidéo et transmis à la fonction main().

S'authentifier sur l'API

Avant de communiquer avec le service de l'API Video Intelligence, vous devez authentifier votre service avec les identifiants précédemment acquis. Dans une application, le moyen le plus simple d'obtenir des identifiants est d'utiliser les identifiants par défaut de l'application. Par défaut, la stratégie des identifiants par défaut de l'application (ADC, Application Default Credential) tente d'obtenir les identifiants à partir du fichier d'environnement GOOGLE_APPLICATION_CREDENTIALS, qui doit être défini pour pointer vers le fichier de clé JSON de votre compte de service. (Vous devez avoir configuré votre compte de service et votre environnement pour utiliser cette stratégie ADC dans le guide de démarrage rapide.

Créer la requête

video_client = videointelligence.VideoIntelligenceServiceClient()
features = [videointelligence.Feature.LABEL_DETECTION]
operation = video_client.annotate_video(
    request={"features": features, "input_uri": path}
)

Maintenant que le service de l'API Video Intelligence est prêt, vous pouvez créer une requête vers ce service. Les requêtes adressées à l'API Video Intelligence sont fournies en tant qu'objets JSON. Consultez le document de référence de l'API Video Intelligence pour obtenir des informations complètes sur la structure spécifique d'une telle requête.

Cet extrait de code effectue les tâches suivantes :

  1. Il génère le fichier JSON pour une requête POST vers la méthode annotate_video().
  2. Il intègre l'emplacement Cloud Storage du nom de fichier vidéo transmis dans la requête.
  3. Il indique que la méthode annotate doit exécuter une requête LABEL_DETECTION.

Vérifier l'opération

result = operation.result(timeout=90)
print("\nFinished processing.")

La requête d'opération existante pour l'opération existante permet de créer une boucle while pour vérifier régulièrement l'état de cette opération. Une fois que l'opération indique que l'opération est done, la réponse est analysée.

Analyser la réponse

segment_labels = result.annotation_results[0].segment_label_annotations
for i, segment_label in enumerate(segment_labels):
    print("Video label description: {}".format(segment_label.entity.description))
    for category_entity in segment_label.category_entities:
        print(
            "\tLabel category description: {}".format(category_entity.description)
        )

    for i, segment in enumerate(segment_label.segments):
        start_time = (
            segment.segment.start_time_offset.seconds
            + segment.segment.start_time_offset.microseconds / 1e6
        )
        end_time = (
            segment.segment.end_time_offset.seconds
            + segment.segment.end_time_offset.microseconds / 1e6
        )
        positions = "{}s to {}s".format(start_time, end_time)
        confidence = segment.confidence
        print("\tSegment {}: {}".format(i, positions))
        print("\tConfidence: {}".format(confidence))
    print("\n")

Une fois l'opération terminée, le résultat est contenu dans une réponse AnnotateVideoResponse, qui consiste en une liste de annotationResults, un pour chaque vidéo envoyée dans la requête. Étant donné qu'une seule vidéo a été envoyée dans la requête, les premiers résultats segmentLabelAnnotations sont pris en compte. Par conséquent, tous les libellés de segmentLabelAnnotations sont mis en boucle. En n'utilisant que segmentLabelAnnotations, ce tutoriel n'affiche que les annotations au niveau de la vidéo. Chaque segment_label comprend une description (segment_label.description), une liste de catégories d'entités (segment_label.category_entities) et une liste de segments identifiant l'heure de début/fin des occurrences de libellés dans la vidéo (il doit s'agir d'un segment couvrant l'ensemble de la vidéo ou la séquence vidéo pour segment_label_annotations).

{
   "name":"us-west1.12089999971048628582",
   "metadata":{
      "@type":"type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoProgress",
      "annotationProgress":[
         {
            "inputUri":"gs://YOUR_BUCKET/YOUR_OBJECT",
            "updateTime":"2020-01-31T01:49:52.498015Z",
            "startTime":"2020-01-31T01:49:43.056481Z"
         }
      ]
   },
   "done": true,
   "response":{
      "@type":"type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoResponse",
      "annotationResults":[
         {
            "inputUri":"gs://YOUR_BUCKET/YOUR_OBJECT",
            "segmentLabelAnnotations": [
              {
                "entity": {
                  "entityId": "/m/01yrx",
                  "languageCode": "en-US"
                },
                "segments": [
                  {
                    "segment": {
                      "startTimeOffset": "0s",
                      "endTimeOffset": "14.833664s"
                    },
                    "confidence": 0.98509187
                  }
                ]
              },
               ...
            ]
         }
      ]
   }
}

Étant donné qu'une seule vidéo a été envoyée dans la requête, la première description du premier résultat est imprimée.

Exécuter votre application

Pour exécuter votre application, transmettez-lui simplement l'URI Cloud Storage d'une vidéo :

$ python labels.py gs://YOUR_BUCKET/YOUR_OBJECT
Operation us-west1.4757250774497581229 started: 2020-01-30T01:46:30.158989Z
Operation processing ...
The video has been successfully processed.

Video label description: urban area
        Label category description: city
        Segment 0: 0.0s to 38.752016s
        Confidence: 0.946980476379

Video label description: traffic
        Segment 0: 0.0s to 38.752016s
        Confidence: 0.94105899334

Video label description: vehicle
        Segment 0: 0.0s to 38.752016s
        Confidence: 0.919958174229
...
 

Sortie

Vous trouverez ci-dessous un exemple de résultat possible.

Processing video for label annotations:

Finished processing. Video label description: crowd Label category description: people Segment 0: 0.0s to 60.24s Confidence: 0.527720749378

Video label description: official Label category description: person Segment 0: 0.0s to 60.24s Confidence: 0.372822880745

Video label description: audience Label category description: people Segment 0: 0.0s to 60.24s Confidence: 0.501719772816

Video label description: news Segment 0: 0.0s to 60.24s Confidence: 0.867252230644

Video label description: people Label category description: person Segment 0: 0.0s to 60.24s Confidence: 0.46747264266

Video label description: politics Segment 0: 0.0s to 60.24s Confidence: 0.319397002459

Félicitations ! Vous avez réalisé une annotation à l'aide de l'API Video Intelligence.