voc旋转标注数据转dota类型

  • voc2dota.py
  • ListFilesToTxt.py
  • roxml_to_dota.py

在cv领域数据集的标注过程中,用labelImg工具我们可以对数据进行标注,标注生成的voc类型的xml框一般是如下格式:(bndbox)(x1,y1,x2,y2)

但是在标注的过程中,往往会遇到使用水平的矩形框无法完整地框出类别的特征的情况,这会导致无用特征的冗余。
在dota类型的标注中,就能解决这个问题:
我们可以定义三个类型的bbox:HBB,OBB,POLY

HBB由左上点和右下点表示。 HBB 的最后一个维度应该是 4。
OBB由中心点(x, y)、宽度(w)、高度(h) 和θ 表示。宽度是较长边的长度。高度是较短边的长度。Theta 是长边和 x 轴之间的角度。 OBB 的最后一个维度应该是 5。
POLY由四点坐标表示。这些点的顺序无关紧要,但相邻的点应该是POLY的一侧。 POLY的最后一个维度应该是8

很明显,普通的xml标注文件属于HBB类型。而在旋转目标检测中,我们如果用到labelImg2来标注旋转的矩形框:

以及他生成的xml标注文件:

很明显,格式产生了变化
(robndbox)(cx,cy,w,h)

为了统一使用,我们可以将两种格式的框统一转成dota格式的txt文件(也就是poly格式)

他的格式一般是这样:

————数字分别对应从左上角开始顺时针旋转的四个点坐标

接下来直接附上voc转dota的代码,适用于xml混合bndbox和robndbox的情况

voc2dota.py

import math
import shutil
import os
import numpy as np
import xml.etree.ElementTree as ETdataset_dir = r'/home/xiaopeng/dataset/test_oriented/1/img'
ana_dir = r'/home/xiaopeng/dataset/test_oriented/1/xml'
save_dir = r'/home/xiaopeng/dataset/test_oriented/1/dota_txt'
train_img_dir = r'/home/xiaopeng/dataset/test_oriented/1/imgSets/test.txt' #txt文件保存的是所有文件的名称f1 = open(train_img_dir, 'r')
train_img = f1.readlines()def rotatePoint(xc, yc, xp, yp, theta):xoff = xp - xc;yoff = yp - yc;cosTheta = math.cos(theta)sinTheta = math.sin(theta)pResx = cosTheta * xoff + sinTheta * yoffpResy = - sinTheta * xoff + cosTheta * yoffreturn str(int(xc + pResx)), str(int(yc + pResy))def rota(x, y, w, h, a):  # 旋转中心点,旋转中心点,框的w,h,旋转角x0, y0 = rotatePoint(x, y, x - w / 2, y - h / 2, -a)x1, y1 = rotatePoint(x, y, x + w / 2, y - h / 2, -a)x2, y2 = rotatePoint(x, y, x + w / 2, y + h / 2, -a)x3, y3 = rotatePoint(x, y, x - w / 2, y + h / 2, -a)return x0, y0, x1, y1, x2, y2, x3, y3  # 旋转后的四个点,左上,右上,右下,左下for img in train_img:shutil.copy(os.path.join(dataset_dir, img[:-1] + '.jpg'),os.path.join(save_dir,  'images', img[:-1] + '.jpg'))xml_file = open(os.path.join(ana_dir, img[:-1] + '.xml'), encoding='utf-8')tree = ET.parse(xml_file)root = tree.getroot()with open(os.path.join(save_dir,  'labelTxt', img[:-1] + '.txt'), 'w') as f:for obj in root.iter('object'):cls = obj.find('name').textbox = obj.find('robndbox')# print(box)if(box!=None): #xml for labelImg2x_c = float(box.find('cx').text)y_c = float(box.find('cy').text)h = float(box.find('h').text)w = float(box.find('w').text)theta = float(box.find('angle').text)bdx = rota(x_c, y_c, w, h, theta)# print(bdx)x1=bdx[0]y1=bdx[1]x2=bdx[2]y2=bdx[3]x3=bdx[4]y3=bdx[5]x4=bdx[6]y4=bdx[7]f.write("{} {} {} {} {} {} {} {} {} 0\n".format(str(x1), str(y1), str(x2), str(y2), str(x3), str(y3), str(x4), str(y4), cls))else:#xml for labelImgbox1=obj.find('bndbox')xmin = int(box1[0].text)ymin = int(box1[1].text)xmax = int(box1[2].text)ymax = int(box1[3].text)f.write("{} {} {} {} {} {} {} {} {} 0\n".format(xmin,ymax,xmax,ymax,xmax,ymin,xmin,ymin,cls))

