问题
I am using tensorflow_hub modules to perform neural style transfer and I get the error "'images' contains no shape". I don't understand where I made a mistake.
This is my code:
import tensorflow_hub as hub
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
content_path = r'C:\Users\Sriram\Desktop\efil.jpg'
style_path = r'C:\Users\Sriram\Desktop\download1.jfif'
content_image = plt.imread(content_path)
style_image = plt.imread(style_path)
plt.subplot(1, 2, 1)
plt.title('Content Image')
plt.axis('off')
plt.subplot(1, 2, 2)
plt.title('Style Image')
plt.axis('off')
def image_to_tensor(path_to_img):
img = tf.io.read_file(path_to_img)
img = tf.image.decode_image(img, channels=3, dtype=tf.float32)
# Resize the image to specific dimensions
img = tf.image.resize(img, [720, 512])
img = img[tf.newaxis, :]
return img
def tensor_to_image(tensor):
tensor = tensor*255
tensor = np.array(tensor, dtype=np.uint8)
tensor = tensor[0]
plt.figure(figsize=(20,10))
plt.axis('off')
return plt.imshow(tensor)
content_image_tensor = image_to_tensor(content_path)
style_image_tensor = image_to_tensor(style_path)
hub_module = hub.load('https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2')
combined_result = hub_module(tf.constant(content_image_tensor), tf.constant(style_image_tensor))[0]
result=tensor_to_image(combined_result)
Here is the error:
runfile('C:/Users/Sriram/.spyder-py3/temp.py', wdir='C:/Users/Sriram/.spyder-py3')
Traceback (most recent call last):
File "C:\Users\Sriram\.spyder-py3\temp.py", line 30, in <module>
content_image_tensor = image_to_tensor(content_path)
File "C:\Users\Sriram\.spyder-py3\temp.py", line 20, in image_to_tensor
img = tf.image.resize(img, [720, 512])
File "C:\Users\Sriram\anaconda3\lib\site-packages\tensorflow\python\ops\image_ops_impl.py", line 1182, in resize_images
skip_resize_if_same=True)
File "C:\Users\Sriram\anaconda3\lib\site-packages\tensorflow\python\ops\image_ops_impl.py", line 1029, in _resize_images_common
raise ValueError('\'images\' contains no shape.')
ValueError: 'images' contains no shape
回答1:
Your code runs fine on TensorFlow 2.2, so I'm assuming you're hitting a somewhat known issue with decode_image
on TensorFlow 1.x: When "generically" decoding an image, the shape is not returned - which makes the call to resize()
fail. There's multiple ways to go about it.
Making use of known image sizes
If you know the size of of your image(s) beforehand, you can force a size onto the Tensor using the set_shape(shape) method (and then resize it):
img = tf.io.read_file(path_to_img)
img = tf.image.decode_image(img, channels=3, dtype=tf.float32)
# Workaround
img.set_shape([width, height, 3])
img = tf.image.resize(img, [720, 512])
img = img[tf.newaxis, :]
Making use of known image formats
If you know that all your images are JPEG, you can use decode_jpeg
instead, which behaves a bit better:
img = tf.io.read_file(path_to_img)
# Workaround
img = tf.image.decode_jpeg(img, channels=3)
img = tf.image.convert_image_dtype(img, np.float32)
img = tf.image.resize(img, [720, 512])
img = img[tf.newaxis, :]
Using resize with cropping and padding
Alternatively, you may try using tf.image.resize_with_crop_or_pad which apparently works around that issue:
img = tf.io.read_file(path_to_img)
img = tf.image.decode_image(img, channels=3, dtype=tf.float32)
# Workaround
img = tf.image.resize_image_with_crop_or_pad(img, 720, 512)
img = img[tf.newaxis, :]
There's one caveat though: The code assumes that all operations are executed eagerly, which is the default on TensorFlow 2.x, but not on TensorFlow 1.x. As a result of that, the tensor_to_image(tensor)
function will fail because the provided Tensor cannot be simply converted into an NumPy array. To fix this, you can enable eager execution at the start of your script by running
tf.compat.v1.enable_eager_execution()
On a side note - you can make use of tf.image.convert_image_dtype() and tf.squeeze() to convert your image back:
def tensor_to_image(tensor):
tensor = tf.image.convert_image_dtype(tensor, np.uint8)
tensor = tf.squeeze(tensor)
plt.figure(figsize=(20,10))
plt.axis('off')
return plt.imshow(tensor)
This will make sure that all values properly saturate (you won't have values outside 0..1
when converting to np.float32
, for example) and gets rid of the somewhat magic [0]
indexing.
来源:https://stackoverflow.com/questions/62957726/i-got-value-error-that-image-has-no-shape-while-converting-image-to-tensor-for-p