给数据加入黑边
一、原因
- 有时候由于网络设计的原因,我们需要输入固定尺寸大小的图片,例如比较常见的就是输入正方形的图片到网络中,如:YOLO中输入图片的大小有416x416大小的。但是,我们的数据集中的图片往往不是正方形的,那么我们在一般情况下,需要对图片进行处理,可以加入黑边的操作。
- 这里面加入黑边,一般会有两种情况,这一般与标签的制作方法、处理的问题或者是简单复杂程度来决定的。
通常情况有两种
- 一种情况是回归问题:如画框,一般情况下框的标签已经确定,因此,我们一般为了方便,我们不会修改原始的标签,因此,就讲图片粘贴到一张正方形的固定颜色背景图上,原始图片与背景图片的0点重合,这样图片的坐标就不要进行修改
- 另外一种请框时分割问题:有时候由于制作标签的问题,我们一般分割的时候(如:医学分割)重点是图片中心的部分,因此我们需要将原始数据集图片放在整个正方形背景图的中间,然后将标签掩码图也放在正方形背景的中间,这样对于特定的分割任务的效果会比较好。(因为一般我们使用的卷积核都是奇数的是有中心点的,对于整个图的中线区域卷的次数是比较多的,效果会比较好)。
二、代码
- 将原始数据集图片放在背景图的左上角:
from PIL import Image, ImageDraw
def convert_to_416x416(image, scale_side=416, process_path=None, index=None):
# image = Image.open(r"fake_path/1.jpg")
# 获得图片原始宽高
ow, oh = image.size
img = image.copy()
# 根据最大边进行缩放,图像只会缩小,不会变大
img.thumbnail((scale_side, scale_side)) # 这个不需要返回值,直接在原图上进行了修改
w, h = img.size
# 缩放比例=缩放的框/原始框 (缩放比例是一个小数)
s_w, s_h = w / ow, h / oh
s = (s_h + s_w) / 2
# print(s)
bg_img = Image.new("RGB", (scale_side, scale_side), (0, 0, 0))
bg_img.paste(img, (0, 0))
if process_path is not None:
bg_img.save(f"{process_path}/{index}.jpg")
return w, h, s, bg_img
- 将原始数据集图片放在背景图的中心(github上看到有人这么写,感觉很好,进行了借鉴):
from PIL import Image
"按照缩放的边长对图片进行等比缩放,并转成正方形居中"
def scale_img(image, scale_side):
# 根据最大边长缩放,图像只会缩小,不会变大
# 当被缩放的图片宽和高都小于缩放尺寸的时候,图像不变
image.thumbnail((scale_side, scale_side))
# 获得缩放后的宽高
w2, h2 = image.size
# 新建一张scale_side*scale_side的空白黑背景图片
bg_img = Image.new("RGB", (scale_side, scale_side), (0, 0, 0))
# 根据缩放后的宽高粘贴图像到背景上
if w2 == scale_side:
bg_img.paste(image, (0, int((scale_side - h2) / 2)))
elif h2 == scale_side:
bg_img.paste(image, (int((scale_side - w2) / 2)), 0)
else:
bg_img.paste(image, (int((scale_side - w2) / 2)), int((scale_side - h2) / 2))
return bg_img