Anleitung für Zuschneidehinweise

Zielgruppe

Diese Anleitung soll Ihnen die Anwendungsentwicklung mit dem Feature "Zuschneidehinweise" der Vision API erleichtern. Es wird davon ausgegangen, dass Sie mit grundlegenden Programmierkonstrukten und -techniken vertraut sind. Aber auch als Einsteiger in die Programmierarbeit sollten Sie dieser Anleitung gut folgen und im Anschluss unter Verwendung der Referenzdokumentation für die Cloud Vision API einfache Anwendungen erstellen können.

Sie werden in dieser Anleitung durch eine Vision API-Anwendung geführt. Darin erfahren Sie, wie Sie die Vision API bezüglich der Verwendung der Funktion "Zuschneidehinweise" anrufen.

Vorbereitung

Überblick

In dieser Anleitung wird eine grundlegende Vision API-Anwendung erläutert, bei der eine Crop Hints-Anfrage verwendet wird. Sie können das zu verarbeitende Bild entweder über einen Cloud Storage-URI (Standort des Cloud Storage-Buckets) angeben oder in die Anfrage einbetten. Eine erfolgreiche Crop Hints-Antwort gibt die Koordinaten für einen Begrenzungsrahmen zurück, der um das dominante Objekt oder Gesicht im Bild zugeschnitten ist.

Codeliste

Wir empfehlen, beim Lesen des Codes die Python-Referenz für die Cloud Vision API hinzuzuziehen.

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)

Im Detail

Bibliotheken importieren

import argparse

from typing import MutableSequence

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

Importieren Sie Standardbibliotheken:

  • argparse, damit die Anwendung eingegebene Dateinamen als Argumente akzeptiert
  • io für Datei-E/A

Weitere Importe:

  • Die Klasse ImageAnnotatorClient in der Bibliothek google.cloud.vision zum Zugreifen auf die Vision API
  • Das Modul types in der Bibliothek google.cloud.vision zum Erstellen von Anfragen
  • Die Module Image und ImageDraw aus der Python Imaging Library (PIL) zum Zeichnen eines Begrenzungsrahmens auf dem Eingabebild

Anwendung ausführen

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)

Im folgenden Abschnitt analysieren Sie einfach das eingereichte Argument, das den lokalen Bilddateinamen angibt. Anschließend übergeben Sie es an eine Funktion zum Zuschneiden des Bildes oder zum Zeichnen des Hinweises.

Bei der API authentifizieren

Damit Sie mit dem Vision API-Dienst kommunizieren können, müssen Sie den Dienst mit den zuvor abgerufenen Anmeldedaten authentifizieren. Innerhalb einer Anwendung erhalten Sie die Anmeldedaten am einfachsten über die Verwendung der Standardanmeldedaten für Anwendungen (Application Default Credentials, ADC). Die Clientbibliothek versucht standardmäßig, die Anmeldedaten aus der Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS abzurufen. Diese sollte auf die JSON-Schlüsseldatei Ihres Dienstkontos verweisen. Weitere Informationen finden Sie unter Dienstkonto einrichten.

Anmerkungen zu Zuschneidehinweisen für das Bild abrufen

Die Vision-Clientbibliothek ist nun authentifiziert. Rufen Sie die Methode crop_hints der Instanz ImageAnnotatorClient auf, um auf den Dienst zuzugreifen. Das Seitenverhältnis der Ausgabe wird im Objekt ImageContext angegeben. Wenn Sie mehrere Seitenverhältnisse übergeben, wird für jedes ein Zuschneidehinweis zurückgegeben.

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

Die Details zu API-Anfragen und -Antworten sind in der Clientbibliothek enthalten. Ausführliche Informationen zum Aufbau einer Anfrage finden Sie in der Vision API-Referenz.

Mithilfe der Antwort den Markierungsrahmen für den Hinweis zuschneiden oder zeichnen

Sobald der Vorgang abgeschlossen ist, enthält die API-Antwort die Koordinaten des Begrenzungsrahmens von mindestens einem cropHint. Mit der Methode draw_hint werden Linien um den CropHints-Begrenzungsrahmen gezeichnet. Anschließend wird das Bild in die Datei output-hint.jpg geschrieben.

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

Mit der Methode crop_to_hint wird das Bild mithilfe des vorgeschlagenen Zuschneidehinweises zugeschnitten.

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

Anwendung ausführen

Sie können zum Ausführen der Anwendung die Datei cat.jpg herunterladen. Klicken Sie gegebenenfalls mit der rechten Maustaste auf den Link. Übergeben Sie anschließend den Speicherort der heruntergeladenen Datei auf Ihrem lokalen Computer an die Anleitungsanwendung (crop_hints.py).

Hier sehen Sie den Python-Befehl gefolgt von der Konsolenausgabe, in der die JSON-Antwort cropHintsAnnotation angezeigt wird. Diese Antwort enthält die Koordinaten des Begrenzungsrahmens cropHints. Wir haben einen Ausschnitt mit einem Seitenverhältnis der Breite zur Höhe von 1,77 angefordert. Die für das Zuschneiderechteck zurückgegebenen x- und y-Koordinaten für oben links und unten rechts lauten 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
     }
    ]
   }
  }
 ]
}

Hier sehen Sie das zugeschnittene Bild.

Das wars auch schon! Sie haben die Funktion "Zuschneidehinweise" der Cloud Vision API ausgeführt, um die optimierten Koordinaten für den Markierungsrahmen um das als dominant erkannte Objekt im Bild zurückzugeben.