VOC2007数据集制作

VOC2007数据集制作


https://github.com/Parlefan/create-voc2007-dataset#voc2007数据集制作



**********************************************README************************************************************

数据准备

  • 图片

    • jpg格式
    • 命名随意,可以包含路径
  • 标注

    • 类似给出的output.txt形式的标注
    • 可以使用LabelPicture的标注工具来标注

使用

  • 首先用rename_images.py来遍历保存图片的文件夹,以编号的形式命名所有图片

  • 然后使用create_annotations.py来生成xml形式的VOC标注

  • 使用create_imagesets.py来生成ImageSets的文件

    • 可以自己修改train、test、val的比例





*********************************create_annotations.py**********************************
# -*- coding:utf-8 -*-
__author__ = "peic"
   
  import xml.dom
  import xml.dom.minidom
  import os
   
  from PIL import Image
   
  # xml文件规范定义
  _INDENT = ' ' * 4
  _NEW_LINE = '\n'
  _FOLDER_NODE = 'person'
  _ROOT_NODE = 'annotation'
  _DATABASE_NAME = 'Caltech'
  _ANNOTATION = 'PASCAL VOC2007'
  _AUTHOR = 'Peic'
   
  _SEGMENTED = '0'
  _DIFFICULT = '0'
  _TRUNCATED = '0'
  _POSE = 'Unspecified'
   
  _IMAGE_PATH = 'img\\'
  _TXT_PATH = 'img\\output.txt'
  _IMAGE_COPY_PATH = 'JPEGImages'
  _ANNOTATION_SAVE_PATH = 'Annotations'
   
  _IMAGE_CHANNEL = 3
   
   
  # 封装创建节点的过程
  def createElementNode(doc, tag, attr):
  # 创建一个元素节点
  element_node = doc.createElement(tag)
   
  # 创建一个文本节点
  text_node = doc.createTextNode(attr)
   
  # 将文本节点作为元素节点的子节点
  element_node.appendChild(text_node)
   
  return element_node
   
   
  # 封装添加一个子节点的过程
  def createChildNode(doc, tag, attr, parent_node):
   
  child_node = createElementNode(doc, tag, attr)
  parent_node.appendChild(child_node)
   
   
   
  # object节点比较特殊
  def createObjectNode(doc, attrs):
  object_node = doc.createElement('object')
  createChildNode(doc, 'name', attrs['classification'], object_node)
  createChildNode(doc, 'pose', _POSE, object_node)
  createChildNode(doc, 'truncated', _TRUNCATED, object_node)
  createChildNode(doc, 'difficult', _DIFFICULT, object_node)
   
  bndbox_node = doc.createElement('bndbox')
  createChildNode(doc, 'xmin', attrs['xmin'], bndbox_node)
  createChildNode(doc, 'ymin', attrs['ymin'], bndbox_node)
  createChildNode(doc, 'xmax', attrs['xmax'], bndbox_node)
  createChildNode(doc, 'ymax', attrs['ymax'], bndbox_node)
  object_node.appendChild(bndbox_node)
   
  return object_node
   
   
  # 将documentElement写入XML文件中
  def writeXMLFile(doc, filename):
  tmpfile = open('tmp.xml', 'w')
  doc.writexml(tmpfile, addindent=' '*4, newl='\n', encoding='utf-8')
  tmpfile.close()
   
   
  # 删除第一行默认添加的标记
  fin = open('tmp.xml')
  fout = open(filename, 'w')
  lines = fin.readlines()
   
  for line in lines[1:]:
  if line.split():
  fout.writelines(line)
   
  #new_lines = ''.join(lines[1:])
  #fout.write(new_lines)
  fin.close()
  fout.close()
   
   
  # 创建XML文档并写入节点信息
  def createXMLFile(attrs, width, height, filename):
   
  # 创建文档对象, 文档对象用于创建各种节点
  my_dom = xml.dom.getDOMImplementation()
  doc = my_dom.createDocument(None, _ROOT_NODE, None)
   
  # 获得根节点
  root_node = doc.documentElement
   
  # folder节点
  createChildNode(doc, 'folder', _FOLDER_NODE, root_node)
   
  # filename节点
  createChildNode(doc, 'filename', attrs['name'], root_node)
   
  # source节点
  source_node = doc.createElement('source')
  # source的子节点
  createChildNode(doc, 'database', _DATABASE_NAME, source_node)
  createChildNode(doc, 'annotation', _ANNOTATION, source_node)
  createChildNode(doc, 'image', 'flickr', source_node)
  createChildNode(doc, 'flickrid', 'NULL', source_node)
  root_node.appendChild(source_node)
   
  # owner节点
  owner_node = doc.createElement('owner')
  # owner的子节点
  createChildNode(doc, 'flickrid', 'NULL', owner_node)
  createChildNode(doc, 'name', _AUTHOR, owner_node)
  root_node.appendChild(owner_node)
   
  # size节点
  size_node = doc.createElement('size')
  createChildNode(doc, 'width', str(width), size_node)
  createChildNode(doc, 'height', str(height), size_node)
  createChildNode(doc, 'depth', str(_IMAGE_CHANNEL), size_node)
  root_node.appendChild(size_node)
   
  # segmented节点
  createChildNode(doc, 'segmented', _SEGMENTED, root_node)
   
  # object节点
  object_node = createObjectNode(doc, attrs)
  root_node.appendChild(object_node)
   
  # 写入文件
  writeXMLFile(doc, filename)
   
   
   
  if __name__ == "__main__":
   
  ouput_file = open(_TXT_PATH)
  current_dirpath = os.path.dirname(os.path.abspath('__file__'))
   
  if not os.path.exists(_ANNOTATION_SAVE_PATH):
  os.mkdir(_ANNOTATION_SAVE_PATH)
  if not os.path.exists(_IMAGE_COPY_PATH):
  os.mkdir(_IMAGE_COPY_PATH)
   
  lines = ouput_file.readlines()
  for line in lines:
  s = line.rstrip('\n')
  array = s.split()
  print
  attrs = dict()
  attrs['name'] = array[0]
  attrs['classification'] = 'face'
  attrs['xmin'] = array[1]
  attrs['ymin'] = array[2]
  attrs['xmax'] = array[3]
  attrs['ymax'] = array[4]
   
  # 构建XML文件名称
  xml_file_name = os.path.join(_ANNOTATION_SAVE_PATH, (attrs['name'].split('.'))[0] + '.xml')
  print xml_file_name
   
  if os.path.exists( xml_file_name):
  # print('do exists')
  existed_doc = xml.dom.minidom.parse(xml_file_name)
  root_node = existed_doc.documentElement
   
  # 如果XML存在了, 添加object节点信息即可
  object_node = createObjectNode(existed_doc, attrs)
  root_node.appendChild(object_node)
   
  # 写入文件
  writeXMLFile(existed_doc, xml_file_name)
   
  else:
  # print('not exists')
  # 如果XML文件不存在, 创建文件并写入节点信息
  img_name = attrs['name']
  img_path = os.path.join(current_dirpath, _IMAGE_PATH, img_name)
  img = Image.open(img_path)
  width, height = img.size
   
  # 将图片保存在JPEGImages文件夹中一份
  img.save(os.path.join(current_dirpath, _IMAGE_COPY_PATH, img_name), 'jpeg')
  img.close()
   
  # 创建XML文件
  createXMLFile(attrs, width, height, xml_file_name)

