【问题标题】:Tensorflow meets an error when rotating imagesTensorflow 在旋转图像时遇到错误
【发布时间】:2016-12-18 07:21:21
【问题描述】:

我想通过在 Tensorflow 中旋转图像来实现数据论证。在堆栈溢出中查找相关资料后,根据zimmermc找到了一个更好的答案。

def rotate_image_tensor(image, angle, mode='black'):
"""
Rotates a 3D tensor (HWD), which represents an image by given radian angle.
New image has the same size as the input image.
mode controls what happens to border pixels.
mode = 'black' results in black bars (value 0 in unknown areas)
mode = 'white' results in value 255 in unknown areas
mode = 'ones' results in value 1 in unknown areas
mode = 'repeat' keeps repeating the closest pixel known
"""

s = image.get_shape().as_list()
assert len(s) == 3, "Input needs to be 3D."
assert (mode == 'repeat') or (mode == 'black') or (mode == 'white') or (mode == 'ones'), "Unknown boundary mode."
image_center = [np.floor(x/2) for x in s]

# Coordinates of new image
coord1 = tf.range(s[0])
coord2 = tf.range(s[1])

# Create vectors of those coordinates in order to vectorize the image
coord1_vec = tf.tile(coord1, [s[1]])

coord2_vec_unordered = tf.tile(coord2, [s[0]])
coord2_vec_unordered = tf.reshape(coord2_vec_unordered, [s[0], s[1]])
coord2_vec = tf.reshape(tf.transpose(coord2_vec_unordered, [1, 0]), [-1])

# center coordinates since rotation center is supposed to be in the image center
coord1_vec_centered = coord1_vec - image_center[0]
coord2_vec_centered = coord2_vec - image_center[1]

coord_new_centered = tf.cast(tf.pack([coord1_vec_centered, coord2_vec_centered]), tf.float32)

# Perform backward transformation of the image coordinates
rot_mat_inv = tf.dynamic_stitch([[0], [1], [2], [3]], [tf.cos(angle), tf.sin(angle), -tf.sin(angle), tf.cos(angle)])
rot_mat_inv = tf.reshape(rot_mat_inv, shape=[2, 2])
coord_old_centered = tf.matmul(rot_mat_inv, coord_new_centered)

# Find nearest neighbor in old image
coord1_old_nn = tf.cast(tf.round(coord_old_centered[0, :] + image_center[0]), tf.int32)
coord2_old_nn = tf.cast(tf.round(coord_old_centered[1, :] + image_center[1]), tf.int32)

# Clip values to stay inside image coordinates
if mode == 'repeat':
    coord_old1_clipped = tf.minimum(tf.maximum(coord1_old_nn, 0), s[0]-1)
    coord_old2_clipped = tf.minimum(tf.maximum(coord2_old_nn, 0), s[1]-1)
else:
    outside_ind1 = tf.logical_or(tf.greater(coord1_old_nn, s[0]-1), tf.less(coord1_old_nn, 0))
    outside_ind2 = tf.logical_or(tf.greater(coord2_old_nn, s[1]-1), tf.less(coord2_old_nn, 0))
    outside_ind = tf.logical_or(outside_ind1, outside_ind2)

    coord_old1_clipped = tf.boolean_mask(coord1_old_nn, tf.logical_not(outside_ind))
    coord_old2_clipped = tf.boolean_mask(coord2_old_nn, tf.logical_not(outside_ind))

    coord1_vec = tf.boolean_mask(coord1_vec, tf.logical_not(outside_ind))
    coord2_vec = tf.boolean_mask(coord2_vec, tf.logical_not(outside_ind))

coord_old_clipped = tf.cast(tf.transpose(tf.pack([coord_old1_clipped, coord_old2_clipped]), [1, 0]), tf.int32)

# Coordinates of the new image
coord_new = tf.transpose(tf.cast(tf.pack([coord1_vec, coord2_vec]), tf.int32), [1, 0])

image_channel_list = tf.split(2, s[2], image)

image_rotated_channel_list = list()
for image_channel in image_channel_list:
    image_chan_new_values = tf.gather_nd(tf.squeeze(image_channel), coord_old_clipped)

    if (mode == 'black') or (mode == 'repeat'):
        background_color = 0
    elif mode == 'ones':
        background_color = 1
    elif mode == 'white':
        background_color = 255

    image_rotated_channel_list.append(tf.sparse_to_dense(coord_new, [s[0], s[1]], image_chan_new_values,
                                                         background_color, validate_indices=False))

image_rotated = tf.transpose(tf.pack(image_rotated_channel_list), [1, 2, 0])

return image_rotated

在执行上述代码时,我遇到如下错误。 如何解决?非常感谢! image_center = [np.floor(x/2) for x in s] TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'

我使用输入管道方法将数据提供给图表。调试代码时,s = [None, None, 3]。源码的url是tensorflow: how to rotate an image for data augmentation?

【问题讨论】:

    标签: tensorflow


    【解决方案1】:

    您输入的image 很可能是具有可变尺寸的tf.placeholder

    例如,未定义高度的图像:

    image = tf.placeholder(tf.float32, shape=[None, 365, 3])

    评估图表时,您可以获得实际尺寸:

    s = tf.shape(image) # Returns a Tensor, not a list image_center = tf.floor(s / 2)

    您不能使用 numpy,因为此计算需要作为图表的一部分进行。

    顺便说一句,您现在应该使用tf.contrib.image.rotate

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-21
      • 1970-01-01
      • 2020-11-23
      • 2014-11-08
      • 2023-04-10
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多