生成目录下所有文件名的txt文件代码:

ListFilesToTxt.py

def ListFilesToTxt(dir, file, wildcard, recursion):exts = wildcard.split(" ")for root, subdirs, files in os.walk(dir):for name in files:# name1=name.split(".")[0]for ext in exts:if (name.endswith(ext)):file.write(name.split('.')[0] + "\n")breakif (not recursion):breakdef Test():dir = "/home/xiaopeng/dataset/test_oriented/1/split_class/Rough yarn/img"outfile = "/home/xiaopeng/dataset/test_oriented/1/split_class/Rough yarn/test.txt"wildcard = ".txt .exe .dll .lib .jpg"file = open(outfile, "w")if not file:print("cannot open the file %s for writing" % outfile)ListFilesToTxt(dir, file, wildcard, 0)file.close()if __name__ == '__main__':Test()

***———————————***2022.6.30更新
之前的voc转dota代码我自己用了之后觉得不好用,对于旋转角度比较小的情况,旋转框往往转换不出来。
在借鉴别人脚本的基础上,进行了改进,分享给大家。只需要下面一个脚本便可实现xml格式转dota格式:

roxml_to_dota.py

# 文件名称   :roxml_to_dota.py
# 功能描述   :把rolabelimg标注的xml文件转换成dota能识别的xml文件,
#             再转换成dota格式的txt文件
#            把旋转框 cx,cy,w,h,angle,转换成四点坐标x1,y1,x2,y2,x3,y3,x4,y4
import os
import xml.etree.ElementTree as ET
import mathdef edit_xml(xml_file):"""修改xml文件:param xml_file:xml文件的路径:return:"""tree = ET.parse(xml_file)objs = tree.findall('object')for ix, obj in enumerate(objs):x0 = ET.Element("x0")  # 创建节点y0 = ET.Element("y0")x1 = ET.Element("x1")y1 = ET.Element("y1")x2 = ET.Element("x2")y2 = ET.Element("y2")x3 = ET.Element("x3")y3 = ET.Element("y3")# obj_type = obj.find('bndbox')# type = obj_type.text# print(xml_file)if (obj.find('robndbox') == None):obj_bnd = obj.find('bndbox')obj_xmin = obj_bnd.find('xmin')obj_ymin = obj_bnd.find('ymin')obj_xmax = obj_bnd.find('xmax')obj_ymax = obj_bnd.find('ymax')xmin = float(obj_xmin.text)ymin = float(obj_ymin.text)xmax = float(obj_xmax.text)ymax = float(obj_ymax.text)obj_bnd.remove(obj_xmin)  # 删除节点obj_bnd.remove(obj_ymin)obj_bnd.remove(obj_xmax)obj_bnd.remove(obj_ymax)x0.text = str(xmin)y0.text = str(ymax)x1.text = str(xmax)y1.text = str(ymax)x2.text = str(xmax)y2.text = str(ymin)x3.text = str(xmin)y3.text = str(ymin)else:obj_bnd = obj.find('robndbox')obj_bnd.tag = 'bndbox'  # 修改节点名obj_cx = obj_bnd.find('cx')obj_cy = obj_bnd.find('cy')obj_w = obj_bnd.find('w')obj_h = obj_bnd.find('h')obj_angle = obj_bnd.find('angle')cx = float(obj_cx.text)cy = float(obj_cy.text)w = float(obj_w.text)h = float(obj_h.text)angle = float(obj_angle.text)obj_bnd.remove(obj_cx)  # 删除节点obj_bnd.remove(obj_cy)obj_bnd.remove(obj_w)obj_bnd.remove(obj_h)obj_bnd.remove(obj_angle)x0.text, y0.text = rotatePoint(cx, cy, cx - w / 2, cy - h / 2, -angle)x1.text, y1.text = rotatePoint(cx, cy, cx + w / 2, cy - h / 2, -angle)x2.text, y2.text = rotatePoint(cx, cy, cx + w / 2, cy + h / 2, -angle)x3.text, y3.text = rotatePoint(cx, cy, cx - w / 2, cy + h / 2, -angle)# obj.remove(obj_type)  # 删除节点obj_bnd.append(x0)  # 新增节点obj_bnd.append(y0)obj_bnd.append(x1)obj_bnd.append(y1)obj_bnd.append(x2)obj_bnd.append(y2)obj_bnd.append(x3)obj_bnd.append(y3)tree.write(xml_file, method='xml', encoding='utf-8')  # 更新xml文件# 转换成四点坐标
def rotatePoint(xc, yc, xp, yp, theta):xoff = xp - xc;yoff = yp - yc;cosTheta = math.cos(theta)sinTheta = math.sin(theta)pResx = cosTheta * xoff + sinTheta * yoffpResy = - sinTheta * xoff + cosTheta * yoffreturn str(int(xc + pResx)), str(int(yc + pResy))def totxt():xml_path = '/home/xiaopeng/dataset/test_oriented/3/split/for-try (copy)'out_path = '/home/xiaopeng/dataset/test_oriented/3/split/try_txt/'# 想要生成的txt文件保存的路径,这里可以自己修改files = os.listdir(xml_path)for file in files:tree = ET.parse(xml_path + os.sep + file)root = tree.getroot()name = file.strip('.xml')output = out_path + name + '.txt'file = open(output, 'w')objs = tree.findall('object')for obj in objs:cls = obj.find('name').textbox = obj.find('bndbox')x0 = int(float(box.find('x0').text))y0 = int(float(box.find('y0').text))x1 = int(float(box.find('x1').text))y1 = int(float(box.find('y1').text))x2 = int(float(box.find('x2').text))y2 = int(float(box.find('y2').text))x3 = int(float(box.find('x3').text))y3 = int(float(box.find('y3').text))file.write("{} {} {} {} {} {} {} {} {} 0\n".format(x0, y0, x1, y1, x2, y2, x3, y3, cls))file.close()print(output)if __name__ == '__main__':# -----**** 第一步:把xml文件统一转换成旋转框的xml文件 ****-----dir = "/home/xiaopeng/dataset/test_oriented/3/split/for-try (copy)"  # 目录下保存的是需要转换的xml文件filelist = os.listdir(dir)for file in filelist:edit_xml(os.path.join(dir, file))# -----**** 第二步:把旋转框xml文件转换成txt格式 ****-----totxt()

