Tutorial de pistas de recorte

Audiencia

El objetivo de este tutorial es ayudarte a desarrollar aplicaciones con la función Sugerencias de recorte de la API Vision. Se da por supuesto que conoces las estructuras y las técnicas de programación básicas. Sin embargo, aunque seas un programador principiante, deberías poder seguir este tutorial y ejecutarlo sin dificultad, y luego usar la documentación de referencia de la API Vision para crear aplicaciones básicas.

En este tutorial se explica paso a paso una aplicación de la API Vision y se muestra cómo hacer una llamada a la API Vision para usar su función Sugerencias de recorte.

Requisitos previos

Información general

En este tutorial se explica cómo crear una aplicación básica de la API Vision que usa una Crop Hints solicitud. Puedes proporcionar la imagen que se va a procesar mediante un URI de Cloud Storage (ubicación del segmento de Cloud Storage) o insertándola en la solicitud. Una Crop Hints respuesta correcta devuelve las coordenadas de un cuadro delimitador recortado alrededor del objeto o la cara dominantes de la imagen.

Listado de código

Mientras lees el código, te recomendamos que consultes la referencia de Python de la API Cloud Vision.

import argparse

from typing import MutableSequence

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



def get_crop_hint(path: str) -> MutableSequence[vision.Vertex]:
    """Detect crop hints on a single image and return the first result.

    Args:
        path: path to the image file.

    Returns:
        The vertices for the bounding polygon.
    """
    client = vision.ImageAnnotatorClient()

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

    image = vision.Image(content=content)

    crop_hints_params = vision.CropHintsParams(aspect_ratios=[1.77])
    image_context = vision.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: str) -> None:
    """Draw a border around the image using the hints in the vector list.

    Args:
        image_file: path to the image file.
    """
    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: str) -> None:
    """Crop the image using the hints in the vector list.

    Args:
        image_file: path to the image file.
    """
    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)

Una mirada en profundidad

Importar bibliotecas

import argparse

from typing import MutableSequence

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

Importamos bibliotecas estándar:

  • argparse para permitir que la aplicación acepte nombres de archivo de entrada como argumentos
  • io para la E/S de archivos

Otras importaciones:

  • La clase ImageAnnotatorClient de la biblioteca google.cloud.vision para acceder a la API Vision.
  • El módulo types de la biblioteca google.cloud.vision para crear solicitudes
  • Los módulos Image y ImageDraw de Python Imaging Library (PIL). para dibujar un cuadro delimitador en la imagen de entrada.

Ejecutar la aplicación

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)

Aquí, simplemente analizamos el argumento transmitido que especifica el nombre de archivo de la imagen local y lo transmitimos a una función para recortar la imagen o dibujar la pista.

Autenticar a la API

Antes de comunicarte con el servicio de la API Vision, debes autenticar tu servicio con las credenciales que hayas obtenido previamente. En una aplicación, la forma más sencilla de obtener credenciales es usar las credenciales predeterminadas de la aplicación (ADC). De forma predeterminada, la biblioteca de cliente intentará obtener las credenciales de la variable de entorno GOOGLE_APPLICATION_CREDENTIALS, que debe configurarse para que apunte al archivo de clave JSON de tu cuenta de servicio (consulta Configurar una cuenta de servicio para obtener más información).

Obtener anotaciones de pistas de recorte de la imagen

Ahora que la biblioteca de cliente de Vision está autenticada, podemos acceder al servicio llamando al método crop_hints de la instancia ImageAnnotatorClient. La relación de aspecto de la salida se especifica en un objeto ImageContext. Si se proporcionan varias relaciones de aspecto, se devolverán varias sugerencias de recorte, una por cada relación de aspecto.

"""Detect crop hints on a single image and return the first result.

Args:
    path: path to the image file.

Returns:
    The vertices for the bounding polygon.
"""
client = vision.ImageAnnotatorClient()

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

image = vision.Image(content=content)

crop_hints_params = vision.CropHintsParams(aspect_ratios=[1.77])
image_context = vision.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

La biblioteca de cliente encapsula los detalles de las solicitudes y respuestas de la API. Consulta la referencia de la API Vision para obtener información completa sobre la estructura de una solicitud.

Usar la respuesta para recortar o dibujar el cuadro delimitador de la pista

Una vez que la operación se haya completado correctamente, la respuesta de la API contendrá las coordenadas del cuadro delimitador de uno o varios cropHints. El método draw_hint dibuja líneas alrededor del cuadro delimitador de CropHints y, a continuación, escribe la imagen en 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")

El método crop_to_hint recorta la imagen con el recorte sugerido.

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

Ejecutar la aplicación

Para ejecutar la aplicación, puedes descargar este archivo cat.jpg (puede que tengas que hacer clic con el botón derecho en el enlace) y, a continuación, pasar la ubicación donde descargaste el archivo en tu máquina local a la aplicación del tutorial (crop_hints.py).

A continuación se muestra el comando de Python, seguido del resultado de la consola, que muestra la respuesta JSON cropHintsAnnotation. Esta respuesta incluye las coordenadas del cuadro delimitador cropHints. Hemos solicitado un área de recorte con una relación de aspecto de 1,77 entre la anchura y la altura, y las coordenadas x e y de la esquina superior izquierda y de la esquina inferior derecha del rectángulo de recorte devueltas son 0,336 y 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
     }
    ]
   }
  }
 ]
}

Aquí tienes la imagen recortada.

¡Enhorabuena! Has ejecutado la API Crop Hints de Cloud Vision para obtener las coordenadas del cuadro delimitador optimizado del objeto dominante detectado en la imagen.