**************************************************create_imagesets.py****************************************************************

# -*- coding:utf-8 -*-
   
  import os
   
  __author__ = 'peic'
   
  _IMAGE_SETS_PATH = 'ImageSets'
  _MAin_PATH = 'ImageSets\\Main'
  _XML_FILE_PATH = 'Annotations'
   
  if __name__ == '__main__':
   
  if os.path.exists(_IMAGE_SETS_PATH):
  print('ImageSets dir is already exists')
  if os.path.exists(_MAin_PATH):
  print('Main dir is already in ImageSets')
  else:
  os.mkdir(_IMAGE_SETS_PATH)
  os.mkdir(_MAin_PATH)
   
  print _MAin_PATH
   
  # 测试集, 总数据的50%
  f_test = open(os.path.join(_MAin_PATH, 'test.txt'), 'w')
  # 训练和验证集, 除去测试的剩余50%
  f_trainval = open(os.path.join(_MAin_PATH, 'trainval.txt'), 'w')
  # trainval中训练部分, trainval的50%
  f_train = open(os.path.join(_MAin_PATH, 'train.txt'), 'w')
  # trainval中验证集, trainval的50%
  f_val = open(os.path.join(_MAin_PATH, 'val.txt'), 'w')
   
  # 遍历XML文件夹
  for root, dirs, files in os.walk(_XML_FILE_PATH):
  i = 1
  j = 1
  for file in files:
  if i % 2:
  # 作为测试集
  f_test.writelines(str(file).split('.')[0] + '\n')
  else:
  # 训练和验证集
  f_trainval.writelines(str(file).split('.')[0] + '\n')
  if j % 2:
  # 训练集
  f_train.writelines(str(file).split('.')[0] + '\n')
  else:
  # 验证集
  f_val.writelines(str(file).split('.')[0] + '\n')
  j += 1
  i += 1
   
  f_test.close()
  f_train.close()
  f_trainval.close()
  f_val.close()



**************************************************rename_images.py***********************************************************
# _*_ coding:utf-8 _*_

#

from PIL import Image

import os

import re

import sys



if __name__ == "__main__":



if(len(sys.argv) != 2):

print("args is not 2!")

sys.exit(1);



BASE_PATH = sys.argv[1];

print(BASE_PATH)



# os.walk返回一个walk对象,是一个三元组

for rootpath, dirnames, filenames in os.walk(BASE_PATH):

name_number = 1

name_length = 6

for filename in filenames:

if(re.match("^(\d*).jpg", filename)):

name_str = (name_length - len(str(name_number))) * '0' + str(name_number) + ".jpg"

print name_str, '\n'

name_number = name_number + 1

image = Image.open(os.path.join(BASE_PATH, filename))

image.save(os.path.join(BASE_PATH, name_str), 'jpeg')

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值