正样本图片示例(为正样本文件夹的其中一张,对应的xml目标框label为皮卡丘):
示例xml文件内容:
上代码(输入输出文件夹改为自己的即可,笔者预设裁剪尺寸为[64, 128, 256, 416, 608],可自定义,但一定要小于图片尺寸):
from PIL import Image
import random
import xml.etree.ElementTree as ET
count = 0 ##计算生成图片数
num=0 ## 现在对哪张图片进行裁剪(图片已经按序号顺序排列在文件夹下)
num_eve = 0 ##各图片目前裁剪出几张了
while 1:
img = Image.open('C:/Users/hq/Desktop/pikaqiu_data/pikaqiu_crop_img/%s.jpg' % str(num+1)) # 打开当前路径图像
# 加载label数据
xml_name = 'C:/Users/hq/Desktop/pikaqiu_data/pikaqiu_crop_xml/%s.xml' % str(num+1)
root = ET.parse(xml_name).getroot()
boxes = []
for obj in root.iter('object'):
#name = obj.find('name').text
xmlbox = obj.find('bndbox')
x0 = int(xmlbox.find('xmin').text)
y0 = int(xmlbox.find('ymin').text)
x1 = int(xmlbox.find('xmax').text)
y1 = int(xmlbox.find('ymax').text)
boxes.append([x0, y0, x1, y1])
# 设置截取尺寸
strides = [64, 128, 256, 416, 608]
xyl = [random.randint(1,img.size[0]), random.randint(1,img.size[1])]
for i in range(len(strides)):
if (xyl[0]+strides[i]<=img.size[0]) and (xyl[1]+strides[i]<=img.size[1]):
box1 = (xyl[0], xyl[1], xyl[0]+strides[i], xyl[1]+strides[i]) # 设置图像裁剪区域 (x左上,y左上,x右下,y右下)
# 判断截取坐标是否位于标注框内
for _, box in enumerate(boxes):
if (max(xyl[0], box[0]) > min(xyl[0]+strides[i], box[2])) or (max(xyl[1], box[1]) > min(xyl[1]+strides[i], box[3])):
image1 = img.crop(box1) # 图像裁剪
image1.save('C:/Users/hq/Desktop/pikaqiu_data/pikaqiu_crop/%s_%s_%s.jpg' %(str(num+1), str(strides[i]), str(count+1))) # 存储裁剪得到的图像
print("successfully save %s_%s_%s pic" %(str(num+1), str(strides[i]), str(count+1)))
count+=1
num_eve+=1
if num_eve== 20:
num_eve=0
num += 1 #设定num_eve为每张图片每个strides需要裁剪出的图片数
if num==5:
exit(0)
生成结果:
注:每张正样本生成的图片尺寸、数量均可自定义。
负样本的xml文件生成:
参考笔者之前的博客即可:https://blog.csdn.net/weixin_44414948/article/details/106078906