Tensorflow:如何以相同的方式随机裁剪输入图像和标签?

时间:2017-02-09 21:44:03

标签: tensorflow

我正试图从图像中随机拍摄。就像在Caffe中为了数据增加而做的一样。

我知道tensorflow已经有了一个函数

    img = tf.random_crop(img, [h, w, 3])
    label = tf.random_crop(label, [h, w, 1])

但我不确定它是否需要相同的裁剪图像和标签。此功能也不能自动填充一个或两个尺寸小于裁剪尺寸[h,w]的图像。

再次由

完成
    img = tf.image.resize_image_with_crop_or_pad(img, h, w)
    label = tf.image.resize_image_with_crop_or_pad(label, h, w)

但只需要中心作物而不是随机作物。

编辑:
以下是一些代码如何完成填充:

# Cropping dimensions (crops of 700 x 800)
crp_h = tf.constant(700)
crp_w = tf.constant(800)

shape = tf.shape(img)
img_h = shape[0]
img_w = shape[1]    
img = tf.cond(img_h < crp_h, lambda: tf.image.pad_to_bounding_box(img, 0, 0, crp_h, img_w), lambda: img)
# Update image dimensions
shape = tf.shape(img)
img_h = shape[0]
img = tf.cond(img_w < crp_w, lambda: tf.image.pad_to_bounding_box(img, 0, 0, img_h, crp_w), lambda: img)
# Update image dimensions
shape = tf.shape(img)
img_w = shape[1]

不幸的是,我不能在这里使用python if条件,因此必须使用丑陋的tf.cond(...)

1 个答案:

答案 0 :(得分:7)

我建议将图像与标签合并,然后将它们随机裁剪在一起:

import tensorflow as tf

def random_crop_and_pad_image_and_labels(image, labels, size):
  """Randomly crops `image` together with `labels`.

  Args:
    image: A Tensor with shape [D_1, ..., D_K, N]
    labels: A Tensor with shape [D_1, ..., D_K, M]
    size: A Tensor with shape [K] indicating the crop size.
  Returns:
    A tuple of (cropped_image, cropped_label).
  """
  combined = tf.concat([image, labels], axis=2)
  image_shape = tf.shape(image)
  combined_pad = tf.image.pad_to_bounding_box(
      combined, 0, 0,
      tf.maximum(size[0], image_shape[0]),
      tf.maximum(size[1], image_shape[1]))
  last_label_dim = tf.shape(labels)[-1]
  last_image_dim = tf.shape(image)[-1]
  combined_crop = tf.random_crop(
      combined_pad,
      size=tf.concat([size, [last_label_dim + last_image_dim]],
                     axis=0))
  return (combined_crop[:, :, :last_image_dim],
          combined_crop[:, :, last_image_dim:])

举个例子:

cropped_image, cropped_labels = random_crop_and_pad_image_and_labels(
    image=tf.reshape(tf.range(4*4*3), [4, 4, 3]),
    labels=tf.reshape(tf.range(4*4), [4, 4, 1]),
    size=[2, 2])

with tf.Session() as session:
  print(session.run([cropped_image, cropped_labels]))

打印类似:

[array([[[30, 31, 32],
        [33, 34, 35]],

       [[42, 43, 44],
        [45, 46, 47]]], dtype=int32), array([[[10],
        [11]],

       [[14],
        [15]]], dtype=int32)]

第二个图片尺寸不足的例子:

cropped_image, cropped_labels = random_crop_and_pad_image_and_labels(
    image=tf.reshape(tf.range(4*1*3), [4, 1, 3]),
    labels=tf.reshape(tf.range(4*1), [4, 1, 1]),
    size=[2, 2])

with tf.Session() as session:
  print(session.run([cropped_image, cropped_labels]))

打印:

[array([[[3, 4, 5],
        [0, 0, 0]],

       [[6, 7, 8],
        [0, 0, 0]]], dtype=int32), array([[[1],
        [0]],

       [[2],
        [0]]], dtype=int32)]