8

Task:

  • Convert Google Vision API response to JSON

Problem:

  • The return value from the API call is not in a JSON format

Python Function

def detect_logos(path):
"""Detects logos in the file."""
client = vision.ImageAnnotatorClient()

# [START migration_logo_detection]
with io.open(path, 'rb') as image_file:
    content = image_file.read()

image = types.Image(content=content)

response = client.logo_detection(image=image)
logos = response.logo_annotations

print('Logos:')
print(logos)
print(type(logos))

Google online JSON

"logoAnnotations": [
{
  "mid": "/m/02wwnh",
  "description": "Maxwell House",
  "score": 0.41142157,
  "boundingPoly": {
    "vertices": [
      {
        "x": 74,
        "y": 129
      },
      {
        "x": 161,
        "y": 129
      },
      {
        "x": 161,
        "y": 180
      },
      {
        "x": 74,
        "y": 180
      }
    ]
  }
}

Google Response (List)

 [mid: "/m/02wwnh"
description: "Maxwell House"
score: 0.4114215672016144
bounding_poly {
  vertices {
    x: 74
    y: 129
  }
  vertices {
    x: 161
    y: 129
  }
  vertices {
    x: 161
    y: 180
  }
  vertices {
    x: 74
    y: 180
  }
}
]

Type:

google.protobuf.internal.containers.RepeatedCompositeFieldContainer

Tried:

Protobuf to json in python

K P
  • 854
  • 7
  • 19
  • Do you have the python script you wrote returning just Google Response (List), is it returned without commas or simply the way you have it here ? – itsmrbeltre Feb 05 '18 at 14:06
  • yes it is without commas, exactly what i have pasted – K P Feb 05 '18 at 14:07
  • can you provide a simplified version of the call in a small python script... i will run it and get to the bottom of the problem – itsmrbeltre Feb 05 '18 at 14:30
  • 1
    sure, please check it. that function calls vision API and I get response which I mentioned. – K P Feb 06 '18 at 05:51

3 Answers3

10

Google vision 2.0 requires different code and will throw the following error if the code isn't changed:

object has no attribute 'DESCRIPTOR'

Here is an example of how to serialize and de-serialize using json and/or protobuf:

import io, json
from google.cloud import vision_v1
from google.cloud.vision_v1 import AnnotateImageResponse

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

image = vision_v1.Image(content=content)
client = vision_v1.ImageAnnotatorClient()
response = client.document_text_detection(image=image)

# serialize / deserialize proto (binary)
serialized_proto_plus = AnnotateImageResponse.serialize(response)
response = AnnotateImageResponse.deserialize(serialized_proto_plus)
print(response.full_text_annotation.text)

# serialize / deserialize json
response_json = AnnotateImageResponse.to_json(response)
response = json.loads(response_json)
print(response['fullTextAnnotation']['text'])

Note 1: proto-plus doesn't support converting to snake_case names, which is supported in protobuf with "preserving_proto_field_name=True". So currently there is no way around the field names being converted from response['full_text_annotation'] to response['fullTextAnnotation'] There is an open feature request for this: googleapis/proto-plus-python#109

Note 2: The google vision api doesn't return an x coordinate if x=0. If x doesn't exist, the protobuf will default x=0. In python vision 1.0.0 using MessageToJson(), these x values weren't included in the json, but now with python vision 2.0.0 and .To_Json() these values are included as x:0

Alex Mann
  • 296
  • 3
  • 4
8

That library returns plain protobuf objects, which can be serialized to JSON using:

from google.protobuf.json_format import MessageToJson
serialized = MessageToJson(original)

This worked for me.

Dileep C C
  • 87
  • 1
  • 14
    it returns this error: `AttributeError: 'google.protobuf.pyext._message.RepeatedCompositeCo' object has no attribute 'DESCRIPTOR'` – Abdul Rehman May 04 '18 at 04:15
  • 2
    `MessageToJson(response._pb)` worked for me. [credit to Martin J](https://stackoverflow.com/questions/64403737/attribute-error-descriptor-while-trying-to-convert-google-vision-response-to-dic) – Feng Mai Apr 05 '21 at 02:37
5

Found solution. It can not be converted to JSON but can be accessed like this:

print(logos[0].bounding_poly.vertices[0].x)
K P
  • 854
  • 7
  • 19