# *_* coding : UTF-8 *_*
# 文件名称 :roxml_to_dota.py
# 功能描述 :把rolabelimg标注的xml文件转换成dota能识别的xml文件
# 就是把旋转框 cx,cy,w,h,angle,转换成四点坐标x1,y1,x2,y2,x3,y3,x4,y4
import os
import xml.etree.ElementTree as ET
import math
import cv2
import numpy as np
def edit_xml(xml_file):
if ".xml" not in xml_file:
return
tree = ET.parse(xml_file)
objs = tree.findall('object')
txt = xml_file.replace(".xml", ".txt")
jpg = xml_file.replace(".xml", ".jpg") #图片是jpg格式
src = cv2.imread(jpg, 1)
with open(txt, 'w') as wf:
wf.write("imagesource:GoogleEarth\n")
wf.write("gsd:0.115726939386\n")
for ix, obj in enumerate(objs):
x0text = ""
y0text = ""
x1text = ""
y1text = ""
x2text = ""
y2text = ""
x3text = ""
y3text = ""
difficulttext = ""
className = ""
obj_type = obj.find('type')
type = obj_type.text
obj_name = obj.find('name')
className = obj_name.text
obj_difficult = obj.find('difficult')
difficulttext = obj_difficult.text
if type == 'bndbox': #若用rolabelimg标注的是水平框
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)
x0text = str(xmin)
y0text = str(ymin)
x1text = str(xmax)
y1text = str(ymin)
x2text = str(xmin)
y2text = str(ymax)
x3text = str(xmax)
y3text = str(ymax)
points = np.array([[int(float(x0text)), int(float(y0text))], [int(float(x1text)), int(float(y1text))], [int(float(x2text)), int(float(y2text))],
[int(float(x3text)), int(float(y3text))]], np.int32)
cv2.polylines(src, [points], True, (255, 0, 0)) # 画任意多边
elif type == 'robndbox': #若用rolabelimg标注的是旋转框
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)
x0text, y0text = rotatePoint(cx, cy, cx - w / 2, cy - h / 2, -angle)
x1text, y1text = rotatePoint(cx, cy, cx + w / 2, cy - h / 2, -angle)
x2text, y2text = rotatePoint(cx, cy, cx + w / 2, cy + h / 2, -angle)
x3text, y3text = rotatePoint(cx, cy, cx - w / 2, cy + h / 2, -angle)
points = np.array([[int(float(x0text)), int(float(y0text))], [int(float(x1text)), int(float(y1text))], [int(float(x2text)), int(float(y2text))],
[int(float(x3text)), int(float(y3text))]], np.int32)
cv2.polylines(src, [points], True, (255, 0, 0)) # 画任意多边形
# print(x0text,y0text,x1text,y1text,x2text,y2text,x3text,y3text,className,difficulttext)
wf.write(
"{} {} {} {} {} {} {} {} {} {}\n".format(x0text, y0text, x1text, y1text, x2text, y2text, x3text, y3text,
className, difficulttext))
# 转换成四点坐标
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 * yoff
pResy = - sinTheta * xoff + cosTheta * yoff
return str(int(xc + pResx)), str(int(yc + pResy))
if __name__ == '__main__':
dir = "D:/soft/Pycharm/pythonProjectss/updatepicturesname/xml1130" #此处的xml1130文件夹中必须既要放jpg图片集又要放图片对应的xml文件不然会报打不开文件的错误!!
filelist = os.listdir(dir)
for file in filelist:
edit_xml(os.path.join(dir, file))
中途报错:ValueError: invalid literal for int() with base 10问题处理
解决::把points=......那行代码先将字符串转换为浮点数float
,再将浮点数转化为整数int。
示例
:a=int(float(123.456))
最终的txt文件内容如下:
#功能描述:从指定文件夹中根据文件名后缀提取相应文件以txt文件为例,并存储到新文件夹中
import os
import shutil
'''
参数描述:
file_dir指读的文件目录;save_dir为保存文件的目录
suffix用于存放打算提取的文件的后缀名;
'''
def filterfile(file_dir,save_dir,suffix):
if os.path.exists(save_dir):
shutil.rmtree(save_dir) #如果已经存在该文件夹,移除
if not os.path.exists(save_dir):
os.makedirs(save_dir) #如果不存在该文件夹,则创建,用于储存后续提取出来的文件
filelist = [] #存储要copy的文件全名
for dirpath,dirnames,filenames in os.walk(file_dir):#根据路径执行树状的遍历,分别遍历根目录,根目录下的文件夹,文件夹下的文件
for file in filenames:#遍历文件夹中的文件
file_type = file.split('.')[-1]#对文件名根据.进行分隔,实现文件名,后缀名的分离
if(file_type in suffix):#下面根据后缀名是否在列表中,提取文件
file_fullname = os.path.join(dirpath, file) #文件全名
filelist.append(file_fullname)#将符合要求的文件存放在列表中
for file in filelist:
shutil.copy(file, save_dir)#将列表中的文件复制到新的文件夹
if __name__ == "__main__":
filterfile("xml1130","txtfiles",['txt'])