Deeplab v3+ 的可视化输出问题
Problem with the visualization output from Deeplab v3+
我正在尝试 运行 Deeplab v3+(标准 tensorflow 版本)对一些遥感数据执行二元分类(对冲或不对冲),但我发现输出非常奇怪,让我相信我的输入数据的读取可能出了问题。
在 运行 执行 vis.py 脚本后,我在 segmentation_results 文件夹中得到以下 000000_image.png 输出。根据我的理解,名为 xxxx_image 的图像应该代表原始图像?此处的像素值范围为0-3,其他图像中的值可以为0-7。
但我的原始图像看起来像这样(不是完全相同的文件,只是原始数据的一个示例,因此您会有所了解)。
此文件夹中还有预测文件:
因此我假设预测 = 分类,图像 = 原始文件。知道为什么我将其作为原始文件吗?
要构建 TFRecords 数据,我使用以下脚本:
import math
import os.path
import sys
import build_data
import tensorflow as tf
FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_string('image_folder',
'./VOCdevkit/VOC2012/JPEGImages',
'Folder containing images.')
tf.app.flags.DEFINE_string(
'semantic_segmentation_folder',
'./VOCdevkit/VOC2012/SegmentationClassRaw',
'Folder containing semantic segmentation annotations.')
tf.app.flags.DEFINE_string(
'list_folder',
'./VOCdevkit/VOC2012/ImageSets/Segmentation',
'Folder containing lists for training and validation')
tf.app.flags.DEFINE_string(
'output_dir',
'./tfrecord',
'Path to save converted SSTable of TensorFlow examples.')
_NUM_SHARDS = 4
def _convert_dataset(dataset_split):
"""Converts the specified dataset split to TFRecord format.
Args:
dataset_split: The dataset split (e.g., train, test).
Raises:
RuntimeError: If loaded image and label have different shape.
"""
dataset = os.path.basename(dataset_split)[:-4]
sys.stdout.write('Processing ' + dataset)
filenames = [x.strip('\n') for x in open(dataset_split, 'r')]
num_images = len(filenames)
num_per_shard = int(math.ceil(num_images / float(_NUM_SHARDS)))
image_reader = build_data.ImageReader('png', channels=3)
label_reader = build_data.ImageReader('png', channels=1)
for shard_id in range(_NUM_SHARDS):
output_filename = os.path.join(
FLAGS.output_dir,
'%s-%05d-of-%05d.tfrecord' % (dataset, shard_id, _NUM_SHARDS))
with tf.python_io.TFRecordWriter(output_filename) as tfrecord_writer:
start_idx = shard_id * num_per_shard
end_idx = min((shard_id + 1) * num_per_shard, num_images)
for i in range(start_idx, end_idx):
sys.stdout.write('\r>> Converting image %d/%d shard %d' % (
i + 1, len(filenames), shard_id))
sys.stdout.flush()
# Read the image.
image_filename = os.path.join(
FLAGS.image_folder, filenames[i] + '.' + FLAGS.image_format)
image_data = tf.gfile.FastGFile(image_filename, 'rb').read()
height, width = image_reader.read_image_dims(image_data)
# Read the semantic segmentation annotation.
seg_filename = os.path.join(
FLAGS.semantic_segmentation_folder,
filenames[i] + '.' + FLAGS.label_format)
seg_data = tf.gfile.FastGFile(seg_filename, 'rb').read()
seg_height, seg_width = label_reader.read_image_dims(seg_data)
if height != seg_height or width != seg_width:
raise RuntimeError('Shape mismatched between image and label.')
# Convert to tf example.
example = build_data.image_seg_to_tfexample(
image_data, filenames[i], height, width, seg_data)
tfrecord_writer.write(example.SerializeToString())
sys.stdout.write('\n')
sys.stdout.flush()
def main(unused_argv):
dataset_splits = tf.gfile.Glob(os.path.join(FLAGS.list_folder, '*.txt'))
for dataset_split in dataset_splits:
_convert_dataset(dataset_split)
if __name__ == '__main__':
tf.app.run()
在 build_data.py 脚本中,我更改了一个细节,因为我的输入数据是 png uint16。
elif self._image_format == 'png':
self._decode = tf.image.decode_png(self._decode_data,
channels=channels, dtype=tf.uint16)
为了训练,我使用了您可以在此 link 找到的脚本(我觉得粘贴在这里有点大)https://github.com/tensorflow/models/blob/master/research/deeplab/train.py
对于导致此输出的可视化,我已经展示了我使用此处找到的脚本 https://github.com/tensorflow/models/blob/master/research/deeplab/vis.py
如果有人有一些见解,我将不胜感激。
我修复了它,事实证明这些模型不是为将 16 位数据作为输入而构建的,因此您需要更改图像解码器以明确读取图像为 16 位。在数据生成相关的脚本中以及 model_export 中有很多地方需要这样做,否则您稍后的推理图像也会被弄乱。
至于 vis.py 生成的输出图像,在 save_annotations 中,如果它正在写入原始图像,我不得不将最终图像编写器更改为使用 cv2,并使用正常方法如果写掩码
if original:
cv2.imwrite('%s/%s.png' % (save_dir, filename),colored_label.astype(np.uint16))
else:
pil_image = img.fromarray(colored_label.astype(dtype=np.uint8))
with tf.gfile.Open('%s/%s.png' % (save_dir, filename), mode='w') as f:
pil_image.save(f, 'PNG')
我正在尝试 运行 Deeplab v3+(标准 tensorflow 版本)对一些遥感数据执行二元分类(对冲或不对冲),但我发现输出非常奇怪,让我相信我的输入数据的读取可能出了问题。
在 运行 执行 vis.py 脚本后,我在 segmentation_results 文件夹中得到以下 000000_image.png 输出。根据我的理解,名为 xxxx_image 的图像应该代表原始图像?此处的像素值范围为0-3,其他图像中的值可以为0-7。
但我的原始图像看起来像这样(不是完全相同的文件,只是原始数据的一个示例,因此您会有所了解)。
此文件夹中还有预测文件:
因此我假设预测 = 分类,图像 = 原始文件。知道为什么我将其作为原始文件吗?
要构建 TFRecords 数据,我使用以下脚本:
import math
import os.path
import sys
import build_data
import tensorflow as tf
FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_string('image_folder',
'./VOCdevkit/VOC2012/JPEGImages',
'Folder containing images.')
tf.app.flags.DEFINE_string(
'semantic_segmentation_folder',
'./VOCdevkit/VOC2012/SegmentationClassRaw',
'Folder containing semantic segmentation annotations.')
tf.app.flags.DEFINE_string(
'list_folder',
'./VOCdevkit/VOC2012/ImageSets/Segmentation',
'Folder containing lists for training and validation')
tf.app.flags.DEFINE_string(
'output_dir',
'./tfrecord',
'Path to save converted SSTable of TensorFlow examples.')
_NUM_SHARDS = 4
def _convert_dataset(dataset_split):
"""Converts the specified dataset split to TFRecord format.
Args:
dataset_split: The dataset split (e.g., train, test).
Raises:
RuntimeError: If loaded image and label have different shape.
"""
dataset = os.path.basename(dataset_split)[:-4]
sys.stdout.write('Processing ' + dataset)
filenames = [x.strip('\n') for x in open(dataset_split, 'r')]
num_images = len(filenames)
num_per_shard = int(math.ceil(num_images / float(_NUM_SHARDS)))
image_reader = build_data.ImageReader('png', channels=3)
label_reader = build_data.ImageReader('png', channels=1)
for shard_id in range(_NUM_SHARDS):
output_filename = os.path.join(
FLAGS.output_dir,
'%s-%05d-of-%05d.tfrecord' % (dataset, shard_id, _NUM_SHARDS))
with tf.python_io.TFRecordWriter(output_filename) as tfrecord_writer:
start_idx = shard_id * num_per_shard
end_idx = min((shard_id + 1) * num_per_shard, num_images)
for i in range(start_idx, end_idx):
sys.stdout.write('\r>> Converting image %d/%d shard %d' % (
i + 1, len(filenames), shard_id))
sys.stdout.flush()
# Read the image.
image_filename = os.path.join(
FLAGS.image_folder, filenames[i] + '.' + FLAGS.image_format)
image_data = tf.gfile.FastGFile(image_filename, 'rb').read()
height, width = image_reader.read_image_dims(image_data)
# Read the semantic segmentation annotation.
seg_filename = os.path.join(
FLAGS.semantic_segmentation_folder,
filenames[i] + '.' + FLAGS.label_format)
seg_data = tf.gfile.FastGFile(seg_filename, 'rb').read()
seg_height, seg_width = label_reader.read_image_dims(seg_data)
if height != seg_height or width != seg_width:
raise RuntimeError('Shape mismatched between image and label.')
# Convert to tf example.
example = build_data.image_seg_to_tfexample(
image_data, filenames[i], height, width, seg_data)
tfrecord_writer.write(example.SerializeToString())
sys.stdout.write('\n')
sys.stdout.flush()
def main(unused_argv):
dataset_splits = tf.gfile.Glob(os.path.join(FLAGS.list_folder, '*.txt'))
for dataset_split in dataset_splits:
_convert_dataset(dataset_split)
if __name__ == '__main__':
tf.app.run()
在 build_data.py 脚本中,我更改了一个细节,因为我的输入数据是 png uint16。
elif self._image_format == 'png':
self._decode = tf.image.decode_png(self._decode_data,
channels=channels, dtype=tf.uint16)
为了训练,我使用了您可以在此 link 找到的脚本(我觉得粘贴在这里有点大)https://github.com/tensorflow/models/blob/master/research/deeplab/train.py
对于导致此输出的可视化,我已经展示了我使用此处找到的脚本 https://github.com/tensorflow/models/blob/master/research/deeplab/vis.py
如果有人有一些见解,我将不胜感激。
我修复了它,事实证明这些模型不是为将 16 位数据作为输入而构建的,因此您需要更改图像解码器以明确读取图像为 16 位。在数据生成相关的脚本中以及 model_export 中有很多地方需要这样做,否则您稍后的推理图像也会被弄乱。
至于 vis.py 生成的输出图像,在 save_annotations 中,如果它正在写入原始图像,我不得不将最终图像编写器更改为使用 cv2,并使用正常方法如果写掩码
if original:
cv2.imwrite('%s/%s.png' % (save_dir, filename),colored_label.astype(np.uint16))
else:
pil_image = img.fromarray(colored_label.astype(dtype=np.uint8))
with tf.gfile.Open('%s/%s.png' % (save_dir, filename), mode='w') as f:
pil_image.save(f, 'PNG')