About tensorflow map function with ifelse statement

Question:

I would like to cut the image which are stored as tensorflow dataset to squared image. But it seems that the tensorflow could not allow the map function with ifelse statement. I hope to know whether I could solve this problem.
Many thanks in advance.

 def tf_resize(img, new_size=256):
 
    h, w,__ = img.shape
    start = math.ceil(abs(w-h))  
    img_corp = tf.cond(tf.constant(w>h, dtype=tf.bool), 
                       lambda: img[:, start:(start+h), :], 
                       lambda: img[start:(start+w), :, :])
    new_img = tf.image.resize(img_corp, [new_size, new_size])/255.0
    return new_img

def load_and_preprocess_image(path, new_size=256):
    image = tf.io.read_file(path)
    image = tf.image.decode_jpeg(image, channels=3)
    return image

data_dir = pathlib.Path(path) 
all_image_paths = [str(path) for path in list(data_dir.glob('*/*.jpg'))] 
path_ds = tf.data.Dataset.from_tensor_slices(all_image_paths)

image_ds = path_ds.map(load_and_preprocess_image)
image_ds = image_ds.map(tf_resize)  # this cause error!!!

The error message is shown below:

File "/tmp/ipykernel_14519/4089718206.py", line 26, in tf_resize  *
        start = math.ceil(abs(w-h))

    TypeError: unsupported operand type(s) for -: 'NoneType' and 'NoneType'
Asked By: xjl_peter

||

Answers:

That you need to specify input mappping, I had correct you definded Fn a bit then there are the answers .

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Functions
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
def f1(path, new_size=256) :
    New_path = 'C:\Users\Jirayu Kaewprateep\Pictures\Cats\samples\03 28x28.jpg'
    New_label = 'Cute'
    return New_path, New_label
def f2(img, new_size=256) :
    New_label = 'Cute'
    return New_label

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: DataSets
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
dataset_cat = tf.data.Dataset.list_files("F:\datasets\downloads\PetImages\train\Cat\*.png")


list_image = [ 'C:\Users\Jirayu Kaewprateep\Pictures\Cats\samples\01 28x28.jpg', 
'C:\Users\Jirayu Kaewprateep\Pictures\Cats\samples\02 28x28.jpg',
'C:\Users\Jirayu Kaewprateep\Pictures\Cats\samples\03 28x28.jpg',
'C:\Users\Jirayu Kaewprateep\Pictures\Cats\samples\04 28x28.jpg',
'C:\Users\Jirayu Kaewprateep\Pictures\Cats\samples\05 28x28.jpg',
'C:\Users\Jirayu Kaewprateep\Pictures\Cats\samples\06 28x28.jpg']
list_label = [ 'Shopping', 'Bath', 'Shower', 'Sickness', 'Recover', 'Handsome' ]

dataset = tf.data.Dataset.from_tensor_slices((list_image, list_label))
dataset.take(6)

New_dataset = dataset.map(f1)

for elem in New_dataset.take(6):
    print(elem)
    ### (<tf.Tensor: shape=(), dtype=string, numpy=b'C:\Users\Jirayu Kaewprateep\Pictures\Cats\samples\01 28x28.jpg'>, <tf.Tensor: shape=(), dtype=string, numpy=b'Shopping'>)
    print(elem[0].numpy)
    ### <bound method _EagerTensorBase.numpy of <tf.Tensor: shape=(), dtype=string, numpy=b'C:\Users\Jirayu Kaewprateep\Pictures\Cats\samples\01 28x28.jpg'>>
    element_as_string = str(elem[0].numpy()).split(''')
    image = plt.imread(os.fspath(element_as_string[1]))
    plt.imshow(image)
    plt.show()
    plt.close()

New mapping added

Answered By: Jirayu Kaewprateep

You have a few errors in your code. Try using tf.shape to get the dynamic shape of img:

import tensorflow as tf

def tf_resize(img, new_size=256):
 
    img_shape = tf.cast(tf.shape(img), tf.float32)
    w = img_shape[1]
    h = img_shape[0]
    start = tf.cast(tf.math.ceil(tf.abs(w-h)), dtype=tf.int32)

    w = tf.cast(w, dtype=tf.int32)
    h = tf.cast(h, dtype=tf.int32)
    img_corp = tf.cond(tf.greater(w, h), 
                       lambda: img[:, start:(start+h), :], 
                       lambda: img[start:(start+w), :, :])
    new_img = tf.image.resize(img_corp, [new_size, new_size])/255.0
    return new_img

def load_and_preprocess_image(path, new_size=256):
    image = tf.io.read_file(path)
    image = tf.image.decode_jpeg(image, channels=3)
    return image

all_image_paths = ['image.jpg'] 
path_ds = tf.data.Dataset.from_tensor_slices(all_image_paths)

image_ds = path_ds.map(load_and_preprocess_image)
image_ds = image_ds.map(tf_resize)  # this cause error!!!

for d in image_ds.take(1):
  print(d.shape)
(256, 256, 3)
Answered By: AloneTogether