一、背景
在计算机视觉中,经常需要将图片作为输入模型的数据。由于很多图像数据是比较大的,如果直接输入模型,会对计算机的要求很高,所以我们经常将尺寸较大的图片裁剪为小图片,以便能够更好的训练我们的模型。
二、本文会分享:
①如何将某一文件夹下的所有图片分割为特定大小的很多个图块;
②可选择性的设置两相邻小图块之间的重叠率。
三、示例数据
本文采用的示例数据为ISPRS Potsdam 2D Segmentation数据集的标签数据(如果要替换为自己的数据,在代码中替换文件路径即可)。原始数据大小为6000*6000,我们要将其划分为很多个512*512的小图块,对于边缘位置不够512的行和列,以倒数512形成裁剪区域,示例:
四、明确任务之后,上代码!
有需要的小伙伴,请注意看注释哦!
import cv2
import os
import math
import shutil
#根据任务要求,定义一个caijian函数
def caijian(path, path_out, size_w=512, size_h=512, step=256): #step为步长,设置为256即相邻图片重叠50%
ims_list=os.listdir(path) #在此例中调用时,ims_list为['image.png', 'label.png']
for im_list in ims_list:
number = 0
name = im_list[:-4] #去除“.png”后缀
img = cv2.imread(path+im_list)#读取要切割的图片
size = img.shape
i=0
for h in range(0,size[0],step):
star_h = h #star_h表示起始高度,从0以步长step=256开始循环
for w in range(0,size[1],step):
star_w = w #star_w表示起始宽度,从0以步长step=256开始循环
end_h = star_h + size_h #end_h是终止高度
if end_h > size[0]:#如果边缘位置不够512的列
# 以倒数512形成裁剪区域
star_h = size[0] - size_h
end_h = star_h + size_h
i=i-1
end_w = star_w + size_w #end_w是中止宽度
if end_w > size[1]:#如果边缘位置不够512的行
# 以倒数512形成裁剪区域
star_w = size[1] - size_w
end_w = star_w + size_w
i=i-1
cropped = img[star_h:end_h, star_w:end_w]#执行裁剪操作
i=i+1
name_img = name + '_'+ str(star_h) +'_' + str(star_w)#用起始坐标来命名切割得到的图像,为的是方便后续标签数据抓取
# name_img = name + str(i)
cv2.imwrite('{}/{}.png'.format(path_out,name_img),cropped)#将切割得到的小图片存在path_out路径下
print("已成功执行!")
#将完整的图像划分为小块
if __name__ == '__main__':
ims_path = 'F:/Practice/test_02/Potsdam/image/'# 图像数据集的路径
#在result文件夹下,创建一个label_s文件夹,用于存放label切割的结果
path= 'F:/Practice/test_02//images'#切割得到的数据集存放路径,当caijian函数执行后label_s文件夹下,存放的是image和label切割的结果
if not os.path.exists(path):
os.makedirs(path)
caijian(ims_path, path, size_w=512, size_h=512, step=256)#调用caijian函数,如果相邻图片不想有重叠部分,则将step设置为512,即与裁剪的尺寸一致