东方耀AI技术分享

标题: 目标检测之coco与voc格式的数据相互转换,并验证coco格式的... [打印本页]

作者: 东方耀    时间: 2020-12-1 15:58
标题: 目标检测之coco与voc格式的数据相互转换,并验证coco格式的...
目标检测之coco与voc格式的数据相互转换,并验证coco格式的脚本




  1. # -*- coding: utf-8 -*-
  2. __author__ = u'江锦炬 微信:dfy_88888'
  3. __date__ = '2020/12/1 上午11:27'
  4. __product__ = 'PyCharm'
  5. __filename__ = '08_coco_to_voc'


  6. # import os, cv2, sys, shutil
  7. import cv2
  8. import shutil
  9. import glob
  10. import os
  11. from xml.dom.minidom import Document
  12. # 将coco和yolo格式的目标检测数据集转换为voc格式的,方便进行anchor的k-means聚类

  13. train_dir_coco = "/media/jiang/AI_DataSets/DataSets/person_vehicle_coco/person_vehicle_yolo_train"
  14. val_dir_coco = "/media/jiang/AI_DataSets/DataSets/person_vehicle_coco/person_vehicle_yolo_val"
  15. label_dict = {"0": "person", "1": "car", "2": "motorbike", "3": "bus", "4": "truck"}

  16. output_dir_voc = "/media/jiang/AI_DataSets/DataSets/person_vehicle_voc"


  17. def writexml(img_path, ori_hw, bboxes, xmlpath):
  18.     doc = Document()
  19.     # 根节点
  20.     annotation = doc.createElement('annotation')
  21.     doc.appendChild(annotation)

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

  27.     filenamenode = doc.createElement('filename')
  28.     filename_name = doc.createTextNode(img_path)
  29.     filenamenode.appendChild(filename_name)
  30.     annotation.appendChild(filenamenode)

  31.     source = doc.createElement('source')
  32.     annotation.appendChild(source)

  33.     database = doc.createElement('database')
  34.     database.appendChild(doc.createTextNode('coco Database'))
  35.     source.appendChild(database)

  36.     annotation_s = doc.createElement('annotation')
  37.     annotation_s.appendChild(doc.createTextNode('jjj VOC2020'))
  38.     source.appendChild(annotation_s)

  39.     image = doc.createElement('image')
  40.     image.appendChild(doc.createTextNode('flickr'))
  41.     source.appendChild(image)

  42.     flickrid = doc.createElement('flickrid')
  43.     flickrid.appendChild(doc.createTextNode('-1'))
  44.     source.appendChild(flickrid)

  45.     owner = doc.createElement('owner')
  46.     annotation.appendChild(owner)

  47.     flickrid_o = doc.createElement('flickrid')
  48.     flickrid_o.appendChild(doc.createTextNode('jjj_88888'))
  49.     owner.appendChild(flickrid_o)

  50.     name_o = doc.createElement('name')
  51.     name_o.appendChild(doc.createTextNode('jjj_88888'))
  52.     owner.appendChild(name_o)

  53.     size = doc.createElement('size')
  54.     annotation.appendChild(size)

  55.     width = doc.createElement('width')
  56.     width.appendChild(doc.createTextNode(str(ori_hw[1])))
  57.     height = doc.createElement('height')
  58.     height.appendChild(doc.createTextNode(str(ori_hw[0])))
  59.     depth = doc.createElement('depth')
  60.     depth.appendChild(doc.createTextNode("3"))
  61.     size.appendChild(width)
  62.     size.appendChild(height)
  63.     size.appendChild(depth)

  64.     segmented = doc.createElement('segmented')
  65.     segmented.appendChild(doc.createTextNode('0'))
  66.     annotation.appendChild(segmented)

  67.     for i in range(len(bboxes)):
  68.         # bbox = ['person', 412, 157, 465, 295]
  69.         bbox = bboxes[i]
  70.         objects = doc.createElement('object')
  71.         annotation.appendChild(objects)

  72.         object_name = doc.createElement('name')
  73.         #
  74.         object_name.appendChild(doc.createTextNode(bbox[0]))
  75.         objects.appendChild(object_name)

  76.         pose = doc.createElement('pose')
  77.         pose.appendChild(doc.createTextNode('Unspecified'))
  78.         objects.appendChild(pose)

  79.         truncated = doc.createElement('truncated')
  80.         truncated.appendChild(doc.createTextNode('1'))
  81.         objects.appendChild(truncated)

  82.         difficult = doc.createElement('difficult')
  83.         difficult.appendChild(doc.createTextNode('0'))
  84.         objects.appendChild(difficult)

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

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


  103. def convert_imgset(img_set_type, dir_coco):
  104.     """
  105.     转换数据集(WiderFace---> VOC)
  106.     :param img_set_type: train or val
  107.     :return:
  108.     """
  109.     img_num = len(glob.glob(os.path.join(dir_coco, "*.jpg")))
  110.     txt_label_num = len(glob.glob(os.path.join(dir_coco, "*.txt")))
  111.     assert img_num == txt_label_num, "必须一致!"
  112.     print("数据集:{};图片数量={};标签txt文件数:{}".format(img_set_type, img_num, txt_label_num))
  113.     output_set_txt = os.path.join(output_dir_voc, "ImageSets", "Main", "%s.txt" % img_set_type)
  114.     output_set_txt_writer = open(output_set_txt, "w")

  115.     for img_path in glob.glob(os.path.join(dir_coco, "*.jpg")):
  116.         shutil.copy2(img_path, os.path.join(output_dir_voc, "JPEGImages"))
  117.         ori_h, ori_w = cv2.imread(img_path).shape[:2]
  118.         img_name = img_path.strip().split("/")[-1].split(".")[0]
  119.         txt_path = img_path.strip().replace("jpg", "txt")
  120.         print("图片的宽={},高={},name={}, txt_path={}".format(ori_w, ori_h, img_name, txt_path))
  121.         output_set_txt_writer.write("%s\n" % img_name)
  122.         # os.path.join(output_dir_voc, "Annotations")
  123.         # "%d %.6f %.6f %.6f %.6f\n" % (class_id, cx, cy, w, h)
  124.         bboxes = []
  125.         with open(txt_path, "r") as f:
  126.             lines = f.readlines()
  127.             for line in lines:
  128.                 class_id, cx, cy, w, h = line.strip().split(" ")
  129.                 x1 = float(cx) - float(w) / 2
  130.                 x2 = float(cx) + float(w) / 2
  131.                 y1 = float(cy) - float(h) / 2
  132.                 y2 = float(cy) + float(h) / 2
  133.                 x1_int = int(x1 * ori_w)
  134.                 y1_int = int(y1 * ori_h)
  135.                 x2_int = int(x2 * ori_w)
  136.                 y2_int = int(y2 * ori_h)
  137.                 bbox = [label_dict[class_id], x1_int, y1_int, x2_int, y2_int]
  138.                 bboxes.append(bbox)

  139.         if len(bboxes) == 0:
  140.             print('txt的标注文件 没有任何目标类')
  141.             continue
  142.         print("该图片={}的所有box标注:{}".format(img_name, bboxes))
  143.         annotation_xml_path = os.path.join(output_dir_voc, "Annotations", "%s.xml" % img_name)
  144.         writexml(img_path, (ori_h, ori_w), bboxes, annotation_xml_path)
  145.         # assert 0 == 1, "停"
  146.     output_set_txt_writer.close()


  147. if __name__ == '__main__':
  148.     # convert_imgset('val', val_dir_coco)
  149.     convert_imgset('train', train_dir_coco)


