Migrazione alla libreria client Python v0.25.1

La libreria client per Python v0.25.1 include alcune modifiche significative al modo in cui sono state progettate le librerie client precedenti. Queste modifiche possono essere riassunte come segue:

  • Consolidamento dei moduli in meno tipi

  • Sostituzione di parametri non tipi con classi ed enumerazioni fortemente tipizzate

Questo argomento fornisce dettagli sulle modifiche che dovrai apportare al codice Python per le librerie client dell'API Cloud Vision per utilizzare la libreria client Python v0.25.1.

Eseguire versioni precedenti della libreria client

Non è necessario eseguire l'upgrade della libreria client Python alla versione 0.25.1. Se vuoi continuare a utilizzare una versione precedente della libreria client Python e non vuoi eseguire la migrazione del codice, devi specificare la versione della libreria client Python utilizzata dalla tua app. Per specificare una versione della libreria specifica, modifica il file requirements.txt come mostrato:

google-cloud-vision==0.25

Moduli rimossi

I seguenti moduli sono stati rimossi nel pacchetto della libreria client Python 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

Modifiche al codice richieste

Importazioni

Includi il nuovo modulo google.cloud.vision.types per accedere ai nuovi tipi nella libreria client Python v0.25.1.

Il modulo types contiene le nuove classi necessarie per la creazione delle richieste, ad esempio types.Image.

from google.cloud import vision

Inoltre, il nuovo modulo google.cloud.vision.enums contiene le enumerazioni utili per analizzare e comprendere le risposte dell'API, come enums.Likelihood.UNLIKELY e enums.FaceAnnotation.Landmark.Type.LEFT_EYE.

Crea un client

La classe Client è stata sostituita con la classe ImageAnnotatorClient. Sostituisci i riferimenti alla classe Client con ImageAnnotatorClient.

Versioni precedenti delle librerie client:

old_client = vision.Client()

Libreria client Python v0.25.1:

client = vision.ImageAnnotatorClient()

Creazione di oggetti che rappresentano i contenuti delle immagini

Per identificare i contenuti delle immagini da un file locale, da un URI Google Cloud Storage o da un URI web, utilizza la nuova classe Image.

Creazione di oggetti che rappresentano i contenuti delle immagini da un file locale

L'esempio seguente mostra il nuovo modo di rappresentare i contenuti delle immagini da un file locale.

Versioni precedenti delle librerie client:

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

image = old_client.image(content=content)

Libreria client Python v0.25.1:

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

image = vision.Image(content=content)

Creazione di oggetti che rappresentano i contenuti delle immagini da un URI

L'esempio seguente mostra il nuovo modo di rappresentare i contenuti delle immagini da un URI Google Cloud Storage o da un URI web. uri è l'URI di un file immagine su Google Cloud Storage o sul web.

Versioni precedenti delle librerie client:

image = old_client.image(source_uri=uri)

Libreria client Python v0.25.1:

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

Invio di richieste ed elaborazione delle risposte

Con la versione 0.25.1 della libreria client Python, i metodi dell'API come face_detection appartengono all'oggetto ImageAnnotatorClient anziché agli oggetti Image.

I valori restituiti sono diversi per diversi metodi, come spiegato di seguito.

In particolare, i vertici del riquadro di delimitazione vengono ora memorizzati in bounding_poly.vertices anziché in bounds.vertices. Le coordinate di ogni vertice sono memorizzate in vertex.x e vertex.y anziché in vertex.x_coordinate e vertex.y_coordinate.

La modifica della riquadro di delimitazione interessa face_detection, logo_detection, text_detection, document_text_detection e crop_hints.

Invio di una richiesta di rilevamento dei volti ed elaborazione della risposta

Le probabilità di emozioni vengono ora restituite come enumerazioni memorizzate in face.surprise_likelihood anziché in face.emotions.surprise. I nomi delle etichette di probabilità possono essere recuperati importando google.cloud.vision.enums.Likelihood.

Versioni precedenti delle librerie client:

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

Libreria client Python 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)
    )

Effettuare una richiesta di rilevamento delle etichette ed elaborare la risposta

Versioni precedenti delle librerie client:

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)

Libreria client Python 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)
    )

Effettuare una richiesta di rilevamento di punti di riferimento ed elaborare la risposta

Versioni precedenti delle librerie client:

La latitudine e la longitudine dei punti di riferimento ora vengono memorizzate in location.lat_lng.latitude e location.lat_lng.longitude, anziché in location.latitude e 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))

Libreria client Python 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)
    )

Effettuare una richiesta di rilevamento del logo ed elaborare la risposta

Versioni precedenti delle librerie client:

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)

Libreria client Python v0.25.1:

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

image = vision.Image(content=content)

response = client.logo_detection(image=image)
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)
    )

Effettuare una richiesta di rilevamento SafeSearch ed elaborare la risposta

Le probabilità di SafeSearch vengono ora restituite come enumerazioni. I nomi delle etichette di probabilità possono essere recuperati importando google.cloud.vision.enums.Likelihood.

Versioni precedenti delle librerie client:

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

Libreria client Python 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)
    )

Effettuare una richiesta di rilevamento del testo ed elaborare la risposta

Versioni precedenti delle librerie client:

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

Libreria client Python 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)
    )

Effettuare una richiesta di rilevamento del testo di un documento ed elaborare la risposta

Versioni precedenti delle librerie client:

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

Libreria client Python 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)
    )

Inviare una richiesta di proprietà delle immagini ed elaborare la risposta

Le informazioni sul colore dominante vengono ora memorizzate in props.dominant_colors.colors anziché in props.colors.

Versioni precedenti delle librerie client:

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

Libreria client Python 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)
    )

Effettuare una richiesta di rilevamento web ed elaborare la risposta

Versioni precedenti delle librerie client:

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

Libreria client Python 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)
    )

Effettuare una richiesta di suggerimenti di ritaglio ed elaborare la risposta

Versioni precedenti delle librerie client:

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

Libreria client Python 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)
    )

Tieni presente che le proporzioni devono essere passate tramite un CropHintsParams e un ImageContext.