user010517720
user010517720

Reputation: 2127

Saving an image as a protobuf in a TFRecord file and then reading it back and showing the image on screen

I want to do the following: Encode an image using the JPEG format in tensorflow, put this in a BytesList feature in protobuff, serialize it, save it, and then read it back again. After reading it, I have to parse it using a feature_description for the image, and then decode the image from the JPEG format. This is what I tried:

from sklearn.datasets import load_sample_images
from tensorflow.train import BytesList, FloatList, Int64List
from tensorflow.train import Feature, Features, Example
import tensorflow as tf
import numpy as np
import matplotlib as plt


# Loading the image and printing it
img = load_sample_images()["images"][0]
plt.imshow(img)
plt.axis("off")
plt.title("Original Image")
plt.show()

enter image description here

# Encode the image to JPEG
data = tf.io.encode_jpeg(img)

# Convert it to a protobuf Example
example_with_image = Example(
    features = Features(
        feature = {
            "image": Feature(bytes_list = BytesList(value = [data.numpy()]))
        }
    )
)

# Serialize the protobuf Example to a string
serialized_example = example_with_image.SerializeToString()

# Imagine we saved 'serialized_example' to disk and read it back into memory
# We now want to print the image

# Provide 'feature_description' so that the parse function knows the default 
# value
feature_description = {
    "image": tf.io.VarLenFeature(tf.string)
}

# Parse the serialized string
example_with_image = tf.io.parse_single_example(serialized_example, feature_description)

This all works great. Then I try to decode the image back using Tensorflow's decode_jpeg() function:

decoded_img = tf.io.decode_jpeg(example_with_image)

And this doesn't work. I get the following ValueError:

ValueError: Attempt to convert a value ({'image': <tensorflow.python.framework.sparse_tensor.SparseTensor object

at 0x000002B4C90AB9D0>}) with an unsupported type (<class 'dict'>) to a Tensor.

It doesn't work with the more general tf.io.decode_image() Tensorflow function either.

Honestly, I have no idea what's going on. Shouldn't I get the image back? What's wrong?

Upvotes: 0

Views: 776

Answers (1)

Aniket Bote
Aniket Bote

Reputation: 3564

example_with_image after using parse_single_example is a dictionary with key as image and a sparse tensor as value

The example_with_image looks like this:

{'image': <tensorflow.python.framework.sparse_tensor.SparseTensor at 0x25b29440cc8>}

The decode_jpeg function expects a byte value but you are providing a dictionary.

The correct way to extract the value would be:
Code:

image = tf.io.decode_jpeg(example_with_image1['image'].values.numpy()[0])
plt.imshow(image)

Output:

out

You can also parse your image as FixedLenFeature instead of VarLenFeature. In this case, you get a dense tensor instead of a sparse tensor.

Code:

feature_description = {
    "image": tf.io.FixedLenFeature([], tf.string)
}

# Parse the serialized string
example_with_image = tf.io.parse_single_example(serialized_example, feature_description)

image = tf.io.decode_jpeg(example_with_image['image'].numpy())
plt.imshow(image)

Upvotes: 1

Related Questions