复制代码



  1. # -*- coding: utf-8 -*-
  2. from __future__ import division, print_function
  3. __author__ = u'江锦炬 微信:dfy_88888'
  4. __date__ = '2020/11/3 下午4:04'
  5. __product__ = 'PyCharm'
  6. __filename__ = 'dfy_voc_2_yolo_format'

  7. import cv2
  8. import os
  9. import shutil
  10. import glob
  11. # import xml.etree.ElementTree as ET
  12. from xml.dom.minidom import parse
  13. import numpy as np
  14. import time
  15. import math
  16. import logging as log
  17. import glob
  18. from PIL import ImageFont
  19. from PIL import Image
  20. from PIL import ImageDraw

  21. fontC = ImageFont.truetype("./Font/platech.ttf", 16, 0)

  22. # 打上boundingbox和标签
  23. def drawRectBox(image, rect, addText, color=(0, 0, 255)):
  24.     cv2.rectangle(image, (int(rect[0]), int(rect[1])), (int(rect[2]), int(rect[3])), color, 2,
  25.                   cv2.LINE_AA)
  26.     # 这个矩形是 文本的边框  高度=18 宽度=115  -1是填充?  红色底
  27.     cv2.rectangle(image, (int(rect[0] - 1), int(rect[1]) - 18), (int(rect[0] + 115), int(rect[1])), color, -1,
  28.                   cv2.LINE_AA)

  29.     img = Image.fromarray(image)
  30.     draw = ImageDraw.Draw(img)
  31.     # draw.text((int(rect[0]+1), int(rect[1]-16)), addText.decode("utf-8"), (255, 255, 255), font=fontC)
  32.     # 字体颜色是白色
  33.     draw.text((int(rect[0] + 1), int(rect[1] - 16)), addText, (255, 255, 255), font=fontC)
  34.     imagex = np.array(img)

  35.     return imagex


  36. voc_imgs_dir = "/media/jiang/AI_DataSets/DataSets/person_vehicle_voc/JPEGImages"

  37. voc_annotations = "/media/jiang/AI_DataSets/DataSets/person_vehicle_voc/Annotations"


  38. output_dir = "/media/jiang/AI_DataSets/DataSets/person_vehicle_voc/temp"
  39. # 需要一张一张的检查啊
  40. # yolo 格式: .jpg  .txt  train.txt  val.txt
  41. label_dict = {"0": "person", "1": "car", "2": "motorbike", "3": "bus", "4": "truck"}

  42. total_img_num = len(glob.glob(os.path.join(voc_imgs_dir, "*.jpg")))
  43. print("共有多少张jpg图片:", total_img_num)
  44. total_xml_anno_num = len(glob.glob(os.path.join(voc_annotations, "*.xml")))
  45. print("共有多少个xml的标注:", total_xml_anno_num)

  46. assert total_img_num == total_xml_anno_num, "图片和xml标注数量必须一致!"
  47. # 共有多少张jpg图片: 2059
  48. # 共有多少个xml的标注: 2059

  49. for idx, img_path in enumerate(glob.glob(os.path.join(voc_imgs_dir, "*.jpg"))):
  50.     ori_img = cv2.imread(img_path)
  51.     ori_h, ori_w = ori_img.shape[:2]
  52.     ori_img_name = img_path.strip().split("/")[-1].split(".")[0]
  53.     # print("图片链接:", img_path, ori_img_name)
  54.     xml_annotation_path = os.path.join(voc_annotations, "%s.xml" % ori_img_name)
  55.     if not os.path.isfile(xml_annotation_path):
  56.         print("找不到xml标注啊:", xml_annotation_path)
  57.         continue
  58.     else:
  59.         pass
  60.         # print("找到了xml标注:", xml_annotation_path)
  61.     # 读取文件
  62.     # xml_annotation_path = "*.xml"  from xml.dom.minidom import parse
  63.     dom = parse(xml_annotation_path)
  64.     # 获取文档元素对象
  65.     data = dom.documentElement
  66.     objs = data.getElementsByTagName('object')
  67.     shutil.copy2(img_path, output_dir)
  68.     new_text_file_writer = open(os.path.join(output_dir, "%s.txt" % ori_img_name), "w")
  69.     # 0 0.622266 0.552778 0.289844 0.483333  fire
  70.     # # <x_center> <y_center> <width> <height>
  71.     for obj in objs:
  72.         # 获取标签中内容
  73.         name = obj.getElementsByTagName('name')[0].childNodes[0].nodeValue
  74.         x1 = obj.getElementsByTagName('bndbox')[0].getElementsByTagName('xmin')[0].childNodes[0].nodeValue
  75.         y1 = obj.getElementsByTagName('bndbox')[0].getElementsByTagName('ymin')[0].childNodes[0].nodeValue
  76.         x2 = obj.getElementsByTagName('bndbox')[0].getElementsByTagName('xmax')[0].childNodes[0].nodeValue
  77.         y2 = obj.getElementsByTagName('bndbox')[0].getElementsByTagName('ymax')[0].childNodes[0].nodeValue
  78.         # print('name:', name, ', box:[{},{},{},{}]'.format(x1, y1, x2, y2))
  79.         rect_box = [int(x1), int(y1), int(x2), int(y2)]

  80.         # ori_img = drawRectBox(ori_img, rect_fire_smoke, name, color=(0, 0, 255))
  81.         box_width = max(0, (int(x2) - int(x1)) * 1.0 / ori_w)
  82.         box_height = max(0, (int(y2) - int(y1)) * 1.0 / ori_h)
  83.         box_cx = max(0, (int(x2) + int(x1)) / (ori_w * 2.0))
  84.         box_cy = max(0, (int(y2) + int(y1)) / (ori_h * 2.0))

  85.         if label_dict["0"] == name:
  86.             new_text_file_writer.write("0 %.6f %.6f %.6f %.6f\n" % (box_cx, box_cy, box_width, box_height))
  87.         elif label_dict["1"] == name:
  88.             new_text_file_writer.write("1 %.6f %.6f %.6f %.6f\n" % (box_cx, box_cy, box_width, box_height))
  89.         elif label_dict["2"] == name:
  90.             new_text_file_writer.write("2 %.6f %.6f %.6f %.6f\n" % (box_cx, box_cy, box_width, box_height))
  91.         elif label_dict["3"] == name:
  92.             new_text_file_writer.write("3 %.6f %.6f %.6f %.6f\n" % (box_cx, box_cy, box_width, box_height))
  93.         elif label_dict["4"] == name:
  94.             new_text_file_writer.write("4 %.6f %.6f %.6f %.6f\n" % (box_cx, box_cy, box_width, box_height))

  95.     new_text_file_writer.close()

  96.     # cv2.imshow("ori", ori_img)
  97.     # cv2.waitKey(0)
  98.     # if idx == 9:
  99.     #     assert 0 == 1, "停"




