מעבר לגרסה v0.25.1 של ספריית הלקוח של Python

ספריית הלקוח ל-Python v0.25.1 כוללת כמה שינויים משמעותיים בעיצוב של ספריות לקוח קודמות. השינויים האלה מסוכמים באופן הבא:

  • איחוד של מודולים למספר קטן יותר של סוגים

  • החלפת פרמטרים לא מוקלדים במחלקות ובספירות מוקלדות

במאמר הזה מפורטים השינויים שצריך לבצע בקוד Python של ספריות הלקוח של Cloud Vision API כדי להשתמש בספריית הלקוח של Python בגרסה v0.25.1.

הפעלת גרסאות קודמות של ספריית הלקוח

אין חובה לשדרג את ספריית הלקוח של Python לגרסה v0.25.1. אם אתם רוצים להמשיך להשתמש בגרסה קודמת של ספריית הלקוח של Python ולא רוצים להעביר את הקוד, אתם צריכים לציין את הגרסה של ספריית הלקוח של Python שבה האפליקציה שלכם משתמשת. כדי לציין גרסה ספציפית של הספרייה, עורכים את הקובץ requirements.txt כמו שמוצג כאן:

google-cloud-vision==0.25

מודולים שהוסרו

המודולים הבאים הוסרו בחבילה Python Client Library v0.25.1.

  • google.cloud.vision.annotations

  • google.cloud.vision.batch

  • google.cloud.vision.client

  • google.cloud.vision.color

  • google.cloud.vision.crop_hint

  • google.cloud.vision.entity

  • google.cloud.vision.face

  • google.cloud.vision.feature

  • google.cloud.vision.geometry

  • google.cloud.vision.image

  • google.cloud.vision.likelihood

  • google.cloud.vision.safe_search

  • google.cloud.vision.text

  • google.cloud.vision.web

שינויים נדרשים בקוד

ייבוא

כדי לגשת לסוגים החדשים בספריית הלקוח של Python בגרסה v0.25.1, צריך לכלול את המודול google.cloud.vision.types החדש.

מודול types מכיל את המחלקות החדשות שנדרשות ליצירת בקשות, כמו types.Image.

from google.cloud import vision

בנוסף, מודול google.cloud.vision.enums החדש מכיל את המספורים ששימושיים לניתוח ולהבנה של תגובות API, כמו enums.Likelihood.UNLIKELY ו-enums.FaceAnnotation.Landmark.Type.LEFT_EYE.

יצירת לקוח

הכיתה Client הוחלפה בכיתה ImageAnnotatorClient. מחליפים את ההפניות למחלקה Client ב-ImageAnnotatorClient.

גרסאות קודמות של ספריות הלקוח:

old_client = vision.Client()

Python Client Library v0.25.1:

client = vision.ImageAnnotatorClient()

יצירת אובייקטים שמייצגים תוכן של תמונות

כדי לזהות תוכן של תמונה מקובץ מקומי, מ-URI של Cloud Storage או מ-URI באינטרנט, משתמשים במחלקה החדשה Image.

יצירת אובייקטים שמייצגים תוכן תמונה מקובץ מקומי

בדוגמה הבאה מוצגת הדרך החדשה לייצוג תוכן של תמונה מקובץ מקומי.

גרסאות קודמות של ספריות הלקוח:

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

image = old_client.image(content=content)

Python Client Library v0.25.1:

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

image = vision.Image(content=content)

יצירת אובייקטים שמייצגים תוכן תמונה מ-URI

בדוגמה הבאה מוצגת הדרך החדשה לייצוג תוכן תמונה מ-URI של Cloud Storage או מ-URI של אינטרנט. ‫uri הוא ה-URI לקובץ תמונה ב-Google Cloud Storage או באינטרנט.

גרסאות קודמות של ספריות הלקוח:

image = old_client.image(source_uri=uri)

Python Client Library v0.25.1:

image = vision.Image()
image.source.image_uri = uri

יצירת בקשות ועיבוד תגובות

בספריית הלקוח של Python בגרסה 0.25.1, שיטות ה-API כמו face_detection שייכות לאובייקט ImageAnnotatorClient ולא לאובייקטים Image.

