在裁剪大图片的时候,存在不能完全切割的问题,将大图片切成小图片制作训练集时,不能完全切割会造成对图像信息的浪费。我简单写了一个可以将图片完全切割的代码。
示例:
原图大小:3000×4000×3(height × width × channels)
目标大小:512×512×3 (height × width × channels)
图-1 原图
代码:
#Part1:导入相关模块 import cv2 from tqdm import tqdm import os #Part2:设置裁剪目标图片大小,设置输入输出位置 size = 512 out_image_path = "D:/out_image_path/" out_label_path = "D:/out_label_path/" in_image_path = "D:/in_image_path/" in_label_path = "D:/in_label_path/" #Part3:设置GPU os.environ["CUDA_VISIBLE_DEVICES"] = "0" #Part4:读取图片和标签数量 origin_images_path = [] for i in os.listdir(in_image_path): origin_images_path.append(in_image_path + i) origin_labels_path = [] for j in os.listdir(in_label_path): origin_labels_path.append(in_label_path + j) #Part4:裁剪函数 def generate_train_dataset(out_image_path, out_label_path, input_height, input_width): p_count = 0 #裁剪后图片数量统计 images_path = origin_images_path labels_path = origin_labels_path main_height_num = input_height // size #以整除的形式算出能够完整不重复切出目标大小的区域 main_width_num = input_width // size #以整除的形式算出能够完整不重复切出目标大小的区域 main_count = main_width_num*main_height_num #将不重复完整切割区域定义为主切割区 for i in tqdm(range(len(images_path))): count_m = 0 #主切割区切图数量统计 count_h = 0 #下边缘边角区切图数量统计 count_w = 0 #右边缘边角区切图数量统计 image = cv2.imread(images_path[i], 1) #根据需要设置参数值,如变化,注意下方切图通道数 label = cv2.imread(labels_path[i], 1) #根据需要设置参数值,如变化,注意下方切图通道数 X_height, X_width = image.shape[0], image.shape[1] width_start = 0 height_start = 0 while count_m < main_count: image_ogi = image[height_start: height_start + size, width_start: width_start + size, :] label_ogi = label[height_start: height_start + size, width_start: width_start + size, :] cv2.imwrite((out_image_path + '%d_img.jpg' % p_count), image_ogi) #注意目标图片格式 cv2.imwrite((out_label_path + '%d_lab.png' % p_count), label_ogi) #注意目标图片格式 count_m += 1 p_count += 1 width_start += size if width_start == size * main_width_num : height_start = height_start +size width_start = 0 width_start = 0 height_start = X_height - size while count_w < main_width_num + 1 : if X_width - width_start < size: width_start = X_width - size image_ogi = image[height_start: height_start + size, width_start: width_start + size, :] label_ogi = label[height_start: height_start + size, width_start: width_start + size, :] cv2.imwrite((out_image_path + '%d_img.jpg' % p_count), image_ogi) cv2.imwrite((out_label_path + '%d_lab.png' % p_count), label_ogi) count_w += 1 p_count += 1 width_start += size width_start = X_width - size height_start = 0 while count_h < main_height_num: #注意区别上一个while循环,这里的循环数比上一个少1,避免最右下角被重复切图 if X_height - height_start < size: height_start = X_height - size image_ogi = image[height_start: height_start + size, width_start: width_start + size, :] label_ogi = label[height_start: height_start + size, width_start: width_start + size, :] cv2.imwrite((out_image_path + '%d_img.jpg' % p_count), image_ogi) cv2.imwrite((out_label_path + '%d_lab.png' % p_count), label_ogi) count_h += 1 p_count += 1 height_start += size #调用 if __name__ == '__main__': if not os.path.exists(out_image_path): os.mkdir(out_image_path) if not os.path.exists(out_label_path): os.mkdir(out_label_path) generate_train_dataset(out_image_path=out_image_path, out_label_path=out_label_path,input_height=3000,input_width=4000) #设置参数
图-2 裁剪后
自动计算生成48张裁剪后图片。