Tutorial de detecção de alteração de imagem

Público

Este tutorial foi criado para possibilitar a exploração e o desenvolvimento de aplicativos com a API Video Intelligence. Ele se destina a pessoas familiarizadas com a programação básica. Porém, mesmo sem muito conhecimento de programação, você deverá ser capaz de acompanhar. Após concluir este tutorial, você estará apto a usar a Documentação de referência para criar seus aplicativos básicos.

Neste tutorial, vamos trabalhar com um aplicativo da Video Intelligence API usando o código Python. O objetivo aqui não é explicar as bibliotecas de cliente Python, mas explicar como fazer chamadas para a API Video Intelligence. Aplicativos em Java e Node.js são basicamente similares.

Se você está procurando um exemplo somente de código ou em outra linguagem, consulte o guia de instruções complementar.

Pré-requisitos

Os pré-requisitos para este tutorial são:

Como anotar um vídeo usando a detecção de alteração de imagem

Veja neste tutorial um aplicativo básico da Video API que usa uma solicitação SHOT_CHANGE_DETECTION. Uma solicitação SHOT_CHANGE_DETECTION fornece os resultados da anotação:

  • Lista de todas as imagens do vídeo
  • Fornece a hora inicial e final de cada imagem

Primeiro, mostraremos todo o código. Retiramos grande parte dos comentários desse código para você ver como ele é curto. Forneceremos mais comentários à medida que analisarmos o código.

import argparse

from google.cloud import videointelligence

def analyze_shots(path):
    """ Detects camera shot changes. """
    video_client = videointelligence.VideoIntelligenceServiceClient()
    features = [videointelligence.enums.Feature.SHOT_CHANGE_DETECTION]
    operation = video_client.annotate_video(input_uri=path, features=features)
    print('\nProcessing video for shot change annotations:')

    result = operation.result(timeout=120)
    print('\nFinished processing.')

    for i, shot in enumerate(result.annotation_results[0].shot_annotations):
        start_time = (shot.start_time_offset.seconds +
                      shot.start_time_offset.nanos / 1e9)
        end_time = (shot.end_time_offset.seconds +
                    shot.end_time_offset.nanos / 1e9)
        print('\tShot {}: {} to {}'.format(i, start_time, end_time))

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

    analyze_shots(args.path)

Esse aplicativo simples:

  • Importa as bibliotecas necessárias para executar o aplicativo.
  • Usa um arquivo de vídeo armazenado no URI do Cloud Storage como um argumento e transmita-o para a função main().
  • Recebe credenciais para executar o serviço da API Video Intelligence.
  • Cria uma solicitação de anotação de vídeo para enviar ao serviço de vídeo.
  • Envia a solicitação e retorna uma operação de longa duração.
  • Repete a operação de longa duração até o vídeo ser processado e retorna valores disponíveis.
  • Analisa a resposta do serviço e exibe a resposta para o usuário.

A seguir, veja essas etapas com mais detalhes.

Como importar bibliotecas

import argparse

from google.cloud import videointelligence

É preciso importar argparse para que o aplicativo aceite nomes de arquivos de entrada como argumentos.

Para usar a API Cloud Video Intelligence, também importamos a biblioteca google.cloud.videointelligence, que contém o diretório das chamadas de API e das constantes de enumeração.

Como executar o aplicativo