הערכים שמוחזרים שונים בכמה שיטות, כפי שמוסבר בהמשך.

באופן ספציפי, קודקודי תיבת התוחמת מאוחסנים עכשיו ב-bounding_poly.vertices ולא ב-bounds.vertices. הקואורדינטות של כל קודקוד מאוחסנות ב-vertex.x וב-vertex.y ולא ב-vertex.x_coordinate וב-vertex.y_coordinate.

השינוי בתיבת התוחמת משפיע על face_detection,‏ logo_detection,‏ text_detection,‏ document_text_detection וגם על crop_hints.

שליחת בקשה לזיהוי פנים ועיבוד התגובה

הסבירות לרגשות מוחזרת עכשיו כספירות שמאוחסנות ב-face.surprise_likelihood ולא ב-face.emotions.surprise. אפשר לשחזר את השמות של תוויות הסבירות על ידי ייבוא של google.cloud.vision.enums.Likelihood.

גרסאות קודמות של ספריות הלקוח::

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

image = old_client.image(content=content)

faces = image.detect_faces()

for face in faces:
    print('anger: {}'.format(face.emotions.anger))
    print('joy: {}'.format(face.emotions.joy))
    print('surprise: {}'.format(face.emotions.surprise))

    vertices = (['({},{})'.format(bound.x_coordinate, bound.y_coordinate)
                for bound in face.bounds.vertices])

    print('face bounds: {}'.format(','.join(vertices)))

Python Client Library v0.25.1:

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

image = vision.Image(content=content)

response = client.face_detection(image=image)
faces = response.face_annotations

# Names of likelihood from google.cloud.vision.enums
likelihood_name = (
    "UNKNOWN",
    "VERY_UNLIKELY",
    "UNLIKELY",
    "POSSIBLE",
    "LIKELY",
    "VERY_LIKELY",
)
print("Faces:")

for face in faces:
    print(f"anger: {likelihood_name[face.anger_likelihood]}")
    print(f"joy: {likelihood_name[face.joy_likelihood]}")
    print(f"surprise: {likelihood_name[face.surprise_likelihood]}")

    vertices = [
        f"({vertex.x},{vertex.y})" for vertex in face.bounding_poly.vertices
    ]

    print("face bounds: {}".format(",".join(vertices)))

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

שליחת בקשה לזיהוי תוויות ועיבוד התגובה

גרסאות קודמות של ספריות הלקוח::

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

image = old_client.image(content=content)

labels = image.detect_labels()

for label in labels:
    print(label.description)

Python Client Library v0.25.1:

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

image = vision.Image(content=content)

response = client.label_detection(image=image)
labels = response.label_annotations
print("Labels:")

for label in labels:
    print(label.description)

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

שליחת בקשה לזיהוי ציוני דרך ועיבוד התגובה

גרסאות קודמות של ספריות הלקוח::

קווי הרוחב והאורך של מיקומי ציוני דרך מאוחסנים עכשיו ב-location.lat_lng.latitude וב-location.lat_lng.longitude, ולא ב-location.latitude וב-location.longitude.

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

image = old_client.image(content=content)

landmarks = image.detect_landmarks()

for landmark in landmarks:
    print(landmark.description, landmark.score)
    for location in landmark.locations:
        print('Latitude'.format(location.latitude))
        print('Longitude'.format(location.longitude))

Python Client Library v0.25.1:

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

image = vision.Image(content=content)

response = client.landmark_detection(image=image)
landmarks = response.landmark_annotations
print("Landmarks:")

for landmark in landmarks:
    print(landmark.description)
    for location in landmark.locations:
        lat_lng = location.lat_lng
        print(f"Latitude {lat_lng.latitude}")
        print(f"Longitude {lat_lng.longitude}")

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

שליחת בקשה לזיהוי לוגו ועיבוד התגובה

גרסאות קודמות של ספריות הלקוח::

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

image = old_client.image(content=content)

logos = image.detect_logos()

for logo in logos:
    print(logo.description, logo.score)

Python Client Library v0.25.1:

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

image = vision.Image(content=content)

request = {
    "image": image,
    "features": [{"type_": vision.Feature.Type.LOGO_DETECTION}],
}

response = client.annotate_image(request=request)
logos = response.logo_annotations
print("Logos:")

