Tutoriel sur les possibilités de découpage

Audience

L'objectif de ce tutoriel est de vous aider à développer des applications à l'aide de la fonctionnalité Crop Hints (suggestions de cadrage) de l'API Cloud Vision. Nous partons du principe que vous maîtrisez les constructions et les techniques de programmation de base. Cependant, même si vous êtes un programmeur débutant, vous devriez être capable de suivre et d'exécuter ce tutoriel sans difficulté, puis d'utiliser la Documentation de référence de l'API Vision pour créer des applications de base.

Ce tutoriel décrit une application de l'API Vision montrant comment faire appel à cette API pour utiliser la fonctionnalité de suggestions de recadrage.

Prérequis

Python

Présentation

Ce tutoriel vous présente une application de base de l'API Vision, qui utilise une requête Crop Hints. Vous pouvez fournir l'image à traiter via un URI Cloud Storage (emplacement du bucket Cloud Storage) ou intégrée à la requête. Une réponse Crop Hints réussie renvoie les coordonnées d'un cadre de délimitation autour de l'objet ou du visage dominant dans l'image.

Intégralité du code

Lors de la lecture du code, nous vous recommandons de vous reporter également la documentation de référence de l'API Cloud Vision pour Python.

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)

Gros plan sur

Importer des bibliothèques

import argparse

from typing import MutableSequence

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

Nous importons des bibliothèques standards :

  • argparse pour autoriser l'application à accepter les noms de fichiers d'entrée comme arguments
  • io pour les E/S des fichiers

Autres importations :

  • La classe ImageAnnotatorClient de la bibliothèque google.cloud.vision pour l'accès à l'API Vision.
  • Le module types de la bibliothèque google.cloud.vision pour la création des requêtes
  • Les modules Image et ImageDraw du Python Imaging Library (PIL) pour tracer une zone de délimitation sur l'image d'entrée.

Exécuter l'application

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)

Ici, nous analysons simplement l'argument transmis qui spécifie le nom de fichier de l'image locale et nous le transmettons à une fonction pour recadrer l'image ou tracer la zone de recadrage suggérée.

S'authentifier dans l'API

Avant de communiquer avec le service de l'API Vision, 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 bibliothèque cliente tente d'obtenir les identifiants de la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS, laquelle doit être définie de manière à pointer sur le fichier de clé JSON de votre compte de service (consultez la section Configurer un compte de service pour en savoir plus).

Obtenir des annotations de suggestions de recadrage pour l’image

Maintenant que la bibliothèque cliente Vision est authentifiée, nous pouvons accéder au service en appelant la méthode crop_hints de l'instance ImageAnnotatorClient. Le format de la sortie est spécifié dans un objet ImageContext. Si plusieurs formats sont transmis, plusieurs suggestions de recadrage sont renvoyées, une pour chaque format.

"""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 bibliothèque cliente encapsule les informations sur les requêtes adressées à l'API et sur les réponses obtenues. Voir la documentation de référence de l'API Vision pour obtenir des informations complètes sur la structure d'une requête

Utiliser la réponse pour recadrer ou dessiner le cadre de délimitation suggéré

Une fois l'opération terminée, la réponse de l'API contient les coordonnées du cadre de délimitation d'une ou de plusieurs valeurs cropHint. La méthode draw_hint dessine des lignes autour du cadre de délimitation CropHints, puis écrit l'image dans 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")

La méthode crop_to_hint recadre l'image en fonction de la zone de recadrage suggérée.

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

Exécuter l'application

Pour exécuter l'application, vous pouvez télécharger ce fichier cat.jpg (vous devrez peut-être effectuer un clic droit sur le lien), puis transmettre l'emplacement du fichier téléchargé sur votre machine locale à l'application de tutoriel (crop_hints.py).

Voici la commande Python, suivie de la sortie de la console, qui affiche la réponse JSON cropHintsAnnotation. Cette réponse inclut les coordonnées du cadre de délimitation cropHints. Nous avons demandé une zone de recadrage avec un ratio largeur/hauteur de 1,77. Les coordonnées x,y renvoyées en haut à gauche et en bas à droite du rectangle de recadrage sont 0,336, 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
     }
    ]
   }
  }
 ]
}

Voici l'image recadrée.

Félicitations ! Vous avez exécuté l'API Crop Hints de Cloud Vision pour renvoyer les coordonnées optimisées du cadre de délimitation autour de l'objet dominant détecté dans l'image !