如何在Tensorflow 2中为每个像素分类从PNG创建单热编码矩阵

问题描述 投票:0回答:1

我正在尝试训练Unet,以便为256x256图像的每个像素提供标签,类似于给定的教程here。在该示例中,Unet的预测是(128x128x3)输出,其中3表示分配给每个像素的分类之一。在我的情况下,我需要一个(256x256x10)输出,该输出具有10种不同的分类(对于图像中的每个像素,基本上是一个热编码数组)。

我可以加载图像,但是我正在努力将每个图像的相应分割蒙版转换为正确的格式。我通过定义一个名为process_path的映射函数来创建DataSet,该函数采用保存的掩码的numpy表示并创建尺寸张量(256 256 10),但是当我调用ValueError时得到一个model.fit,告诉我它无法调用as_list,因为无法找到张量的形状:

# --------------------------------------------------------------------------------------
# DECODE A NUMPY .NPY FILE INTO THE REQUIRED FORMAT FOR TRAINING
# --------------------------------------------------------------------------------------
def decode_npy(npy):
  filename = npy.numpy()
  data = np.load(filename)
  data = kerasUtils.to_categorical(data, 10)
  return data

# --------------------------------------------------------------------------------------
# DECODE AN IMAGE (PNG) FILE INTO THE REQUIRED FORMAT FOR TRAINING
# --------------------------------------------------------------------------------------
def decode_img(img):
  img = tf.image.decode_png(img, channels=3)
  return tf.image.convert_image_dtype(img, tf.float32)

# --------------------------------------------------------------------------------------
# PROCESS A FILE PATH FOR THE DATASET
# input - path to an image file
# output - an input image and output mask
# --------------------------------------------------------------------------------------
def process_path(filePath):
  parts = tf.strings.split(filePath, '/')
  fileName = parts[-1]
  parts = tf.strings.split(fileName, '.')
  prefix = tf.convert_to_tensor(maskDir, dtype=tf.string)
  suffix = tf.convert_to_tensor("-mask.png", dtype=tf.string)
  maskFileName = tf.strings.join((parts[-2], suffix))
  maskPath = tf.strings.join((prefix, maskFileName), separator='/')

  # load the raw data from the file as a string
  img = tf.io.read_file(filePath)
  img = decode_img(img)
  mask = tf.py_function(decode_npy, [maskPath], tf.float32)
  return img, mask

trainDataSet = allDataSet.take(trainSize)
trainDataSet = trainDataSet.map(process_path).batch(4)
validDataSet = allDataSet.skip(trainSize)
validDataSet = validDataSet.map(process_path).batch(4)

我如何获取每个图像的对应(256 256 3)分割蒙版(存储为png)并将其转换为(256 256 10)张量,其中第i个通道表示像素值,如tutorial ?有人可以在process_path函数中或在执行转换的最有效位置中,说明如何实现此目标吗?

更新:

这里是分割蒙版的示例。每个蒙版都包含相同的10种颜色:

enter image description here

python tensorflow tensorflow-datasets tensorflow2.0
1个回答
0
投票
import numpy as np
from cv2 import imread

im = imread('hfoa7.png', 0) # read as grayscale to get 10 unique values
n_classes = 10
one_hot = np.zeros((im.shape[0], im.shape[1], n_classes))
for i, unique_value in enumerate(np.unique(im)):
    one_hot[:, :, i][im == unique_value] = 1

hfao7是您发布的图像的名称。此代码段从图像创建一个热矩阵。您需要将此代码插入decode_npy()。但是,由于您向我发送了png,因此上面的代码不适用于npy文件。您可以传入png而不是npys的名称。不用担心使用kerasUtils.to_categorical-我发布的函数可以创建分类标签。

© www.soinside.com 2019 - 2024. All rights reserved.