复制代码



  1. # -*- coding: utf-8 -*-
  2. __author__ = u'江锦炬 微信:dfy_88888'
  3. __date__ = '2020/11/3 下午2:52'
  4. __product__ = 'PyCharm'
  5. __filename__ = 'dfy_demo01'

  6. import cv2
  7. import os
  8. import glob

  9. import cv2
  10. import os
  11. import shutil
  12. # import xml.etree.ElementTree as ET
  13. from xml.dom.minidom import parse
  14. import numpy as np
  15. import time
  16. import math
  17. import logging as log
  18. import glob
  19. from PIL import ImageFont
  20. from PIL import Image
  21. from PIL import ImageDraw

  22. fontC = ImageFont.truetype("./Font/platech.ttf", 16, 0)

  23. # 打上boundingbox和标签
  24. def drawRectBox(image, rect, addText, color=(0, 0, 255)):
  25.     cv2.rectangle(image, (int(rect[0]), int(rect[1])), (int(rect[2]), int(rect[3])), color, 2,
  26.                   cv2.LINE_AA)
  27.     # 这个矩形是 文本的边框  高度=18 宽度=115  -1是填充?  红色底
  28.     cv2.rectangle(image, (int(rect[0] - 1), int(rect[1]) - 18), (int(rect[0] + 115), int(rect[1])), color, -1,
  29.                   cv2.LINE_AA)

  30.     img = Image.fromarray(image)
  31.     draw = ImageDraw.Draw(img)
  32.     # draw.text((int(rect[0]+1), int(rect[1]-16)), addText.decode("utf-8"), (255, 255, 255), font=fontC)
  33.     # 字体颜色是白色
  34.     draw.text((int(rect[0] + 1), int(rect[1] - 16)), addText, (255, 255, 255), font=fontC)
  35.     imagex = np.array(img)

  36.     return imagex


  37. # 验证一下 yolo格式的标注数据  数据来源:yolo-mark标注的 或 其他格式转换过来的  *.jpg  *.txt
  38. input_imgs_dir = "/media/jiang/AI_DataSets/DataSets/person_vehicle_voc/temp"

  39. # label_dict = {"0": "fire", "1": "smoke"}
  40. label_dict = {"0": "person", "1": "car", "2": "motorbike", "3": "bus", "4": "truck"}
  41. img_num = len(glob.glob(os.path.join(input_imgs_dir, "*.jpg")))
  42. txt_num = len(glob.glob(os.path.join(input_imgs_dir, "*.txt")))
  43. assert img_num == txt_num, "图片和标注文件个数必须一致!"

  44. for idx, img_path in enumerate(glob.glob(os.path.join(input_imgs_dir, "*.jpg"))):
  45.     ori_img = cv2.imread(img_path)
  46.     ori_h, ori_w = ori_img.shape[:2]
  47.     txt_file_path = img_path.strip().split(".")[0] + ".txt"
  48.     ori_img_name = img_path.strip().split("/")[-1].split(".")[0]
  49.     with open(txt_file_path, "r") as f:
  50.         lines = f.readlines()
  51.         for line in lines:
  52.             class_id, cx, cy, w, h = line.strip().split()
  53.             cx = float(cx) * ori_w
  54.             cy = float(cy) * ori_h
  55.             w = float(w) * ori_w
  56.             h = float(h) * ori_h

  57.             x1 = int(cx - w / 2)
  58.             y1 = int(cy - h / 2)
  59.             x2 = int(cx + w / 2)
  60.             y2 = int(cy + h / 2)
  61.             rect_fire_smoke = [x1, y1, x2, y2]
  62.             ori_img = drawRectBox(ori_img, rect_fire_smoke, label_dict[class_id], color=(0, 0, 255))
  63.             # cv2.rectangle(ori_img, (x1, y1), (x2, y2), (0, 0, 255), thickness=2)
  64.     print("当前正在查看的图片:", ori_img_name)
  65.     cv2.imshow("ori", ori_img)
  66.     cv2.waitKey(0)

  67.     if idx == 300:
  68.         assert 0 == 1, "停"

