Python 클라이언트 라이브러리 v0.25.1로 이전

Python v0.25.1용 클라이언트 라이브러리에는 이전 클라이언트 라이브러리의 설계 방법에 대한 몇 가지 중요한 변경사항이 포함되어 있습니다. 이러한 변경사항은 다음과 같습니다.

  • 더 적은 수의 유형으로 모듈 통합

  • 유형화되지 않은 매개변수를 강력한 유형의 클래스 및 열거로 교체

이 주제에서는 v0.25.1 Python 클라이언트 라이브러리를 사용하기 위해 Cloud Vision API 클라이언트 라이브러리와 관련된 Python 코드를 어떻게 변경해야 하는지 자세히 설명합니다.

이전 버전의 클라이언트 라이브러리 실행

Python 클라이언트 라이브러리를 v0.25.1로 반드시 업그레이드할 필요는 없습니다. 이전 버전의 Python 클라이언트 라이브러리를 계속 사용하고 코드를 마이그레이션하지 않으려면 앱에서 사용되는 Python 클라이언트 라이브러리 버전을 지정해야 합니다. 특정 라이브러리 버전을 지정하려면 requirements.txt 파일을 다음과 같이 편집합니다.

google-cloud-vision==0.25

삭제된 모듈

다음 모듈은 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

필수 코드 변경

가져오기

Python 클라이언트 라이브러리 v0.25.1의 새로운 유형에 액세스하려면 새로운 google.cloud.vision.types 모듈을 포함합니다.

types 모듈에는 요청 생성에 필요한 새로운 클래스(예: types.Image)가 포함되어 있습니다.

from google.cloud import vision

또한 새로운 google.cloud.vision.enums 모듈에는 enums.Likelihood.UNLIKELYenums.FaceAnnotation.Landmark.Type.LEFT_EYE와 같은 API 응답을 파싱하고 이해하는 데 유용한 열거형이 포함되어 있습니다.

클라이언트 만들기

Client 클래스가 ImageAnnotatorClient 클래스로 대체되었습니다. Client 클래스에 대한 참조를 ImageAnnotatorClient로 대체하세요.

이전 버전의 클라이언트 라이브러리:

old_client = vision.Client()

Python 클라이언트 라이브러리 v0.25.1:

client = vision.ImageAnnotatorClient()

이미지 콘텐츠를 나타내는 객체 생성

로컬 파일, Google Cloud Storage URI, 웹 URI에서 이미지 콘텐츠를 식별하려면 새로운 Image 클래스를 사용합니다.

로컬 파일의 이미지 콘텐츠를 나타내는 객체 구성

다음 예에서는 로컬 파일의 이미지 콘텐츠를 나타내는 새로운 방법을 보여줍니다.

이전 버전의 클라이언트 라이브러리:

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

image = old_client.image(content=content)

Python 클라이언트 라이브러리 v0.25.1:

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

image = vision.Image(content=content)

URI의 이미지 콘텐츠를 나타내는 객체 구성

다음 예시에서는 Google Cloud Storage URI 또는 웹 URI의 이미지 콘텐츠를 나타내는 새로운 방법을 보여줍니다. uri는 Google Cloud Storage 또는 웹에 있는 이미지 파일에 대한 URI입니다.

이전 버전의 클라이언트 라이브러리:

image = old_client.image(source_uri=uri)

Python 클라이언트 라이브러리 v0.25.1:

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

요청 생성 및 응답 처리

Python 클라이언트 라이브러리 v0.25.1에서는 face_detection 등의 API 메서드는 Image 객체가 아니라 ImageAnnotatorClient 객체에 속합니다.

아래 설명과 같이 몇 가지 메서드의 반환 값이 달라졌습니다.

특히, 이제 경계 상자 꼭짓점은 bounds.vertices가 아니라 bounding_poly.vertices에 저장됩니다. 각 꼭짓점의 좌표는 vertex.x_coordinate, vertex.y_coordinate가 아니라 vertex.x, vertex.y에 저장됩니다.

경계 상자의 변경사항은 face_detection, logo_detection, text_detection, document_text_detection, crop_hints에 영향을 줍니다.

얼굴 인식 요청 보내기 및 응답 처리

감정 확률은 이제 face.emotions.surprise가 아니라 face.surprise_likelihood에 저장되는 열거형으로 반환됩니다. 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 클라이언트 라이브러리 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 클라이언트 라이브러리 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.latitude, location.longitude가 아니라 location.lat_lng.latitude, location.lat_lng.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 클라이언트 라이브러리 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 클라이언트 라이브러리 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)
    )

세이프서치 감지 요청 보내기 및 응답 처리

세이프서치 확률은 이제 열거형으로 반환됩니다. 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 클라이언트 라이브러리 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 클라이언트 라이브러리 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 클라이언트 라이브러리 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.colors가 아니라 props.dominant_colors.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 클라이언트 라이브러리 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 클라이언트 라이브러리 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 클라이언트 라이브러리 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)
    )

CropHintsParamsImageContext를 통해 가로세로 비율을 전달해야 합니다.