I try to setup an images pipeline that builds an images dataset for Tensorflow that crops the images. I followed this tutorial but I want to crop the file to a square and not resize it without preserving the aspect ratio. I can't figure out how to get their dimensions.
#
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
#
import glob
AUTOTUNE = tf.data.experimental.AUTOTUNE
IMAGE_SIZE = 192
def preprocess_image(path):
img_raw = tf.io.read_file(path)
img_tensor = tf.image.decode_jpeg(img_raw, channels=3)
print("img_tensor")
print(img_tensor)
height = img_tensor.shape[0]
print("height")
print(height)
return img_tensor
files_path = glob.glob('./images/*.jpeg')
image_count = len(files_path)
path_ds = tf.data.Dataset.from_tensor_slices(files_path)
path_ds.map(preprocess_image, num_parallel_calls=AUTOTUNE)
The tensor shape returned by tf.image.decode_jpeg
is :
Tensor("DecodeJpeg:0", shape=(None, None, 3), dtype=uint8)
How can I access the size of the jpg image ?
When I access it this way it works :
#
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
#
image = tf.io.read_file('./images/4c34476047bcbbfd10b1fd3342605659.jpeg/')
image = tf.image.decode_jpeg(image, channels=3)
print("image.shape")
print(image.shape)
It prints :
image.shape
(700, 498, 3)
The tf. image module contains various functions for image processing and decoding-encoding Ops. Many of the encoding/decoding functions are also available in the core tf.io module.
You are facing this issue because the dataset is loaded lazily (only evaluated as it's needed).
Inherently, tf can only 'know' the size of the image if it either reads the file or we, as the developer, tell it. That may seem like an obvious point but it is worth bearing in mind.
So, given that a tf Dataset
object can represent arbitrarily large sequences of data (in fact, it's perfectly reasonable to represent infinite datasets this way), by design it doesn't read the files up front. Rather it reads them each time our downstream code needs a new example or batch.
I'm afraid it's really on us to either know the size of the images or to code against all possible sizes up front.
P.S. The reason you can get the second method to work is that it is eagerly evaluating the (single) tensor example.
P.P.S. You perhaps already know that you can "evaluate" the shape of any tensor at execution time with tf.shape()
(and use the results of this in your dataset pre-processing pipeline) but you can't inspect it up front
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With