【问题标题】:Keras - How to use ImageDataGenerator without deforming aspect ratioKeras - 如何在不改变纵横比的情况下使用 ImageDataGenerator
【发布时间】:2017-07-17 00:04:11
【问题描述】:

我有一个包含不同大小图像的文件夹。我尝试使用 ImageDataGenerator 和 flow_from_directory 进行批量加载/数据增强。

有没有办法保持图像的纵横比?似乎图像被拉伸到 target_size :我想“填充”我的图像而不使它们变形(用恒定值填充间隙)

这是我的代码:

datagen = ImageDataGenerator(
    rescale = 1./255,
    fill_mode='constant')

generator = datagen.flow_from_directory(
    'data/images',
    target_size=(256,256),
    color_mode = 'grayscale',
    batch_size=99,
    class_mode=None,
    shuffle=False)

图像被拉伸到 (256,256)。

【问题讨论】:

    标签: python image-processing keras


    【解决方案1】:

    我找到了问题的答案。

    目前在使用 ImageDataGenerator / flow_from_directory 时无法保持纵横比,但在 Github 上打开了一个pull request 以添加此功能。

    【讨论】:

    • 它仍然是一个开放的拉取请求:github.com/keras-team/keras-preprocessing/pull/81
    • 仍然是一个开放的拉取请求
    • 在我看来这太荒谬了!更愚蠢的是,预处理钩子在原始调整大小之后运行,所以你甚至不能使用它来使图像成为正方形。
    【解决方案2】:

    根据this post,您可以使用此代码为图像添加填充而不拉伸它:

    使用PIL:

    from PIL import Image, ImageOps
    
    desired_size = 224
    im_pth = "/home/jdhao/test.jpg"
    
    im = Image.open(im_pth)
    old_size = im.size  # old_size[0] is in (width, height) format
    
    ratio = float(desired_size) / max(old_size)
    new_size = tuple([int(x * ratio) for x in old_size])
    # use thumbnail() or resize() method to resize the input image
    
    # thumbnail is a in-place operation
    
    # im.thumbnail(new_size, Image.ANTIALIAS)
    
    im = im.resize(new_size, Image.ANTIALIAS)
    # create a new image and paste the resized on it
    
    new_im = Image.new("RGB", (desired_size, desired_size))
    new_im.paste(im, ((desired_size - new_size[0]) // 2,
                      (desired_size - new_size[1]) // 2))
    
    new_im.show()
    

    使用opencv

    import cv2
    desired_size = 224
    im_pth = "data_cropped/ges_cropped_0/001019180113990401104712_frame_150.jpg"
    
    im = cv2.imread(im_pth)
    old_size = im.shape[:2]  # old_size is in (height, width) format
    
    ratio = float(desired_size) / max(old_size)
    new_size = tuple([int(x * ratio) for x in old_size])
    
    # new_size should be in (width, height) format
    
    im = cv2.resize(im, (new_size[1], new_size[0]))
    
    delta_w = desired_size - new_size[1]
    delta_h = desired_size - new_size[0]
    top, bottom = delta_h // 2, delta_h - (delta_h // 2)
    left, right = delta_w // 2, delta_w - (delta_w // 2)
    
    color = [0, 0, 0]
    new_im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT,
                                value=color)
    
    print(new_im.shape)
    cv2.imshow("image", new_im)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    ImageDataGenerator 中,您可以使用preprocessing_function 参数在生成数据之前进行上述预处理。我知道答案已经晚了,但我希望其他开发人员可以使用此代码。

    【讨论】:

    • 我不确定进行任何类型的调整大小和扩充是否有意义,因为在文档中,它说“函数将在图像调整大小后运行 和增强。因此,在您的情况下, preprocessing_function 将应用于纵横比已被破坏的图像
    • @KevinSüdmersen 完全正确。发布此答案后,我意识到了这个错误,但我忘了更新答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    • 2018-04-29
    • 1970-01-01
    • 2021-03-31
    • 1970-01-01
    相关资源
    最近更新 更多