voc旋转标注数据转dota类型相关推荐

  1. 旋转标注框数据标签制作-roLabelImg

    一.roLabelImg简介 roLabelImg是基于labelImg改进的,也是用来标注为VOC格式的数据,但是在labelImg的基础上增加了能够使标注的框进行旋转的功能. 网址:https:/ ...

  2. 【AI目标检测】VOC格式数据集转换为DOTA类型数据集

    由于目前的imglabel画出来框都是voc类型的xml文件: <annotation><folder>rotate_jueyuanzi_zip</folder>& ...

  3. 无需标注数据,利用辅助性旋转损失的自监督GANs,效果堪比现有最好方法

    作者 | Ting Chen 译者 | 王红成 出品 | AI科技大本营(ID:rgznai100) 本文作者提出了一种自检督方式的生成对抗网络,通过辅助性的旋转损失来达到目的.因为通常主流方法来生成 ...

  4. 人工智能数据标注都有哪些类型

    人工智能数据标注都有哪些类型 人工智能数据标注指的是,将非结构化数据转换成电脑可以识别理解的结构化数据. 例如,将下图中的车识别出来,人看到车的外轮廓是: 但是需要让电脑去识别认知这个图中的车,电脑需 ...

  5. python实现目标检测voc格式标签数据增强

    文章目录 前言 一.显示图片(可关闭) 二.创建图像变换的类 1.增强数据代码 2.图像加噪声 3.调整图像亮度 4.添加黑色像素块 5.旋转图像 6.图像裁剪 7.平移图像 8.图像镜像 9.图像随 ...

  6. 预、自训练之争:谷歌说预训练虽火,但在标注数据上自训练更有效

    公众号关注 "视学算法" 设为 "星标",重磅干货,第一时间送达! 来源 | 机器之心 预训练是当前计算机视觉领域的主要范式,但何恺明等人先前的研究发现,预训练 ...

  7. 史上最强GAN被谷歌超越!标注数据少用90%,造假效果却更逼真

    当前生成图像最逼真的BigGAN被超越了! 出手的,是谷歌大脑和苏黎世联邦理工学院.他们提出了新一代GAN:S³GAN. 它们生成的照片,都是真假难辨. 下面这两只蝴蝶,哪只更生动? 两张风景照片,哪 ...

  8. 分割 标注数据_7种常用的数据标注工具

    工欲善其事,必先利其器. 标注工具是数据标注行业的基础,一款好用的标注工具是提升标注效率与产出高质量标注数据的关键. 常用的数据标注工具主要有以下几种:2D框.语义分割.多边形分割.点标注.线标注.视 ...

  9. python 将YOLO(txt)格式的标注数据批量转换为PascalVOC(XML)格式的标注数据

    python 将YOLO(txt)格式的标注数据批量转换为PascalVOC(XML)格式的标注数据 准备工作 修改代码路径 运行代码 程序bug(没时间看所以还没解决): 准备工作 需在目标文件夹中 ...

  10. python 将PascalVOC(XML)格式的标注数据批量转换为YOLO(txt)格式的标注数据

    文章目录 20191022 20200523 第一次使用,修改了代码内容 使用方法 修改过的代码 20191022 引用文章:啊哈~发表第一篇博客,voc格式的标注数据转换为yolo格式的标注数据 i ...

