1、rolableimg标注旋转框的xml文件转dota格式的txt文件;2、如何批量从指定文件夹中根据后缀名提取文件,并存到新文件夹中

# *_* 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'])

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一鹿向晗99

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值