如何检索 tf.image.decode_jpeg 返回的图像张量的高度和高度?

Ant*_*nt1 5 python tensorflow

我尝试设置一个图像管道,为 Tensorflow 构建一个图像数据集来裁剪图像。我遵循了本教程,但我想将文件裁剪为正方形,而不是在不保留纵横比的情况下调整其大小。我无法弄清楚如何获得它们的尺寸。

#
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)

Run Code Online (Sandbox Code Playgroud)

返回的张量形状tf.image.decode_jpeg 是:

Tensor("DecodeJpeg:0", shape=(None, None, 3), dtype=uint8)
Run Code Online (Sandbox Code Playgroud)

如何访问 jpg 图像的大小?

当我以这种方式访问​​它时,它可以工作:

#
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)


Run Code Online (Sandbox Code Playgroud)

它打印:

image.shape
(700, 498, 3)
Run Code Online (Sandbox Code Playgroud)

Ste*_*t_R 4

您遇到此问题是因为数据集是延迟加载的(仅在需要时进行评估)。

本质上,tf 只能“知道”图像的大小,如果它读取文件或者我们(作为开发人员)告诉它。这似乎是一个显而易见的观点,但值得牢记。

因此,考虑到 tfDataset对象可以表示任意大的数据序列(事实上,以这种方式表示无限数据集是完全合理的),根据设计,它不会预先读取文件。相反,每次我们的下游代码需要新的示例或批次时,它都会读取它们。

恐怕我们真的需要知道图像的大小或预先针对所有可能的大小进行编码。

PS 您可以使用第二种方法的原因是它正在急切地评估(单个)张量示例。

PPS 您可能已经知道您可以在执行时“评估”任何张量的形状tf.shape()(并在数据集预处理管道中使用其结果),但您无法预先检查它

  • 这是一个开放式问题,但实际上是这样。每次需要从数据集中获取新图像时,“tf.shape(img_tensor)”都会进行评估,而“img_tensor.shape”甚至在读取任何数据之前就存在。因此,我们可以将“img_tensor.shape”视为设计时属性,而“tf.shape(img_tensor)”是仅在数据传递给它时才评估的操作。一个更常见的示例是具有未知第一维度的张量流操作,该维度表示批量大小(仅在执行时已知) (2认同)