for logo in logos:
    print(logo.description)

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

שליחת בקשה לזיהוי החיפוש הבטוח ועיבוד התגובה

ההסתברויות של החיפוש הבטוח מוחזרות עכשיו כספירות. אפשר לשחזר את השמות של תוויות הסבירות על ידי ייבוא של google.cloud.vision.enums.Likelihood.

גרסאות קודמות של ספריות הלקוח::

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

image = old_client.image(content=content)

safe = image.detect_safe_search()
print('Safe search:')
print('adult: {}'.format(safe.adult))
print('medical: {}'.format(safe.medical))
print('spoofed: {}'.format(safe.spoof))
print('violence: {}'.format(safe.violence))

Python Client Library v0.25.1:

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

image = vision.Image(content=content)

response = client.safe_search_detection(image=image)
safe = response.safe_search_annotation

# Names of likelihood from google.cloud.vision.enums
likelihood_name = (
    "UNKNOWN",
    "VERY_UNLIKELY",
    "UNLIKELY",
    "POSSIBLE",
    "LIKELY",
    "VERY_LIKELY",
)
print("Safe search:")

print(f"adult: {likelihood_name[safe.adult]}")
print(f"medical: {likelihood_name[safe.medical]}")
print(f"spoofed: {likelihood_name[safe.spoof]}")
print(f"violence: {likelihood_name[safe.violence]}")
print(f"racy: {likelihood_name[safe.racy]}")

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

שליחת בקשה לזיהוי טקסט ועיבוד התגובה

גרסאות קודמות של ספריות הלקוח::

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

image = old_client.image(content=content)

texts = image.detect_text()

for text in texts:
    print('\n"{}"'.format(text.description))

    vertices = (['({},{})'.format(bound.x_coordinate, bound.y_coordinate)
                for bound in text.bounds.vertices])

    print('bounds: {}'.format(','.join(vertices)))

Python Client Library v0.25.1:

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

image = vision.Image(content=content)

response = client.text_detection(image=image)
texts = response.text_annotations
print("Texts:")

for text in texts:
    print(f'\n"{text.description}"')

    vertices = [
        f"({vertex.x},{vertex.y})" for vertex in text.bounding_poly.vertices
    ]

    print("bounds: {}".format(",".join(vertices)))

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

שליחת בקשה לזיהוי טקסט במסמך ועיבוד התשובה

גרסאות קודמות של ספריות הלקוח::

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

image = old_client.image(content=content)

document = image.detect_full_text()

for page in document.pages:
    for block in page.blocks:
        block_words = []
        for paragraph in block.paragraphs:
            block_words.extend(paragraph.words)

        block_symbols = []
        for word in block_words:
            block_symbols.extend(word.symbols)

        block_text = ''
        for symbol in block_symbols:
            block_text = block_text + symbol.text

        print('Block Content: {}'.format(block_text))
        print('Block Bounds:\n {}'.format(block.bounding_box))

Python Client Library v0.25.1:

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

image = vision.Image(content=content)

response = client.document_text_detection(image=image)

for page in response.full_text_annotation.pages:
    for block in page.blocks:
        print(f"\nBlock confidence: {block.confidence}\n")

        for paragraph in block.paragraphs:
            print("Paragraph confidence: {}".format(paragraph.confidence))

            for word in paragraph.words:
                word_text = "".join([symbol.text for symbol in word.symbols])
                print(
                    "Word text: {} (confidence: {})".format(
                        word_text, word.confidence
                    )
                )

                for symbol in word.symbols:
                    print(
                        "\tSymbol: {} (confidence: {})".format(
                            symbol.text, symbol.confidence
                        )
                    )

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

שליחת בקשה לקבלת מאפייני תמונה ועיבוד התגובה

פרטי הצבע הדומיננטי מאוחסנים עכשיו ב-props.dominant_colors.colors ולא ב-props.colors.

גרסאות קודמות של ספריות הלקוח::

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

image = old_client.image(content=content)

props = image.detect_properties()

for color in props.colors:
    print('fraction: {}'.format(color.pixel_fraction))
    print('\tr: {}'.format(color.color.red))
    print('\tg: {}'.format(color.color.green))
    print('\tb: {}'.format(color.color.blue))
    print('\ta: {}'.format(color.color.alpha))

