Is the input of `tf.image.resize_images` must have static shape?

前端 未结 3 1786
一整个雨季
一整个雨季 2021-01-24 03:51

I run the code below, it raises an ValueError: \'images\' contains no shape. Therefore I have to add the line behind # to set the static shape, but

相关标签:
3条回答
  • 2021-01-24 04:10

    The issue here actually comes from the fact that tf.image.decode_image doesn't return the shape of the image. This was explained in these two GitHub issues: issue1, issue2.

    The problem comes from the fact that tf.image.decode_image also handles .gif, which returns a 4D tensor, whereas .jpg and .png return 3D images. Therefore, the correct shape cannot be returned.


    The solution is to simply use tf.image.decode_jpeg or tf.image.decode_png (both work the same and can be used on .png and .jpg images).

    def _decode_image(filename):
        image_string = tf.read_file(filename)
        image_decoded = tf.image.decode_jpeg(image_string, channels=3)
        image = tf.cast(image_decoded, tf.float32)
        image_resized = tf.image.resize_images(image, [224, 224])
    
        return image_resized
    
    0 讨论(0)
  • 2021-01-24 04:10

    No, tf.image.resize_images can handle dynamic shape

    file_queue = tf.train.string_input_producer(['./dog1.jpg'])
    # shape of dog1.jpg is (720, 720)
    
    reader = tf.WholeFileReader()
    file_name, content = reader.read(file_queue)
    img_raw = tf.image.decode_jpeg(content, 3) # size (?, ?, 3)  <= dynamic h and w
    # img_raw.set_shape([227,227,3])
    img_resized = tf.image.resize_images(img_raw, [227, 227])
    img_shape = tf.shape(img_resized)
    
    with tf.Session() as sess:
        print img_shape.eval() #[227, 227, 3]
    

    BTW, I am using tf v0.12, and there is no function called tf.image.decode_image, but I don't think it is important

    0 讨论(0)
  • 2021-01-24 04:13

    Of course you can use tensor object as size input for tf.image.resize_images.

    So, by saying "turn images with different shapes to [227,227,3]", I suppose you don't want to lose their aspect ratio, right? To achieve this, you have to rescale the input image first, then pad the rest with zero.

    It should be noted, though, you should consider perform image distortion and standardization before padding it.

    # Rescale so that one side of image can fit one side of the box size, then padding the rest with zeros.
    # target height is 227
    # target width is 227
    image = a_image_tensor_you_read
    shape = tf.shape(image)
    img_h = shape[0]
    img_w = shape[1]
    box_h = tf.convert_to_tensor(target_height)
    box_w = tf.convert_to_tensor(target_width)
    img_ratio = tf.cast(tf.divide(img_h, img_w), tf.float32)
    aim_ratio = tf.convert_to_tensor(box_h / box_w, tf.float32)
    aim_h, aim_w = tf.cond(tf.greater(img_ratio, aim_ratio),
                           lambda: (box_h,
                                    tf.cast(img_h / box_h * img_w, tf.int32)),
                           lambda: (tf.cast(img_w / box_w * img_h, tf.int32),
                                    box_w))
    image_resize = tf.image.resize_images(image, tf.cast([aim_h, aim_w], tf.int32), align_corners=True)
    
    # Perform image standardization and distortion
    image_standardized_distorted = blablabla
    
    image_padded = tf.image.resize_image_with_crop_or_pad(image_standardized_distorted, box_h, box_w)
    return image_padded
    
    0 讨论(0)
提交回复
热议问题