深度学习往往面临:1.数据标注过程很麻烦;2.部分场景数据集预测结果不佳
针对以上弊端,通过本文方法进行数据集扩充对训练过程尤为重要
本文主要依靠PIL(pillow)中的图像变换及增强模块进行图像数据集增强处理
并且在进行数据扩充的同时进行标注文件.xml
格式文件相应的修改
具体实现就分为如下两个模块吧,下边详解一下:
'''
批量读取文件夹路径下的图像,然后经过左右、上下翻转,亮度、对比度调整、色调调整进行图像数据集扩充,并自动复制其标签文件进行重命名保存
图像增强:亮度、对比度、饱和度变换
'''import matplotlib.pyplot as plt
import xmlTF
from PIL import Image,ImageEnhance
import shutil
import ospath='./imgs/'t=1200
imgname=""
xmlname=""
imglist=os.listdir(path)
for i in range(len(imglist)):str_=imglist[i].split(".")[-1]if(str_=="jpg"):imgname=path+imglist[i]xmlname = path + imglist[i].split(".")[0] + ".xml"elif(str_=="xml"):continueprint(t," - ",imgname)img_ = Image.open(imgname)# 水平翻转img0 = img_.transpose(Image.FLIP_LEFT_RIGHT)img0.save(path+str(t)+".jpg")shutil.copy(xmlname, path+str(t)+".xml")newname = path + str(t) + ".xml"xmlTF.xmlFlip(newname,1)t+=1# 垂直翻转img1=img_.transpose(Image.FLIP_TOP_BOTTOM)img1.save(path + str(t) + ".jpg")shutil.copy(xmlname, path + str(t) + ".xml")newname = path + str(t) + ".xml"xmlTF.xmlFlip(newname, 2)t += 1# 对角线翻转img2=img1.transpose(Image.FLIP_LEFT_RIGHT)img2.save(path + str(t) + ".jpg")shutil.copy(xmlname, path + str(t) + ".xml")newname = path + str(t) + ".xml"xmlTF.xmlFlip(newname, 3)t += 1## plt.subplot(2,2,1)# plt.imshow(img_)# plt.subplot(2,2,2)# plt.imshow(img0)# plt.subplot(2,2,3)# plt.imshow(img1)# plt.subplot(2,2,4)# plt.imshow(img2)# plt.show()#色彩调整:# 亮度调整brightEnhancer = ImageEnhance.Brightness(img_.copy())img_0 = brightEnhancer.enhance(0.8)img_0.save(path + str(t) + ".jpg")shutil.copy(xmlname, path + str(t) + ".xml")t += 1img_1 = brightEnhancer.enhance(1.5)img_1.save(path + str(t) + ".jpg")shutil.copy(xmlname, path + str(t) + ".xml")t += 1# 对比度调整contrastEnhancer = ImageEnhance.Contrast(img_.copy())img_2 = contrastEnhancer.enhance(1.2)img_2.save(path + str(t) + ".jpg")shutil.copy(xmlname, path + str(t) + ".xml")t += 1img_3 = contrastEnhancer.enhance(1.7)img_3.save(path + str(t) + ".jpg")shutil.copy(xmlname, path + str(t) + ".xml")t += 1# 饱和度调整colorEnhancer = ImageEnhance.Color(img_.copy())img_4 = colorEnhancer.enhance(1.2)img_4.save(path + str(t) + ".jpg")shutil.copy(xmlname, path + str(t) + ".xml")t += 1img_5 = colorEnhancer.enhance(1.8)img_5.save(path + str(t) + ".jpg")shutil.copy(xmlname, path + str(t) + ".xml")t += 1# 清晰度调整SharpnessEnhancer = ImageEnhance.Sharpness(img_.copy())img_6 = SharpnessEnhancer.enhance(0.7)img_6.save(path + str(t) + ".jpg")shutil.copy(xmlname, path + str(t) + ".xml")t += 1img_7 = SharpnessEnhancer.enhance(1.5)img_7.save(path + str(t) + ".jpg")shutil.copy(xmlname, path + str(t) + ".xml")t += 1# plt.figure()# plt.subplot(2, 5, 1),plt.imshow(img_),plt.title("1")# plt.subplot(2, 5, 2),plt.imshow(img_0),plt.title("2")# plt.subplot(2, 5, 3),plt.imshow(img_2),plt.title("3")# plt.subplot(2, 5, 4),plt.imshow(img_4),plt.title("4")# plt.subplot(2, 5, 5),plt.imshow(img_6),plt.title("5")## plt.subplot(2, 5, 6), plt.imshow(img_),plt.title("6")# plt.subplot(2, 5, 7), plt.imshow(img_1),plt.title("7")# plt.subplot(2, 5, 8), plt.imshow(img_3),plt.title("8")# plt.subplot(2, 5, 9), plt.imshow(img_5),plt.title("9")# plt.subplot(2, 5, 10), plt.imshow(img_7),plt.title("10")## plt.show()
.xml
文件主要是读写其内容,并针对性的 做出一些修改xmlTF.py
如下:'''
实现对.xml标签文件的一系列修改:1.实现传入xml文件的检测框的水平、竖直与对角线翻转
'''import os
import xml.etree.ElementTree as ETdef checkname(xmlpath):with open(xmlpath, 'r') as f:tree = ET.parse(f)root = tree.getroot()# print(root)# print(list(root))in_name=root.find("filename").textin_path=root.find("path").textxmlname=xmlpath.split("\\")[-1].split(".")[0]a=xmlnameb=in_name.split(".")[0]if(xmlname != in_name.split(".")[0]):print(a, " - ", b)root.find("filename").text=xmlname +".jpg"root.find("path").text=in_path.rsplit("\\",1)[0]+"\\"+xmlname +".jpg"tree.write(xmlpath)def xmlFlip(xmlpath, flg):'''当图像发生翻转时,相对应的xml文件内容也做出相应变化:param xmlpath: xml路径名字:param flg: 操作类型:1-水平、 2-竖直、 3-对角线翻转:return:保存修改后的文件'''#print(xmlpath)# read xmlwith open(xmlpath, 'r') as f:tree = ET.parse(f)root = tree.getroot()# print(root)# print(list(root))size = root.find("size")w = int(size.find("width").text)h = int(size.find("height").text)# print("w = ",w.text,"h = ",h.text)# 查看多个重复元素for obj in root.iter("object"):box = obj.find("bndbox")x_min = int(box.find("xmin").text)y_min = int(box.find("ymin").text)x_max = int(box.find("xmax").text)y_max = int(box.find("ymax").text)#水平翻转,x变化if flg==1:box.find("xmin").text = str(w - 1 - x_min)box.find("xmax").text = str(w - 1 - x_max)#竖直翻转,y变化elif flg==2:box.find("ymin").text = str(h - 1 - y_min)box.find("ymax").text = str(h - 1 - y_max)#对角线翻转,x,y都发生变化elif flg==3:box.find("xmin").text = str(w - 1 - x_min)box.find("xmax").text = str(w - 1 - x_max)box.find("ymin").text = str(h - 1 - y_min)box.find("ymax").text = str(h - 1 - y_max)# print("x1,y1,x2,y2 = ",[x_min,y_min,x_max,y_max])#如果存在中文,则需要在.write()中设置 encoding='utf-8'# tree.write(newpath + "//" + i)# print(newpath + "//" + i)# newpath="./xmls/"+xmlpath.split("/")[-1]# tree.write(newpath)tree.write(xmlpath)
xml文件
一致,当然,如果内容中filename
和path
不一致,但是xml名字
与图像
名称一致,标签也是一一对应的,但是俺略微有点强迫症,就实现了一下检查名称并修改,其调用如下:#批量赋值图像的标注文件.xml并重命名为图像名字import os
import shutil
import xmlTF# imgspath="./file3/jpg"
# xmlpath="file3/jpg/005.xml"
imgspath="./images"
xmlpath="./images/0.xml"for root,dirs,files in os.walk(imgspath,topdown=True):for name in files:str=name.split('.')if(str[-1] == 'jpg'):newname=str[0]+'.xml'newxml=os.path.join(root,newname)print(newxml)if not os.path.exists(newxml):shutil.copy(xmlpath,newxml)xmlTF.checkname((newxml))