luckygay

  • 5

    获得赞
  • 3

    发布的文章
  • 0

    答辩的项目

教你自制VOC数据集

FasterRCNN PyTorch

最后更新 2020-05-12 10:15 阅读 4673

最后更新 2020-05-12 10:15

阅读 4673

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就好了。 如果没用,参考原博,进行第三步修改。

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可,转载请附上原文出处链接和本声明。
本文链接地址:https://flyai.com/article/460
讨论
500字
表情
发送
删除确认
是否删除该条评论?
取消 删除