【问题标题】:How to decode float32 encoded png to tensor?如何将 float32 编码的 png 解码为张量?
【发布时间】:2019-06-05 15:58:51
【问题描述】:

如何将在 argb 像素通道中编码 float32 值的 png 图像解码为 float32 张量?比如KITTI数据集提供的深度图。

功能

tf.image.decode_png()

只能给我 uint8 或 uint16 值,而不是正确的 float32 值。

是否有任何解决方法或解决方案来获得这样的 float32 tensorflow 张量?

编辑: 因此,在 png 中,每个通道都存储一个 uint8 值。所有 4 个通道 (argb) 一起构成一个 float32 值。这实际上可以用 PIL 和 numpy 轻松读取(此代码由 KITTI 数据集提供):

from PIL import Image
import numpy as np

depth_png = np.array(Image.open(filename), dtype=int)
depth = depth_png.astype(np.float) / 256.

我猜这里的 int 至少是一个 int32,以便保留信息。

但是,我正在寻找一种方法来以某种方式将其转换为我可以在数据集中动态加载的张量流张量。

【问题讨论】:

  • 您在寻找.pngtfrecords 的转换吗?
  • 我正在寻找一种方法来获取存储在 png 的每个通道中的 4 个 uint8 值,以将它们解码为单个 float32 张量。

标签: tensorflow


【解决方案1】:

.png 格式将通道值存储为 uint8。

要转换为介于 0 和 1 之间的 float32,我们只需转换然后除以 255(uint8 的最大值)。

类似这样的:

img_bytes = tf.io.read_file('path/img.png')
img_tensor_uint8 = tf.image.decode_png(img_bytes)
img_tensor_float32 = tf.cast(img_tensor_uint8, tf.float32) / 255

【讨论】:

  • 我不确定这是否正常工作。当我这样做时,我会得到奇怪的值。 png 为每个通道 (argb) 存储 uint8 作为表示单个 float32 值的一种方式,因此所有通道一起形成 32 位浮点数。当我首先解码为 uint8 张量时,我认为这些信息会丢失。我想我需要 4 个 uint8 张量来表示与 float32 张量相同的信息。
  • PNG 文件确实为每个通道存储了一个 uint8。所有 4 个通道都从 decode_png 返回 - 返回的张量的形状是(高度 X 宽度 X 通道)。通常会保留这 4 个通道用于下游训练,但将 uint 转换为浮点数并进行规范化。没有信息丢失:我们可以通过乘以 255 然后转换回 int 来精确撤消转换
  • 嗯,所以当我使用 channels=0 解码时,我只得到一个通道。当我使用 channels=4 解码时,演员表后仍然有 4 个 float32 映射。所以这似乎没有正确地进行这种转换。也许 png 确实也以不同的方式存储了这些信息。我使用提供的 KITTI numpy/PIL 代码编辑了我的问题以读取这些 png 图像。它们还除以 256。您是否知道这实际上是如何工作的并将其转移到 tensorflow 中?
  • 好的,问题在于 png 实际上是灰度 uint16 值,而不是 4 通道 uin8 值。所以这是我的错。我将自己回答我的问题,但给你一个赞成票,因为你的回答对于一般用例也是正确的。
【解决方案2】:

所以这里的问题是 KITTI png 图像是灰度 uint16 值。有了这个正确的解码是:

image = tf.read_file(path)
image = tf.image.decode_png(image, channels=0, dtype=tf.uint16)
image = tf.cast(image, tf.float32)
image = image / 256.0

Stewart_R 的答案当然也适用于一般用例。

【讨论】:

  • 是 255,不是 256
猜你喜欢
  • 2021-07-09
  • 2018-06-15
  • 1970-01-01
  • 2019-02-28
  • 1970-01-01
  • 1970-01-01
  • 2016-06-14
  • 2019-10-24
  • 1970-01-01
相关资源
最近更新 更多