Tensorflow:将图像动态拆分为碎片

时间:2018-05-04 13:49:18

标签: python tensorflow machine-learning

我是tensorflow的新手,需要帮助来管理我的图像数据集。 由于图像集很大,因此阅读和训练阶段应该重叠。 每个图像的宽度也比其高度更多。 我需要将宽图像分割成方形部分。由于图像宽度不同,部件数量也会发生变化。

它遵循我的示例代码,我需要帮助才能使其工作:

def main(unused_argv):
   filenames = tf.constant(['im_01.png', 'im_02.png', 'im_03.png', 'im_04.png'])
   labels = tf.constant([0, 1, 0, 1])

   def parse_fn(file, label):
      image = tf.image.decode_png(tf.read_file(file), channels=1)

       shape_list = image.get_shape().as_list()
       image_width = shape_list[0]
       image_height = shape_list[1]
       num_pieces = int(image_width/image_height)

       Xy_pairs = []
       for i in range(num_pieces):
          offset_width = i * image_height
          sub_image = tf.image.crop_to_bounding_box(image, 0, offset_width, image_height, image_height)
          sub_image = tf.image.resize_images(sub_image, [128, 128])
          Xy_pairs.append((sub_image, label))

       return Dataset.from_tensor_slices(Xy_pairs)


dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
dataset = dataset.flat_map(parse_fn)

sess = tf.InteractiveSession()
it = dataset.make_one_shot_iterator()
while True:
    print('OUT: ' + it.get_next().eval())

错误看起来像这个TypeError: unsupported operand type(s) for /: 'NoneType' and 'NoneType',因为tensorflow在计算数据流图时不知道图像的大小。我很确定我需要像image.get_shape()这样的占位符。我希望社区可以帮助我。

1 个答案:

答案 0 :(得分:2)

正如评论中指出的那样,您的image形状在图表中未定义,因此尝试在评估之前获取值(通过image.get_shape().as_list())会返回(None, None, None)

要让图表中的所有内容都动态化,您可以使用tf.while_loop()代替当前的for循环来提取补丁,如下所示(此代码可能需要进行一些调整):

import tensorflow as tf

filenames = tf.constant(['im_01.png', 'im_02.png', 'im_03.png', 'im_04.png'])
labels = tf.constant([0, 1, 0, 1])
patch_size = [128, 128]

def parse_fn(file, label):
    image = tf.image.decode_png(tf.read_file(file), channels=1)

    shape= tf.shape(image)
    image_width = shape[1]
    image_height = shape[0]
    num_pieces = tf.div(image_width, image_height)

    def tf_while_condition(index, outputs):
        # We loop over the number of pieces:
        return tf.less(index, num_pieces)

    def tf_while_body(index, outputs):
        # We get the image patch for the given index:
        offset_width = index * image_height
        sub_image = tf.image.crop_to_bounding_box(image, 0, offset_width, image_height, image_height)
        sub_image = tf.image.resize_images(sub_image, patch_size)
        sub_image = tf.expand_dims(sub_image, 0)
        # We add it to the output patches (may be a cleaner way to do so):
        outputs = tf.concat([outputs[:index], sub_image, outputs[index + 1:]], axis=0)
        # We increment our index and return the values:
        index = tf.add(index, 1)
        return index, outputs

    # We build our patches tensor which will be filled with the loop:
    patches = tf.zeros((num_pieces, *patch_size, shape[2]), dtype=tf.float32)
    _, patches = tf.while_loop(tf_while_condition, tf_while_body, [0, patches])

    # We tile the label to have one per patch:
    patches_labels = tf.tile(tf.expand_dims(label, 0), [num_pieces])

    return tf.data.Dataset.from_tensor_slices((patches, patches_labels))

dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
dataset = dataset.flat_map(parse_fn)

sess = tf.InteractiveSession()
it = dataset.make_one_shot_iterator()
op = it.get_next()
while True:
    res = sess.run(op)
    print(res)