Search code examples
pythongoogle-cloud-storagepython-imaging-librarygoogle-cloud-vision

TypeError when opening images from GCP storage to process them with Vision API


I'm trying to open/get public images from google cloud storage to process using Vision API. Here is my code.

client = vision.ImageAnnotatorClient()

for file_name in list_blobs(BUCKET_NAME):
    response = requests.get(file_name)
    content = Image.open(BytesIO(response.content))

    image = types.Image(content=content)

    response = client.label_detection(image=image)
    labels = response.label_annotations

    print('Labels:\n')
    for label in labels:
        print(label.description)

I get the following error

Traceback (most recent call last):
  File "/Users/gmwill934/PycharmProjects/PDFRekog/functions_vision.py", line 21, in <module>
    image = types.Image(content=content)
TypeError: <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=800x449 at 0x10BA5AD50> has type JpegImageFile, but expected one of: bytes

I'm having a hard time trying to open the images from the web, It works when I have my images locally and open using with open() as image_file....

[EDIT]

So I've modified my code to this, I converted the image to a bytes type, the code runs as expected but no labels show.

for file_name in list_blobs(BUCKET_NAME):
    image = imageio.imread(file_name)
    my_array = np.asarray(image)
    content = my_array.tobytes()

    image = types.Image(content=content)

    response = client.label_detection(image=image)
    labels = response.label_annotations

    print('Labels:\n')
    for label in labels:
        print(label.description)

Can a numpy array be converted to bytes? or is there something else I'm missing.


Solution

  • So Image was expecting the binary representation of the pixels. I accomplished it by changing the content variable to the following.

    content = urlopen(file_name).read()
    

    content is now returned in binary mode.