מדריך להצעות חיתוך

קהל

המטרה של המדריך הזה היא לעזור לכם לפתח אפליקציות באמצעות התכונה Crop Hints (הצעות לחיתוך) של Vision API. ההנחה היא שאתם מכירים מבנים וטכניקות בסיסיים בתכנות. עם זאת, גם אם אתם מתחילים בתכנות, תוכלו לעקוב אחרי המדריך הזה ולהריץ אותו בלי קושי, ואז להשתמש במאמרי העזרה של ה-Vision API כדי ליצור אפליקציות בסיסיות.

במדריך הזה נסביר איך להשתמש באפליקציית Vision API כדי לבצע קריאה ל-Vision API ולהשתמש בתכונה Crop Hints (הצעות לחיתוך).

דרישות מוקדמות

Python

סקירה כללית

במדריך הזה מוסבר איך ליצור אפליקציה בסיסית של Vision API שמשתמשת בCrop Hints בקשה. אפשר לספק את התמונה לעיבוד באמצעות URI של Cloud Storage (מיקום בקטגוריה של Cloud Storage) או באמצעות הטמעה בבקשה. תגובה מוצלחת של Crop Hints מחזירה את הקואורדינטות של תיבת תוחמת שנחתכה סביב האובייקט או הפנים הדומיננטיים בתמונה.

רשימת קודים

במהלך קריאת הקוד, מומלץ לעיין בהפניה ל-Cloud Vision API 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)

מבט מקרוב

ייבוא ספריות

import argparse

from typing import MutableSequence

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

אנחנו מייבאים ספריות רגילות:

  • argparse כדי לאפשר לאפליקציה לקבל שמות של קובצי קלט כארגומנטים
  • io לקלט/פלט של קבצים

ייבוא אחר:

  • המחלקות ImageAnnotatorClient בספרייה google.cloud.vision לגישה ל-Vision API.
  • מודול types בספרייה google.cloud.vision ליצירת בקשות
  • מודולים Image ו-ImageDraw מ-Python Imaging Library (PIL). כדי לצייר תיבת גבול בתמונת הקלט.

הפעלת האפליקציה

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)

כאן אנחנו פשוט מנתחים את הארגומנט שהועבר ומציין את שם הקובץ של התמונה המקומית, ומעבירים אותו לפונקציה כדי לחתוך את התמונה או לצייר את הרמז.

אימות ל-API

לפני שמתקשרים עם שירות Vision API, צריך לאמת את השירות באמצעות פרטי כניסה שהושגו קודם. בתוך אפליקציה, הדרך הכי פשוטה לקבל פרטי כניסה היא באמצעות Application Default Credentials‏ (ADC). כברירת מחדל, ספריית הלקוח תנסה לקבל פרטי כניסה ממשתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS, שצריך להיות מוגדר כך שיצביע על קובץ מפתח ה-JSON של חשבון השירות (מידע נוסף זמין במאמר בנושא הגדרת חשבון שירות).

קבלת הצעות חיתוך לתמונה

עכשיו, אחרי שספריית הלקוח של Vision מאומתת, אפשר לגשת לשירות באמצעות קריאה לשיטה crop_hints של מופע ImageAnnotatorClient. יחס הגובה-רוחב של הפלט מצוין באובייקט ImageContext. אם מועברים כמה יחסי גובה-רוחב, יוחזרו כמה רמזים לחיתוך, אחד לכל יחס גובה-רוחב.

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

ספריית הלקוח כוללת את הפרטים של הבקשות והתגובות ל-API. מידע מלא על מבנה הבקשה זמין בהפניית Vision API.

שימוש בתשובה כדי לחתוך או לצייר את תיבת התוחמת של הרמז

אחרי שהפעולה תושלם בהצלחה, תגובת ה-API תכיל את קואורדינטות התיבה התוחמת של cropHint אחד או יותר. השיטה draw_hint מציירת קווים מסביב לתיבת התוחמת CropHints, ואז כותבת את התמונה אל 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")

השיטה crop_to_hint חותכת את התמונה באמצעות הצעת החיתוך המוצעת.

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

הפעלת האפליקציה

כדי להפעיל את האפליקציה, אפשר להוריד את הקובץ cat.jpg הזה (יכול להיות שתצטרכו ללחוץ לחיצה ימנית על הקישור), ואז להעביר את המיקום שבו הורדתם את הקובץ במחשב המקומי לאפליקציית ההדרכה (crop_hints.py).

זו פקודת Python, ואחריה פלט המסוף שבו מוצגת תגובת ה-JSON‏ cropHintsAnnotation. התשובה הזו כוללת את הקואורדינטות של התיבה התוחמת cropHints. ביקשנו אזור חיתוך עם יחס גובה-רוחב של 1.77, והקואורדינטות של הפינה הימנית התחתונה והפינה השמאלית העליונה של מלבן החיתוך הן 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
     }
    ]
   }
  }
 ]
}

והנה התמונה החתוכה.

כל הכבוד! הפעלתם את Cloud Vision Crop Hints API כדי לקבל את הקואורדינטות האופטימליות של תיבת התוחמת סביב האובייקט הדומיננטי שזוהה בתמונה.