复制代码










作者: leironh    时间: 2020-12-5 21:25
感谢分享
作者: leironh    时间: 2020-12-5 21:26
干货满满
作者: leironh    时间: 2020-12-5 23:40
566666666666666666666
作者: leironh    时间: 2020-12-6 09:15
Python高级编程与AI数据分析课程
作者: leironh    时间: 2020-12-6 09:18
Python高级编程与AI数据分析课程
作者: leironh    时间: 2020-12-6 09:19
Python高级编程与AI数据分析课程
作者: leironh    时间: 2020-12-6 09:20
Python高级编程与AI数据分析课程
作者: leironh    时间: 2020-12-6 09:25

笔记写的挺好的,点个赞
作者: leironh    时间: 2020-12-6 09:29

笔记写的挺好的,点个赞
作者: leironh    时间: 2020-12-6 09:36
目标检测之coco与voc格式的数据相互转换,并验证coco格式的脚本目标检测之coco与voc格式的数据相互转换,并验证coco格式的脚本
作者: 小别离    时间: 2021-1-12 16:47
感觉编码的好牛厉害
作者: 小别离    时间: 2021-1-12 16:47
我一个学材料的生生的要去学计算机
作者: 小别离    时间: 2021-1-12 16:48
还是得从python基础来学啊,好多东西看不懂呢
作者: 小别离    时间: 2021-1-12 16:48
kuaile 666666666666666666666666666666666666666666
作者: 小别离    时间: 2021-1-12 16:49
快晋级到总计会员了
作者: 小别离    时间: 2021-1-12 16:49
材料为什么要和机器学习联系到一起呢
作者: 小别离    时间: 2021-1-12 16:49
我都不知道我在学什么
作者: 小别离    时间: 2021-1-12 16:50
虽然可以直接调包使用,但是有很多代码看不懂呢
作者: 小别离    时间: 2021-1-12 16:50
慢慢来吧。噶虐这个年有得忙了
作者: 小别离    时间: 2021-1-12 16:51
换一个主题吧




欢迎光临 东方耀AI技术分享 (http://www.ai111.vip/) Powered by Discuz! X3.4