Instructivo de detección de etiquetas

Público

Este instructivo está diseñado para ayudarte a comenzar a explorar y desarrollar aplicaciones con la API de Video Intelligence. Está diseñada para personas con conocimientos básicos de Python. Además, deberías poder seguir adelante con conocimientos limitados de programación. Una vez que completes este instructivo, deberías poder usar la Documentación de referencia para crear tus propias aplicaciones básicas.

En este instructivo, se explica paso a paso una aplicación de la API de Video Intelligence que usa el código de Python. El propósito no es explicar las bibliotecas cliente de Python, sino cómo realizar llamadas a la API de Video Intelligence con la función de detección de etiquetas de video. En esencia, las aplicaciones en Java y Node.js son similares.

Si buscas un ejemplo de código único o un ejemplo en otro lenguaje, consulta la guía práctica complementaria.

Requisitos

Este instructivo tiene los siguientes requisitos previos:

Anota un video con la detección de etiquetas

En este instructivo, se explica cómo es una aplicación básica de la API de video, mediante una solicitud LABEL_DETECTION. Una solicitud LABEL_DETECTION anota un video con etiquetas que se seleccionan en función del contenido de la imagen. Por ejemplo, un video de un tren en un cruce puede producir etiquetas como “tren”, “transporte” y “cruce ferroviario”.

El siguiente es el código completo necesario para este instructivo. Se quitaron la mayoría de los comentarios de este código para destacar lo breve que es. En su lugar, se proporcionan más adelante, a medida que repasamos el código.

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)

Esta aplicación simple ejecuta las siguientes tareas:

  1. Importa las bibliotecas necesarias para ejecutar la aplicación.
  2. Toma un archivo de video almacenado en el URI de Cloud Storage como un argumento y lo pasa a la función main().
  3. Obtiene las credenciales para ejecutar el servicio de la API de Video Intelligence.
  4. Crea una solicitud de anotación de video para enviar al servicio de video.
  5. Envía la solicitud y muestra una operación de larga duración.
  6. Repite de forma indefinida la operación de larga duración hasta que el video se procese y muestre los valores disponibles.
  7. Analiza la respuesta del servicio y muestra la respuesta al usuario.

Importa las bibliotecas

import argparse

from google.cloud import videointelligence

Se importan algunas bibliotecas estándar: argparse para permitir que la aplicación acepte nombres de archivos de entrada como argumentos y sys para formatear el resultado mientras espera las respuestas de la API. Se importa el paquete time para ejecutar algunos bucles de espera simples.

Cuando uses la API de Video Intelligence, también deberás importar el google.cloud.videointelligence_v1 y su clase de enumeración, que contiene el directorio de nuestras llamadas a la API.

Ejecuta la aplicación

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)

Aquí, el argumento pasado se analiza para el URI de Cloud Storage del nombre del archivo de video y se pasa a la función main().

Autenticación en la API

Antes de comunicarte con el servicio de la API de Video Intelligence, debes autenticar tu servicio con las credenciales ya adquiridas. Dentro de una aplicación, la manera más simple de obtener credenciales es usar las Credenciales predeterminadas de la aplicación (ADC). De forma predeterminada, las ADC intentan obtener credenciales del archivo de entorno GOOGLE_APPLICATION_CREDENTIALS, que debe configurarse para que apunte al archivo de claves JSON de tu cuenta de servicio. (Debes haber configurado tu cuenta de servicio y tu entorno para usar las ADC en la Guía de inicio rápido.

Crea la solicitud

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

Ahora que el servicio de la API de Video Intelligence está listo, puedes crear una solicitud para ese servicio. Las solicitudes a la API de Video Intelligence se proporcionan como objetos JSON. Consulta la referencia de la API de Video Intelligence para obtener información completa sobre la estructura específica de esta solicitud.

Este fragmento de código realiza las siguientes tareas:

  1. Construye el JSON para una solicitud POST al método annotate_video().
  2. Inserta la ubicación de Cloud Storage del nombre del archivo de video que se pasó en la solicitud.
  3. Indica que el método annotate debe realizar una LABEL_DETECTION.

Verifica la operación

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

Con la solicitud de operación existente para la operación existente, se construye un bucle while a fin de verificar de forma periódica el estado de esa operación. Una vez que la operación indica que la operación es done, se analiza la respuesta.

Analiza la respuesta

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

Una vez que se haya completado la operación, la respuesta contendrá el resultado en una AnnotateVideoResponse, que consiste en una lista de annotationResults, uno para cada video enviado en la solicitud. Debido a que solo se envió un video en la solicitud, se toma el primer segmentLabelAnnotations de los resultados y se repiten todas las etiquetas en segmentLabelAnnotations. Cuando usas solo segmentLabelAnnotations, en este instructivo solo se muestran anotaciones a nivel del video. Cada segment_label incluye una descripción (segment_label.description), una lista de categorías de entidades (segment_label.category_entities) y una lista de segmentos que identifican la hora de inicio y finalización de los casos de etiqueta en el video (debe ser un segmento que abarque todo el video o el segmento del video para el caso de 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
                  }
                ]
              },
               ...
            ]
         }
      ]
   }
}

Debido a que solo se envió un video en la solicitud, se imprimirá el primer description del primer resultado.

Ejecuta tu aplicación

Para ejecutar la aplicación, solo pasa el URI de Cloud Storage de un video:

$ 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
...
 

Resultado

A continuación, se muestra un resultado posible.

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

¡Felicitaciones! Realizaste una tarea de anotación con la API de Video Intelligence.