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

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

  • איחוד מודולים לפחות סוגים

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

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

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

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

google-cloud-vision==0.25

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

המודולים הבאים הוסרו בחבילה של ספריית הלקוח של Python בגרסה 0.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 בגרסה 0.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 בגרסה 0.25.1:

client = vision.ImageAnnotatorClient()

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

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

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

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

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

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

image = old_client.image(content=content)

ספריית הלקוח של Python בגרסה 0.25.1:

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

image = vision.Image(content=content)

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

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

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

image = old_client.image(source_uri=uri)

ספריית הלקוח של Python בגרסה 0.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.

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

ספריית הלקוח של Python בגרסה 0.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 בגרסה 0.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 בגרסה 0.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 בגרסה 0.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 בגרסה 0.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 בגרסה 0.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 בגרסה 0.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 בגרסה 0.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 בגרסה 0.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 בגרסה 0.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.