Python Client Library v0.25.1:

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

image = vision.Image(content=content)

response = client.image_properties(image=image)
props = response.image_properties_annotation
print("Properties:")

for color in props.dominant_colors.colors:
    print(f"fraction: {color.pixel_fraction}")
    print(f"\tr: {color.color.red}")
    print(f"\tg: {color.color.green}")
    print(f"\tb: {color.color.blue}")
    print(f"\ta: {color.color.alpha}")

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

שליחת בקשת זיהוי באינטרנט ועיבוד התגובה

גרסאות קודמות של ספריות הלקוח::

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

image = old_client.image(content=content)

notes = image.detect_web()

if notes.pages_with_matching_images:
    print('\n{} Pages with matching images retrieved')

    for page in notes.pages_with_matching_images:
        print('Score : {}'.format(page.score))
        print('Url   : {}'.format(page.url))

if notes.full_matching_images:
    print ('\n{} Full Matches found: '.format(
           len(notes.full_matching_images)))

    for image in notes.full_matching_images:
        print('Score:  {}'.format(image.score))
        print('Url  : {}'.format(image.url))

if notes.partial_matching_images:
    print ('\n{} Partial Matches found: '.format(
           len(notes.partial_matching_images)))

    for image in notes.partial_matching_images:
        print('Score: {}'.format(image.score))
        print('Url  : {}'.format(image.url))

if notes.web_entities:
    print ('\n{} Web entities found: '.format(len(notes.web_entities)))

    for entity in notes.web_entities:
        print('Score      : {}'.format(entity.score))
        print('Description: {}'.format(entity.description))

Python Client Library v0.25.1:

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

image = vision.Image(content=content)

response = client.web_detection(image=image)
annotations = response.web_detection

if annotations.best_guess_labels:
    for label in annotations.best_guess_labels:
        print(f"\nBest guess label: {label.label}")

if annotations.pages_with_matching_images:
    print(
        "\n{} Pages with matching images found:".format(
            len(annotations.pages_with_matching_images)
        )
    )

    for page in annotations.pages_with_matching_images:
        print(f"\n\tPage url   : {page.url}")

        if page.full_matching_images:
            print(
                "\t{} Full Matches found: ".format(len(page.full_matching_images))
            )

            for image in page.full_matching_images:
                print(f"\t\tImage url  : {image.url}")

        if page.partial_matching_images:
            print(
                "\t{} Partial Matches found: ".format(
                    len(page.partial_matching_images)
                )
            )

            for image in page.partial_matching_images:
                print(f"\t\tImage url  : {image.url}")

if annotations.web_entities:
    print("\n{} Web entities found: ".format(len(annotations.web_entities)))

    for entity in annotations.web_entities:
        print(f"\n\tScore      : {entity.score}")
        print(f"\tDescription: {entity.description}")

if annotations.visually_similar_images:
    print(
        "\n{} visually similar images found:\n".format(
            len(annotations.visually_similar_images)
        )
    )

    for image in annotations.visually_similar_images:
        print(f"\tImage url    : {image.url}")

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

שליחת בקשה להצעות לחיתוך ועיבוד התגובה

גרסאות קודמות של ספריות הלקוח::

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

image = old_client.image(content=content)

hints = image.detect_crop_hints(aspect_ratios=[1.77])

for n, hint in enumerate(hints):
    print('\nCrop Hint: {}'.format(n))

    vertices = (['({},{})'.format(bound.x_coordinate, bound.y_coordinate)
                for bound in hint.bounds.vertices])

    print('bounds: {}'.format(','.join(vertices)))

Python Client Library v0.25.1:

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

for n, hint in enumerate(hints):
    print(f"\nCrop Hint: {n}")

    vertices = [
        f"({vertex.x},{vertex.y})" for vertex in hint.bounding_poly.vertices
    ]

    print("bounds: {}".format(",".join(vertices)))

if response.error.message:
    raise Exception(
        "{}\nFor more info on error messages, check: "
        "https://cloud.google.com/apis/design/errors".format(response.error.message)
    )

שימו לב: צריך להעביר את יחסי הגובה-רוחב באמצעות CropHintsParams ו-ImageContext.