Tutorial sobre dicas de corte

Público

O objetivo deste tutorial é ajudar você a desenvolver aplicativos usando o recurso Dicas de corte da API Vision. Você precisa conhecer as construções e técnicas básicas de programação. No entanto, mesmo se você for um programador iniciante, poderá seguir e executar este tutorial sem dificuldade. Em seguida, use a documentação de referência da API Vision para criar aplicativos básicos.

Este tutorial aborda um aplicativo da API do Vision e mostra como fazer uma chamada a ela para usar o recurso de dicas de corte.

Pré-requisitos

Python

Visão geral

Neste tutorial, apresentamos um aplicativo básico da API do Vision que usa uma solicitação Crop Hints. É possível fornecer a imagem a ser processada por meio de um URI do Cloud Storage (localização do bucket do Cloud Storage) ou da incorporação na solicitação. Uma resposta Crop Hints correta retorna as coordenadas de uma caixa delimitadora recortada ao redor do objeto ou rosto dominante na imagem.

Listagem de códigos

Durante a leitura do código, recomendamos que você consulte a referência da Cloud Vision API para Python.

import argparse
import io

from google.cloud import vision
from google.cloud.vision import types
from PIL import Image, ImageDraw

def get_crop_hint(path):
    """Detect crop hints on a single image and return the first result."""
    client = vision.ImageAnnotatorClient()

    with io.open(path, 'rb') as image_file:
        content = image_file.read()

    image = types.Image(content=content)

    crop_hints_params = types.CropHintsParams(aspect_ratios=[1.77])
    image_context = types.ImageContext(crop_hints_params=crop_hints_params)

    response = client.crop_hints(image=image, image_context=image_context)
    hints = response.crop_hints_annotation.crop_hints

    # Get bounds for the first crop hint using an aspect ratio of 1.77.
    vertices = hints[0].bounding_poly.vertices

    return vertices

def draw_hint(image_file):
    """Draw a border around the image using the hints in the vector list."""
    vects = get_crop_hint(image_file)

    im = Image.open(image_file)
    draw = ImageDraw.Draw(im)
    draw.polygon([
        vects[0].x, vects[0].y,
        vects[1].x, vects[1].y,
        vects[2].x, vects[2].y,
        vects[3].x, vects[3].y], None, 'red')
    im.save('output-hint.jpg', 'JPEG')
    print('Saved new image to output-hint.jpg')

def crop_to_hint(image_file):
    """Crop the image using the hints in the vector list."""
    vects = get_crop_hint(image_file)

    im = Image.open(image_file)
    im2 = im.crop([vects[0].x, vects[0].y,
                  vects[2].x - 1, vects[2].y - 1])
    im2.save('output-crop.jpg', 'JPEG')
    print('Saved new image to output-crop.jpg')

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('image_file', help='The image you\'d like to crop.')
    parser.add_argument('mode', help='Set to "crop" or "draw".')
    args = parser.parse_args()

    if args.mode == 'crop':
        crop_to_hint(args.image_file)
    elif args.mode == 'draw':
        draw_hint(args.image_file)

Mais detalhes

Como importar bibliotecas

import argparse
import io

from google.cloud import vision
from google.cloud.vision import types
from PIL import Image, ImageDraw

Importamos bibliotecas padrão:

  • argparse para permitir que o aplicativo aceite nomes de arquivo de entrada como argumentos;
  • io para E/S de arquivos.

Outras importações:

  • A classe ImageAnnotatorClient na biblioteca google.cloud.vision para acessar a API Vision.
  • O módulo types na biblioteca google.cloud.vision para criar solicitações.
  • Os módulos Image e ImageDraw de Python Imaging Library (PIL) para desenhar uma caixa delimitadora na imagem de entrada.

Como executar o aplicativo

parser = argparse.ArgumentParser()
parser.add_argument('image_file', help='The image you\'d like to crop.')
parser.add_argument('mode', help='Set to "crop" or "draw".')
args = parser.parse_args()

if args.mode == 'crop':
    crop_to_hint(args.image_file)
elif args.mode == 'draw':
    draw_hint(args.image_file)