最新文章

  1. python使用openCV把原始彩色图像转化为灰度图、使用矩阵索引的方式对数据数据进行剪裁(image cropping)
  2. 重温C# clr 笔记总结
  3. OpenGL上下文共享示例
  4. Oracle Sql 胡乱记
  5. [开发笔记]-判断当前是否联网
  6. 和表头对齐 表格_29 HTML中表格的其他特性
  7. MongoDB学习笔记一:MongoDB的下载和安装
  8. 双联通分量求简单环(Educational Codeforces Round 42: F. Simple Cycles Edges)
  9. C++编程语言中的值传递(pass-by-value)和引用传递(pass-by-reference)介绍
  10. ENVI:There are no available ROls or EVFs associated with this input file.
  11. linux怎么进入windows系统安装目录下,windows下Linux子系统的安装配置
  12. 中职一年级计算机学情分析,一年级学情分析.doc
  13. 虚拟机安装或卸载时,无法打开注册表项问题
  14. 从无序到有序的负熵力量
  15. 基于SQLite的信息管理系统
  16. Line 1 in XML document from URL [file:/D:/tomcat/apache-tomcat-9.0.10/lib/] is invalid;
  17. 更改文字颜色为红色HTMl语言,红色字体CSS_设置html字体颜色为红色
  18. 【强化学习与机器人控制论文 2】基于强化学习的五指灵巧手操作
  19. 优秀的加密方案-软件加密技巧
  20. Win10新特性介绍

热门文章

  1. 实验七 Matlab GUI设计
  2. web前端入门知识大全:系统路线,各类要点解析
  3. JS实现抽奖活动程序
  4. python,用pycharm写的评分系统
  5. 连续自然数之和 C++
  6. 企查查爬虫python实现(一)整体方法
  7. 【收藏】2018-2019届互联网大厂公司校招薪资汇总,基本年薪都在20万以上
  8. flask学习笔记代码篇-10
  9. 树莓派搭建LAMP和FTP服务器
  10. Android键盘输入法(一)——键盘类型