使用imgaug库进行目标检测数据增强
·
import xml.etree.ElementTree as ET
import pickle
import os
from os import getcwd
import numpy as np
from PIL import Image
# 引入一个新的目标检测库
import imgaug as ia
from imgaug import augmenters as iaa
from utils import mkdir
ia.seed(1)
# 读取出图像中的目标框
def read_xml_annotation(root, image_id):
in_file = open(os.path.join(root, image_id))
tree = ET.parse(in_file)
root = tree.getroot()
bndboxlist = []
for object in root.findall('object'): # 找到root节点下的所有country节点
bndbox = object.find('bndbox') # 子节点下节点rank的值
xmin = int(bndbox.find('xmin').text)
xmax = int(bndbox.find('xmax').text)
ymin = int(bndbox.find('ymin').text)
ymax = int(bndbox.find('ymax').text)
# print(xmin,ymin,xmax,ymax)
bndboxlist.append([xmin,ymin,xmax,ymax])
# print(bndboxlist)
bndbox = root.find('object').find('bndbox')
return bndboxlist # 以多维数组的形式保存
# 将xml文件中的旧坐标值替换成新坐标值,并保存,这个程序里面没有使用
# (506.0000, 330.0000, 528.0000, 348.0000) -> (520.4747, 381.5080, 540.5596, 398.6603)
def change_xml_annotation(root, image_id, new_target):
new_xmin = new_target[0]
new_ymin = new_target[1]
new_xmax = new_target[2]
new_ymax = new_target[3]
in_file = open(os.path.join(root, str(image_id) + '.xml')) # 这里root分别由两个意思
tree = ET.parse(in_file)
xmlroot = tree.getroot()
object = xmlroot.find('object')
bndbox = object.find('bndbox')
xmin = bndbox.find('xmin')
xmin.text = str(new_xmin)
ymin = bndbox.find('ymin')
ymin.text = str(new_ymin)
xmax = bndbox.find('xmax')
xmax.text = str(new_xmax)
ymax = bndbox.find('ymax')
ymax.text = str(new_ymax)
tree.write(os.path.join(root, str(image_id) + "_aug" + '.xml'))
# 仅仅是替换,并没有新建
def change_xml_list_annotation(root, image_id, new_target, saveroot, id):
in_file = open(os.path.join(root, str(image_id) + '.xml')) # 读取原来的xml文件
tree = ET.parse(in_file) # 读取xml文件
xmlroot = tree.getroot()
index = 0
# 将bbox中原来的坐标值换成新生成的坐标值
for object in xmlroot.findall('object'): # 找到root节点下的所有country节点
bndbox = object.find('bndbox') # 子节点下节点rank的值
# xmin = int(bndbox.find('xmin').text)
# xmax = int(bndbox.find('xmax').text)
# ymin = int(bndbox.find('ymin').text)
# ymax = int(bndbox.find('ymax').text)
# 注意new_target原本保存为高维数组
### 要是更换数据集的话这里需要改一下
for i in range(4):
if new_target[index][i] < 0:
new_target[index][i] = 0
if new_target[index][i] > 500:
new_target[index][i] = 500
new_xmin = new_target[index][0]
new_ymin = new_target[index][1]
new_xmax = new_target[index][2]
new_ymax = new_target[index][3]
xmin = bndbox.find('xmin')
xmin.text = str(new_xmin)
ymin = bndbox.find('ymin')
ymin.text = str(new_ymin)
xmax = bndbox.find('xmax')
xmax.text = str(new_xmax)
ymax = bndbox.find('ymax')
ymax.text = str(new_ymax)
index = index + 1
tree.write(os.path.join(saveroot, str(image_id) + "_aug_" + str(id) + '.xml'))
# tree.write(os.path.join(saveroot, str(image_id) + '.xml'))
if __name__ == "__main__":
IMG_DIR = r"D:/catalogue/master/generate_data/VOC_30/JPEGTrain"
XML_DIR = r"D:/catalogue/master/generate_data/VOC_30/AnnoTrain"
# 存储增强后的影像文件夹路径
AUG_IMG_DIR = r"D:\Catalogue\master\generate_data\paste_mixup_30\VOC2007_multmixup_3\JPEGImages"
mkdir(AUG_IMG_DIR)
# 存储增强后的XML文件夹路径
AUG_XML_DIR = r"D:\Catalogue\master\generate_data\paste_mixup_30\VOC2007_multmixup_3\Annotations"
mkdir(AUG_XML_DIR)
AUGLOOP = 1 # 每张影像增强的数量
boxes_img_aug_list = []
new_bndbox = []
new_bndbox_list = []
sometimes = lambda aug: iaa.Sometimes(0.25, aug)
seq = iaa.Sequential([
iaa.Flipud(1),
#sometimes(iaa.Multiply((0.7, 1.3))),
sometimes(iaa.GaussianBlur(sigma=(0, 3.0))),
sometimes(iaa.Cutout(nb_iterations=(1, 5), size=0.1, squared=False)),
sometimes(iaa.Affine(
translate_px={"x": 15, "y": 15},
scale=(0.8, 0.95),
rotate=(-30, 30)
))
])
# 得到当前运行的目录和目录当中的文件,其中sub_folders可以为空
for root, sub_folders, files in os.walk(XML_DIR):
# 遍历没一张图片
for name in files:
bndbox = read_xml_annotation(XML_DIR, name)
for epoch in range(AUGLOOP):
seq_det = seq.to_deterministic() # 保持坐标和图像同步改变,而不是随机
# 读取图片
img = Image.open(os.path.join(IMG_DIR, name[:-4] + '.jpg'))
img = np.array(img)
# bndbox 坐标增强,依次处理所有的bbox
for i in range(len(bndbox)):
bbs = ia.BoundingBoxesOnImage([
ia.BoundingBox(x1=bndbox[i][0], y1=bndbox[i][1], x2=bndbox[i][2], y2=bndbox[i][3]),
], shape=img.shape)
bbs_aug = seq_det.augment_bounding_boxes([bbs])[0]
boxes_img_aug_list.append(bbs_aug)
# new_bndbox_list:[[x1,y1,x2,y2],...[],[]]
new_bndbox_list.append([int(bbs_aug.bounding_boxes[0].x1),
int(bbs_aug.bounding_boxes[0].y1),
int(bbs_aug.bounding_boxes[0].x2),
int(bbs_aug.bounding_boxes[0].y2)])
# 存储变化后的图片
image_aug = seq_det.augment_images([img])[0]
path = os.path.join(AUG_IMG_DIR, str(name[:-4]) + "_aug_" + str(epoch) + '.jpg')
# path = os.path.join(AUG_IMG_DIR, str(name[:-4]) + '.jpg')
# image_auged = bbs.draw_on_image(image_aug, thickness=0)
Image.fromarray(image_aug).save(path)
# 存储变化后的XML
change_xml_list_annotation(XML_DIR, name[:-4], new_bndbox_list,AUG_XML_DIR,epoch)
#print(str(name[:-4]) + "_aug_" + str(epoch) + '.jpg')
new_bndbox_list = []
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)