Bootstrap

图像分类——一种适用于自定义数据集的图像剪裁方法

图像分类——一种适用于自定义数据集的图像剪裁方法

1.背景

在做图像分类时,要求输入图像十分规则,例如IMAGENET竞赛采取224×224的图像大小。但是自己准备的数据集往往是从网站中爬取,图像的尺寸不规则。对此本文探讨了一种简便的图像处理办法。

2.讨论

将size不规则的图像变为规则图像存在很多方法,最简单的就是直接resize,比如keras给出了一种解决方案,可通过调用“image_dataset_from_directory”API对图像进行resize,但是这种方法会导致图像变形,如图1和图2所示。在实际应用中,图像形变是不被期望的,容易给结果增加不确定性。
在这里插入图片描述
此时不妨提出一种简单的处理办法来解决形变问题。即选取图像的最短边为基准边规定一个正方形边框,使之在图像范围内随机滑动,剪裁出图像中的正方形子区域而不溢出图像,然后在缩放到预设定的图像大小。这样做的好处在于在训练时可以一定程度上起到数据增强的作用,同时避免了产生形变。在推理阶段,对输入图像做中心剪裁,缩放后送入网络进行预测。该方法效果如下,图3为原图,图4-图7为本文方法,图8用于推理阶段。
在这里插入图片描述
下面是简单的数学推演:
假设现有图像高和宽,我们选取最短边L作为基准边,将会产生下图中红色正方形框,款内图像为剪裁图像。输入图像有一个图像中心O,中心坐标为(cx, cy),红色边界框也有个中心,这个中心的移动范围就是线段AB。下面需要做的就是让红色正方形框的中心随机出现在线段AB上就可以了。实现步骤上假定该正方形中心框与O点重合,然后生成[-1,+1]区间内的随机数k,让k乘以线段AO的距离以便生成改变量Δx,最后计算Δx+cx便可以得到红色框的中心坐标。
在这里插入图片描述

3.实现

实现代码

import random
from PIL import Image
from matplotlib import pyplot as plt

img = Image.open('tem/0/DGQZDS_36.jpg')  # 打开图像
img_w, img_h = img.size
img_l = min(img_w, img_h)  # 正方形框边长
cx, cy = img_w // 2, img_h // 2  # 图像中心
for training in range(2):
    if training:
        k = random.uniform(-1, 1)  # 随机系数
        if img_w >= img_h:
            distance = k * (img_w // 2 - img_l // 2)
            cx += distance  # 沿着x轴平移中心坐标
        else:
            distance = k * (img_h // 2 - img_l // 2)
            cy += distance  # 沿着y轴平移中心坐标
    # 图像剪裁
    img_crop = img.crop(
        (
            int(max(0, (cx - img_l // 2))),
            int(max(0, (cy - img_l // 2))),
            int(min((cx + img_l // 2),img_w)),
            int(min((cy + img_l // 2),img_h))
        )
    )
    # 图像缩放
    img_crop_resize = img_crop.resize((224, 224), Image.ANTIALIAS)
    plt.figure("training:{}".format(training))
    plt.imshow(img_crop_resize)
plt.show()

实现效果

在这里插入图片描述

;