Aqui, simplesmente analisamos o argumento transmitido que especifica o nome de arquivo da imagem local. Além disso, encaminhamos para uma função que corta a imagem ou desenha a dica.

Como autenticar na API

Antes de se comunicar com a API Vision, você precisa autenticar seu serviço usando as credenciais já adquiridas. A maneira mais simples de receber credenciais em um aplicativo é usar o Application Default Credentials (ADC). Por padrão, a biblioteca de cliente tentará conseguir as credenciais da variável de ambiente GOOGLE_APPLICATION_CREDENTIALS. Ela precisa ser configurada para indicar o arquivo de chave JSON da sua conta de serviço. Consulte Configurar uma conta de serviço para mais informações.

Como receber anotações de dicas de corte para a imagem

Agora que a biblioteca de cliente Vision está autenticada, podemos acessar o serviço chamando o método crop_hints da instância ImageAnnotatorClient. A proporção para saída é especificada em um objeto ImageContext. Se várias proporções forem transmitidas, várias dicas de corte serão retornadas, uma para cada proporção.

"""Detect crop hints on a single image and return the first result."""
client = vision.ImageAnnotatorClient()

with io.open(path, 'rb') as image_file:
    content = image_file.read()

image = types.Image(content=content)

crop_hints_params = types.CropHintsParams(aspect_ratios=[1.77])
image_context = types.ImageContext(crop_hints_params=crop_hints_params)

response = client.crop_hints(image=image, image_context=image_context)
hints = response.crop_hints_annotation.crop_hints

# Get bounds for the first crop hint using an aspect ratio of 1.77.
vertices = hints[0].bounding_poly.vertices

A biblioteca de cliente inclui os detalhes das solicitações e respostas para a API. Consulte a Referência da API do Vision para saber informações sobre a estrutura de uma solicitação.

Como usar a resposta para cortar ou desenhar a caixa delimitadora da dica

Quando a operação for concluída, a resposta da API conterá as coordenadas da caixa delimitadora de um ou mais cropHints. O método draw_hint desenha linhas em torno da caixa delimitadora CropHints e, em seguida, grava a imagem em output-hint.jpg.

vects = get_crop_hint(image_file)

im = Image.open(image_file)
draw = ImageDraw.Draw(im)
draw.polygon([
    vects[0].x, vects[0].y,
    vects[1].x, vects[1].y,
    vects[2].x, vects[2].y,
    vects[3].x, vects[3].y], None, 'red')
im.save('output-hint.jpg', 'JPEG')
print('Saved new image to output-hint.jpg')

O método crop_to_hint corta a imagem usando a dica de corte sugerida.

vects = get_crop_hint(image_file)

im = Image.open(image_file)
im2 = im.crop([vects[0].x, vects[0].y,
              vects[2].x - 1, vects[2].y - 1])
im2.save('output-crop.jpg', 'JPEG')
print('Saved new image to output-crop.jpg')

Como executar o aplicativo

Para executar o aplicativo, faça o download deste arquivo cat.jpg (talvez seja necessário clicar com o botão direito no link) e transmita o local onde você fez o download do arquivo em sua máquina local para o aplicativo do tutorial (crop_hints.py).

Este é o comando Python, seguido pela saída do console que exibe a resposta JSON cropHintsAnnotation. A resposta inclui as coordenadas da caixa delimitadora cropHints. Solicitamos uma área de corte com proporção de 1,77 de largura por altura. As coordenadas X e Y retornadas da parte superior esquerda à inferior direita são 0,336 e 1100,967.

python crop_hints.py cat.jpeg crop
{
 "responses": [
  {
   "cropHintsAnnotation": {
    "cropHints": [
     {
      "boundingPoly": {
       "vertices": [
        {
         "y": 336
        },
        {
         "x": 1100,
         "y": 336
        },
        {
         "x": 1100,
         "y": 967
        },
        {
         "y": 967
        }
       ]
      },
      "confidence": 0.79999995,
      "importanceFraction": 0.69
     }
    ]
   }
  }
 ]
}

Esta é a imagem cortada:

Parabéns! Você executou a API Cloud Vision Crop Hints. Com isso, conseguiu retornar as coordenadas otimizadas da caixa delimitadora em torno do principal objeto detectado na imagem.