教你自制VOC数据集
FasterRCNN PyTorch
最后更新 2020-05-12 10:15 阅读 4809
最后更新 2020-05-12 10:15
阅读 4809
FasterRCNN PyTorch
环境 win10 cuda10 pytorch1.0
项目地址:链接
参考博客:https://blog.csdn.net/weixin_43380510/article/details/83004127
data文件夹格式:
---VOC2007 ------Annotations ------ImagesSet ---------Main --------trainval.txt --------test.txt ------JPEGImages
Annotations放xml文件
JPEGImages放图片 Main中存放txt文件,里面是图片名称,不带“.jpg”
脚本制作txt代码如下:
import os path_name = r'D:\Coding\python\faster-rcnn.pytorch-pytorch-1.0\data\VOCdevkit\VOC2007\JPEGImages' f = open('D:/Coding/python/faster-rcnn.pytorch-pytorch-1.0/data/VOCdevkit/VOC2007/ImagesSet/Main/trainval.txt', mode='w') for item in os.listdir(path_name): original_name = os.path.join(path_name, item) print(item)#原始名称带.jpg str_name=item.split('.')#分割字符 print(str_name[0]) f.write(str_name[0] + '\n')
又参考链接博主的github,将xml文件中的folder改名,也可根据博主的代码修改其他属性。
# coding=utf-8 import os import os.path import xml.dom.minidom path = "D:\\Coding\python\\faster-rcnn.pytorch-pytorch-1.0\\data\\VOCdevkit\\VOC2007\\Annotations" files = os.listdir(path) # 得到文件夹下所有文件名称 for xmlFile in files: # 遍历文件夹 if not os.path.isdir(xmlFile): # 判断是否是文件夹,不是文件夹才打开 #print(xmlFile) # 将获取的xml文件名送入到dom解析 dom = xml.dom.minidom.parse(os.path.join(path, xmlFile)) # 输入xml文件具体路径 root = dom.documentElement # 获取标签<name>以及<folder>的值 #name = root.getElementsByTagName('filename') folder = root.getElementsByTagName('folder') cnt=0 # 对每个xml文件的多个同样的属性值进行修改。此处将每一个<name>属性修改为plane,每一个<folder>属性修改为VOC2007 # for i in range(len(name)): # print(name[i].firstChild.data) # name[i].firstChild.data = 'res'+str(cnt)+'.jpg' # #print(name[i].firstChild.data) # cnt += 1 # # print(name[i].firstChild.data) for i in range(len(folder)): print(folder[i].firstChild.data) folder[i].firstChild.data = 'VOC2007' print(folder[i].firstChild.data) # 将属性存储至xml文件中 with open(os.path.join(path, xmlFile), 'w') as fh: dom.writexml(fh) print('已写入')
遇到的一些问题及解决方案
1 自制的xml中含有中文字符,读取失败
这个问题真的很烦,一个个改又太麻烦了,我的path中含有中文,想用上面的方法批量修改,但是xml.dom.minidom.parse(os.path.join(path, xmlFile))这里会报错,也就是都都读不了,试了网上的代码都不行,干脆……我就先转成txt,进行读写,再转成xml,也是很快的,不用在意那些encode方式了(真是烦死了…… 批量xml转txt,同样也可txt转xml
import os path_name = r'D:\NEU-DET\IMAGES' # 批量修改的文件夹路径 i = 0 # 起始数字 for item in os.listdir(path_name): original_name = os.path.join(path_name, item) new_name = os.path.join(path_name, ('res'+str(i)+'.jpg')) #上面一行选择自己想要的格式及命名方式 print(new_name) os.rename(original_name, new_name) # 重命名 i += 1
txt修改,我也改了个脚本,主要把path那行删掉,把第一行改了改:
import os,sys path_name = r'D:\Study\研一下\test' # 批量修改的txt文件夹路径 #f = open(r'D:\Coding\left.txt', mode='w') for item in os.listdir(path_name): original_name = os.path.join(path_name, item) print(item) str_name=item.split('.') file_name=str_name[0]+'.'+str_name[1] f = open(path_name+"\\"+item, 'r')#这个用来读取源文件 flist = f.readlines() w= open(path_name+"\\"+item, 'w')#这个用来写新文件替换旧文件,和原文件同名可覆盖原文件 for l in flist: if 'version' in l: l = l.replace('<?xml version="1.0" ?><annotation>', '<annotation>') #replace函数进行替换 #if 'path'not in l: #这里是为了删除带path那一行 w.write(l) # f.writelines(flist)
写完后转回xml就好了……我可真是另辟蹊径的小机灵鬼哈哈哈哈哈哈哈
2 Keyerror:‘none’
这个是因为我的撒比误操作,labelImg画框框时候,灵机一动画了个"none",忘了加进class中了,我找了半天……这个可以用用上面的随便一种方式,筛选name是否都是你的class,找出错误文件,删掉就好。
3 keyerror:‘width’
删掉/faster-rcnn.pytorch/data/cache/voc_2007_trainval_gt_roidb.pkl介个就好。
4 assert(boxes[:,2]>=boxes[:,0]).all()
介个就是,画的框框太靠边了,问题不大……
参考链接:https://blog.csdn.net/xzzppp/article/details/52036794
修改lib/datasets/imdb.py,append_flipped_images()函数,在一行代码为 boxes[:, 2] = widths[i] - oldx1 - 1下加入代码:
for b in range(len(boxes)): if boxes[b][2]< boxes[b][0]: boxes[b][0] = 0
修改lib/datasets/pascal_voc.py,_load_pascal_annotation()函数
for ix, obj in enumerate(objs): bbox = obj.find('bndbox') # Make pixel indexes 0-based x1 = float(bbox.find('xmin').text) y1 = float(bbox.find('ymin').text) x2 = float(bbox.find('xmax').text) y2 = float(bbox.find('ymax').text)
x1 y1 x2 y2本来都是有-1的,全部删掉-1就好了。
如果没用,参考原博,进行第三步修改。