东方耀AI技术分享

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 4471|回复: 1
打印 上一主题 下一主题

[课堂笔记] python的widerface生成voc格式的数据,生成xml文件的标注

[复制链接]

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14431
QQ
跳转到指定楼层
楼主
发表于 2020-11-3 17:24:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
python生成voc格式的数据,生成xml文件的标注



  1. # -*- coding: utf-8 -*-
  2. __author__ = u'东方耀 微信:dfy_88888'
  3. __date__ = '2019/7/15 下午3:23'
  4. __product__ = 'PyCharm'
  5. __filename__ = 'widerface2voc'

  6. # import os, cv2, sys, shutil
  7. import cv2
  8. import shutil
  9. from xml.dom.minidom import Document

  10. root_dir = '/home/dfy888/DataSets/WIDER Face DataSet'
  11. root_dir_voc = '/home/dfy888/DataSets/widerface_voc'


  12. def writexml(filename, saveimg, bboxes, xmlpath):
  13.     """
  14.     写成voc格式通用的xml文件
  15.     :param filename: 图片的路径
  16.     :param saveimg: 图片对象 cv2
  17.     :param bboxes: 多个人脸框集合
  18.     :param xmlpath: xml文件路径
  19.     :return:
  20.     """
  21.     doc = Document()
  22.     # 根节点
  23.     annotation = doc.createElement('annotation')
  24.     doc.appendChild(annotation)

  25.     folder = doc.createElement('folder')
  26.     # 注意:widerface_voc voc格式数据的文件夹名字
  27.     folder_name = doc.createTextNode('widerface_voc')
  28.     folder.appendChild(folder_name)
  29.     annotation.appendChild(folder)

  30.     filenamenode = doc.createElement('filename')
  31.     filename_name = doc.createTextNode(filename)
  32.     filenamenode.appendChild(filename_name)
  33.     annotation.appendChild(filenamenode)

  34.     source = doc.createElement('source')
  35.     annotation.appendChild(source)

  36.     database = doc.createElement('database')
  37.     database.appendChild(doc.createTextNode('wider face Database'))
  38.     source.appendChild(database)

  39.     annotation_s = doc.createElement('annotation')
  40.     annotation_s.appendChild(doc.createTextNode('PASCAL VOC2007'))
  41.     source.appendChild(annotation_s)

  42.     image = doc.createElement('image')
  43.     image.appendChild(doc.createTextNode('flickr'))
  44.     source.appendChild(image)

  45.     flickrid = doc.createElement('flickrid')
  46.     flickrid.appendChild(doc.createTextNode('-1'))
  47.     source.appendChild(flickrid)

  48.     owner = doc.createElement('owner')
  49.     annotation.appendChild(owner)

  50.     flickrid_o = doc.createElement('flickrid')
  51.     flickrid_o.appendChild(doc.createTextNode('dfy_88888'))
  52.     owner.appendChild(flickrid_o)

  53.     name_o = doc.createElement('name')
  54.     name_o.appendChild(doc.createTextNode('dfy_88888'))
  55.     owner.appendChild(name_o)

  56.     size = doc.createElement('size')
  57.     annotation.appendChild(size)

  58.     width = doc.createElement('width')
  59.     width.appendChild(doc.createTextNode(str(saveimg.shape[1])))
  60.     height = doc.createElement('height')
  61.     height.appendChild(doc.createTextNode(str(saveimg.shape[0])))
  62.     depth = doc.createElement('depth')
  63.     depth.appendChild(doc.createTextNode(str(saveimg.shape[2])))
  64.     size.appendChild(width)
  65.     size.appendChild(height)
  66.     size.appendChild(depth)

  67.     segmented = doc.createElement('segmented')
  68.     segmented.appendChild(doc.createTextNode('0'))
  69.     annotation.appendChild(segmented)

  70.     for i in range(len(bboxes)):
  71.         # bbox 四维向量: [左上角坐标x y 宽高 w h]
  72.         bbox = bboxes[i]
  73.         objects = doc.createElement('object')
  74.         annotation.appendChild(objects)

  75.         object_name = doc.createElement('name')
  76.         # 只有人脸
  77.         object_name.appendChild(doc.createTextNode('face'))
  78.         objects.appendChild(object_name)

  79.         pose = doc.createElement('pose')
  80.         pose.appendChild(doc.createTextNode('Unspecified'))
  81.         objects.appendChild(pose)

  82.         truncated = doc.createElement('truncated')
  83.         truncated.appendChild(doc.createTextNode('1'))
  84.         objects.appendChild(truncated)

  85.         difficult = doc.createElement('difficult')
  86.         difficult.appendChild(doc.createTextNode('0'))
  87.         objects.appendChild(difficult)

  88.         bndbox = doc.createElement('bndbox')
  89.         objects.appendChild(bndbox)
  90.         # xmin ymin 就是标记框 左上角的坐标
  91.         xmin = doc.createElement('xmin')
  92.         xmin.appendChild(doc.createTextNode(str(bbox[0])))
  93.         bndbox.appendChild(xmin)
  94.         ymin = doc.createElement('ymin')
  95.         ymin.appendChild(doc.createTextNode(str(bbox[1])))
  96.         bndbox.appendChild(ymin)
  97.         # xmax ymax 就是标记框 右下角的坐标
  98.         xmax = doc.createElement('xmax')
  99.         xmax.appendChild(doc.createTextNode(str(bbox[0] + bbox[2])))
  100.         bndbox.appendChild(xmax)
  101.         ymax = doc.createElement('ymax')
  102.         ymax.appendChild(doc.createTextNode(str(bbox[1] + bbox[3])))
  103.         bndbox.appendChild(ymax)

  104.     with open(xmlpath, 'w') as f:
  105.         f.write(doc.toprettyxml(indent=''))


  106. def convert_imgset(img_set_type):
  107.     """
  108.     转换数据集(WiderFace---> VOC)
  109.     :param img_set_type: train or val
  110.     :return:
  111.     """
  112.     # 对应数据集中原始图片的路径
  113.     img_dir = root_dir + '/WIDER_' + img_set_type + '/images'
  114.     # ground truth 的路径 (标注文件中)
  115.     gt_filepath = root_dir + '/wider_face_split/wider_face_' + img_set_type + '_bbx_gt.txt'

  116.     fwrite = open(root_dir_voc + '/ImageSets/Main/' + img_set_type + '.txt', 'w')

  117.     print(img_dir)
  118.     print(gt_filepath)

  119.     # 表示我们解析到了第几张图片
  120.     index = 0
  121.     no_face_index = []
  122.     with open(gt_filepath, 'r') as gt_files:
  123.         # 为了快速 只取1000个图片样本  实际可以是True
  124.         while(index < 5):
  125.             # 为什么是[: -1]? 去掉最后的空格
  126.             filename = gt_files.readline().strip()
  127.             # print('读取的filename:%s,其长度为:%d' % (filename, len(filename)))
  128.             if filename == '' or filename is None:
  129.                 break
  130.             # 图片的绝对路径
  131.             img_path = img_dir + '/' + filename
  132.             print('读取的图片绝对路径:', img_path)
  133.             img = cv2.imread(img_path)
  134.             # 可视化看看图片
  135.             # cv2.imshow('1', img)
  136.             # cv2.waitKey(0)
  137.             if not img.data:
  138.                 break

  139.             num_bbox = int(gt_files.readline())

  140.             if num_bbox == 0:
  141.                 # 还是需要读一下
  142.                 line = gt_files.readline()
  143.                 no_face_index.append(index)
  144.                 print('没有人脸框的特殊情况:', line)

  145.             bboxes = []
  146.             for i in range(num_bbox):
  147.                 # 每读取一行 就是一个人脸框 gt
  148.                 line = gt_files.readline()
  149.                 lines = line.split()
  150.                 # 前面4个值
  151.                 lines = lines[0: 4]
  152.                 # bbox 四维向量: [左上角坐标x y 宽高 w h]
  153.                 bbox = (int(lines[0]), int(lines[1]), int(lines[2]), int(lines[3]))

  154.                 # 可视化看看人脸框的矩形
  155.                 cv2.rectangle(img, (int(lines[0]), int(lines[1])),
  156.                               (int(lines[0]) + int(lines[2]), int(lines[1]) + int(lines[3])),
  157.                               color=(0, 0, 255), thickness=1)

  158.                 bboxes.append(bbox)

  159.             cv2.imshow(str(index), img)
  160.             cv2.waitKey(0)

  161.             filename = filename.replace('/', '_')
  162.             print('保存后的filename:', filename)

  163.             if len(bboxes) == 0:
  164.                 print('no face box')
  165.                 index += 1
  166.                 continue

  167.             cv2.imwrite('{}/JPEGImages/{}'.format(root_dir_voc, filename), img)

  168.             fwrite.write(filename.split('.')[0] + '\n')

  169.             xmlpath = '{}/Annotations/{}.xml'.format(root_dir_voc, filename.split('.')[0])

  170.             writexml(filename, img, bboxes, xmlpath)

  171.             print('success number is %d' % index)

  172.             index += 1
  173.         # 循环结束后
  174.         print('所有没有人脸的索引:', no_face_index)

  175.     fwrite.close()


  176. if __name__ == '__main__':
  177.     # num of train images :12879 所有没有人脸的索引: [279, 3808, 7512, 9227]
  178.     # convert_imgset('train')
  179.     # num of val images : 3225 所有没有人脸的索引: []
  180.     convert_imgset('val')
  181.     # 修改文件名  原本是 train.txt  val.txt
  182.     # shutil.move(root_dir_voc + '/ImageSets/Main/' + 'train.txt', root_dir_voc + '/ImageSets/Main/' + 'trainval.txt')
  183.     # shutil.move(root_dir_voc + '/ImageSets/Main/' + 'val.txt', root_dir_voc + '/ImageSets/Main/' + 'test.txt')





复制代码


让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

0

主题

100

帖子

236

积分

2W人工智能培训

Rank: 10Rank: 10Rank: 10

积分
236
沙发
发表于 2020-11-10 19:49:38 | 只看该作者
积分积分积分
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|人工智能工程师的摇篮 ( 湘ICP备2020019608号-1 )

GMT+8, 2024-4-25 18:11 , Processed in 0.171480 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表