Home > database >  How to read images in path If I have a tensorflow string tensor
How to read images in path If I have a tensorflow string tensor

Time:06-26

I have this simple function below, which takes in a tensorflow string tensor (filename) and retrieves an image.

def get_image(filename):
    filename = filename.numpy()
    img = tf.io.read_file(f'images/{filename}')
    return img

But I get AttributeError: 'Tensor' object has no attribute 'numpy' I looked here for a solution but nobody had a good solution for this. A lot of people gave suggestions on how to enable eager execution, but none of it worked. Is it really that hard to retrieve data from a tensor...?

Or is there another way to do what I want in this scenario, without converting to numpy?

CodePudding user response:

I'm assuming you likely have a Tensorflow Dataset and are using .map() to load each image from disk or something similar. This is possible if you wrap the get_image function with tf.py_function but this has some downsides in that it becomes single-threaded essentially. There are some other tradeoffs that are detailed here.

s = tf.constant(["test", "test1"])
dataset = tf.data.Dataset.from_tensor_slices(s)
dataset = dataset.map(lambda x: tf.py_function(get_image, [x], [tf.string]))

If you're able to entertain a different approach, you might want to look into using tf.keras.utils.image_dataset_from_directory which will give you a Dataset with all your images loaded without restricting you to a single thread.

image_height = 256
image_width = 256
batch_size = 20

train_ds = tf.keras.utils.image_dataset_from_directory("images/*",
  validation_split=0.2,
  subset="training",
  seed=123,
  image_size=(img_height, img_width),
  batch_size=batch_size)

CodePudding user response:

TL;DR First of all, Maybe the below example helps you then you can read a solution for solving and reading images from the path.

Example for generating error (We can not access to numpy in this type of function)

# With @tf.function
@tf.function
def func(tns):
    tf.print(tns.numpy())
func(tf.random.uniform(shape=(2,)))
# ->  AttributeError: 'Tensor' object has no attribute 'numpy'


# Without @tf.function
def func(tns):
    tf.print(tns.numpy())
func(tf.random.uniform(shape=(2,)))
# -> array([0.86797523, 0.10352373], dtype=float32)

Solution: For reading images from your path you need to consider:

  1. Create a list of paths with os.path.join that you want to read images from it.
  2. After reading images make sure to use tf.image.decode_png.
import tensorflow as tf
import os

path = 'images'
path_images = [os.path.join(path, img) for img in os.listdir(path)] 
img_dataset = tf.data.Dataset.from_tensor_slices(path_images)

def get_image(filename):
    img = tf.io.read_file(filename)
    img = tf.image.decode_png(img, channels=3)
    return img


img_dataset = img_dataset.map(get_image, num_parallel_calls=tf.data.AUTOTUNE)
for img in img_dataset.take(1):
    print(img.shape)
# (100, 100, 3)

Creating random images in path /images/:

from PIL import Image
import numpy as np

for i in range(10):
    imarray = np.random.rand(100,100,3) * 255
    im = Image.fromarray(imarray.astype('uint8')).convert('RGB')
    im.save(f'images/image_{i}.png')
  • Related