parser = argparse.ArgumentParser(
    description=__doc__,
    formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('path', help='GCS path for shot change detection.')
args = parser.parse_args()

analyze_shots(args.path)

Aqui, analisamos o argumento passado para a URI do Storage do nome do arquivo de vídeo e o transmitimos para a função main().

Como autenticar na API

Antes de iniciar a comunicação com o serviço da API Video Intelligence, autentique seu serviço usando as credenciais recebidas anteriormente. A maneira mais simples de receber credenciais em um aplicativo é usar o Application Default Credentials (ADC). No ADC, as credenciais são adquiridas a partir do arquivo de ambiente GOOGLE_APPLICATION_CREDENTIALS por padrão. Ele precisa apontar para o arquivo da chave JSON da sua conta de serviço. É necessário configurar essa conta de serviço e o ambiente para usar o ADC no Guia de início rápido. Para ver mais informações, consulte Como configurar uma conta de serviço.

Como criar a solicitação

video_client = videointelligence.VideoIntelligenceServiceClient()
features = [videointelligence.enums.Feature.SHOT_CHANGE_DETECTION]
operation = video_client.annotate_video(input_uri=path, features=features)

Agora que o serviço da Video Intelligence API está pronto, criaremos uma solicitação para ele. As solicitações a essa API são fornecidas como objetos JSON. Consulte a Referência da Video Intelligence API para informações completas sobre a estrutura específica da solicitação.

Esse snippet de código executa as seguintes tarefas:

  1. Cria o JSON de uma solicitação POST para o método annotate_video().
  2. Injeta na solicitação o local do nome do arquivo de vídeo transmitido no Google Cloud Storage.
  3. Indica que o método annotate deve executar SHOT_CHANGE_DETECTION.

Como criar a operação de longa duração

Na primeira vez que executamos uma solicitação para a API Video Intelligence, o resultado não é imediato. Em vez disso, recebemos o nome da operação, armazenado no campo name da resposta, que usaremos para verificar os resultados posteriormente.

Quando o nome (uma string numérica) dessa operação é transmitido para o serviço de operações da API Video Intelligence, o método operations retorna o estado atual da operação. Veja um exemplo de resposta:

{
   "response":{
      "@type":"type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoResponse"
   },
   "name":"us-west1.17159971042783089144",
   "metadata":{
      "annotationProgress":[
         {
            "inputUri":"/demomaker/gbikes_dinosaur.mp4",
            "updateTime":"2017-01-27T19:45:54.297807Z",
            "startTime":"2017-01-27T19:45:54.275023Z"
         }
      ],
      "@type":"type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoProgress"
   }
}

No momento, o campo response contém apenas um campo @type, indicando o tipo dessa resposta. Quando os resultados estiverem realmente disponíveis, o campo da resposta conterá os resultados desse tipo.

Como verificar a operação

result = operation.result(timeout=120)
print('\nFinished processing.')

Com a solicitação da operação existente, vamos criar uma repetição while para verificar periodicamente o estado dessa operação. Quando a operação indicar que está done, interromperemos a repetição e analisaremos a resposta.

Como analisar a resposta

for i, shot in enumerate(result.annotation_results[0].shot_annotations):
    start_time = (shot.start_time_offset.seconds +
                  shot.start_time_offset.nanos / 1e9)
    end_time = (shot.end_time_offset.seconds +
                shot.end_time_offset.nanos / 1e9)
    print('\tShot {}: {} to {}'.format(i, start_time, end_time))

Quando a operação for concluída, a resposta conterá um AnnotateVideoResponse, que consiste em uma lista de annotationResults, um para cada vídeo enviado na solicitação. Como enviamos apenas um vídeo na solicitação, selecionamos a primeira shotAnnotations dos resultados. Vamos percorrer todos os segmentos do vídeo.

Como executar o aplicativo

Para executar nosso aplicativo, basta passar o URI do Cloud Storage de um vídeo:

$ python shotchange.py gs://demomaker/gbikes_dinosaur.mp4
operationId=us-west1.12468772851081463748
Operation us-west1.12468772851081463748 started: 2017-01-30T01:53:45.981043Z
Processing video for shot change annotations:
Finished processing.
  Shot 0: 0.0 to 5.166666
  Shot 1: 5.233333 to 10.066666
  Shot 2: 10.1 to 28.133333
  Shot 3: 28.166666 to 42.766666

Parabéns! Você executou uma tarefa de anotação usando a API Video Intelligence.