dota数据集转换为YOLO格式的方法

2023-10-31

  1. 下载好dota数据集
  2. 运行下面代码
    dota_utils.py
import sys
import codecs
import numpy as np
import shapely.geometry as shgeo
import os
import re
import math
"""
    some basic functions which are useful for process DOTA data
"""

wordname_18 = [
  'airport',
  'small-vehicle',
  'large-vehicle',
  'plane',
  'storage-tank',
  'ship',
  'harbor',
  'ground-track-field',
  'soccer-ball-field',
  'tennis-court',
  'swimming-pool',
  'baseball-diamond',
  'roundabout',
  'basketball-court',
  'bridge',
  'helicopter',
  'container-crane',
  'helipad']


def custombasename(fullname):
    return os.path.basename(os.path.splitext(fullname)[0])

def GetFileFromThisRootDir(dir,ext = None):
  allfiles = []
  needExtFilter = (ext != None)
  for root,dirs,files in os.walk(dir):
    for filespath in files:
      filepath = os.path.join(root, filespath)
      extension = os.path.splitext(filepath)[1][1:]
      if needExtFilter and extension in ext:
        allfiles.append(filepath)
      elif not needExtFilter:
        allfiles.append(filepath)
  return allfiles

def TuplePoly2Poly(poly):
    outpoly = [poly[0][0], poly[0][1],
                       poly[1][0], poly[1][1],
                       poly[2][0], poly[2][1],
                       poly[3][0], poly[3][1]
                       ]
    return outpoly

def parse_dota_poly(filename):
    """
        parse the dota ground truth in the format:
        [(x1, y1), (x2, y2), (x3, y3), (x4, y4)]
    """
    objects = []
    #print('filename:', filename)
    f = []
    if (sys.version_info >= (3, 5)):
        fd = open(filename, 'r')
        f = fd
    elif (sys.version_info >= 2.7):
        fd = codecs.open(filename, 'r')
        f = fd
    # count = 0
    while True:
        line = f.readline()
        # count = count + 1
        # if count < 2:
        #     continue
        if line:
            splitlines = line.strip().split(' ')
            object_struct = {}
            ### clear the wrong name after check all the data
            #if (len(splitlines) >= 9) and (splitlines[8] in classname):
            if (len(splitlines) < 9):
                continue
            if (len(splitlines) >= 9):
                    object_struct['name'] = splitlines[8]
            if (len(splitlines) == 9):
                object_struct['difficult'] = '0'
            elif (len(splitlines) >= 10):
                # if splitlines[9] == '1':
                # if (splitlines[9] == 'tr'):
                #     object_struct['difficult'] = '1'
                # else:
                object_struct['difficult'] = splitlines[9]
                # else:
                #     object_struct['difficult'] = 0
            object_struct['poly'] = [(float(splitlines[0]), float(splitlines[1])),
                                     (float(splitlines[2]), float(splitlines[3])),
                                     (float(splitlines[4]), float(splitlines[5])),
                                     (float(splitlines[6]), float(splitlines[7]))
                                     ]
            gtpoly = shgeo.Polygon(object_struct['poly'])
            object_struct['area'] = gtpoly.area
            # poly = list(map(lambda x:np.array(x), object_struct['poly']))
            # object_struct['long-axis'] = max(distance(poly[0], poly[1]), distance(poly[1], poly[2]))
            # object_struct['short-axis'] = min(distance(poly[0], poly[1]), distance(poly[1], poly[2]))
            # if (object_struct['long-axis'] < 15):
            #     object_struct['difficult'] = '1'
            #     global small_count
            #     small_count = small_count + 1
            objects.append(object_struct)
        else:
            break
    return objects

def dots4ToRecC(poly, img_w, img_h):
    xmin, ymin, xmax, ymax = dots4ToRec4(poly)
    x = (xmin + xmax)/2
    y = (ymin + ymax)/2
    w = xmax - xmin
    h = ymax - ymin
    return x/img_w, y/img_h, w/img_w, h/img_h

def parse_dota_poly2(filename):
    """
        parse the dota ground truth in the format:
        [x1, y1, x2, y2, x3, y3, x4, y4]
    """
    objects = parse_dota_poly(filename)
    for obj in objects:
        obj['poly'] = TuplePoly2Poly(obj['poly'])
        obj['poly'] = list(map(int, obj['poly']))
    return objects

def parse_dota_rec(filename):
    """
        parse the dota ground truth in the bounding box format:
        "xmin, ymin, xmax, ymax"
    """
    objects = parse_dota_poly(filename)
    for obj in objects:
        poly = obj['poly']
        bbox = dots4ToRec4(poly)
        obj['bndbox'] = bbox
    return objects
## bounding box transfer for varies format

def dots4ToRec4(poly):
    xmin, xmax, ymin, ymax = min(poly[0][0], min(poly[1][0], min(poly[2][0], poly[3][0]))), \
                            max(poly[0][0], max(poly[1][0], max(poly[2][0], poly[3][0]))), \
                             min(poly[0][1], min(poly[1][1], min(poly[2][1], poly[3][1]))), \
                             max(poly[0][1], max(poly[1][1], max(poly[2][1], poly[3][1])))
    return xmin, ymin, xmax, ymax
def dots4ToRec8(poly):
    xmin, ymin, xmax, ymax = dots4ToRec4(poly)
    return xmin, ymin, xmax, ymin, xmax, ymax, xmin, ymax
    #return dots2ToRec8(dots4ToRec4(poly))
def dots2ToRec8(rec):
    xmin, ymin, xmax, ymax = rec[0], rec[1], rec[2], rec[3]
    return xmin, ymin, xmax, ymin, xmax, ymax, xmin, ymax

def groundtruth2Task1(srcpath, dstpath):
    filelist = GetFileFromThisRootDir(srcpath)
    # names = [custombasename(x.strip())for x in filelist]
    filedict = {}
    for cls in wordname_18:
        fd = open(os.path.join(dstpath, 'Task1_') + cls + r'.txt', 'w')
        filedict[cls] = fd
    for filepath in filelist:
        objects = parse_dota_poly2(filepath)

        subname = custombasename(filepath)
        pattern2 = re.compile(r'__([\d+\.]+)__\d+___')
        rate = re.findall(pattern2, subname)[0]

        for obj in objects:
            category = obj['name']
            difficult = obj['difficult']
            poly = obj['poly']
            if difficult == '2':
                continue
            if rate == '0.5':
                outline = custombasename(filepath) + ' ' + '1' + ' ' + ' '.join(map(str, poly))
            elif rate == '1':
                outline = custombasename(filepath) + ' ' + '0.8' + ' ' + ' '.join(map(str, poly))
            elif rate == '2':
                outline = custombasename(filepath) + ' ' + '0.6' + ' ' + ' '.join(map(str, poly))

            filedict[category].write(outline + '\n')

def Task2groundtruth_poly(srcpath, dstpath):
    thresh = 0.1
    filedict = {}
    Tasklist = GetFileFromThisRootDir(srcpath, '.txt')

    for Taskfile in Tasklist:
        idname = custombasename(Taskfile).split('_')[-1]
        # idname = datamap_inverse[idname]
        f = open(Taskfile, 'r')
        lines = f.readlines()
        for line in lines:
            if len(line) == 0:
                continue
            # print('line:', line)
            splitline = line.strip().split(' ')
            filename = splitline[0]
            confidence = splitline[1]
            bbox = splitline[2:]
            if float(confidence) > thresh:
                if filename not in filedict:
                    # filedict[filename] = codecs.open(os.path.join(dstpath, filename + '.txt'), 'w', 'utf_16')
                    filedict[filename] = codecs.open(os.path.join(dstpath, filename + '.txt'), 'w')
                # poly = util.dots2ToRec8(bbox)
                poly = bbox
                #               filedict[filename].write(' '.join(poly) + ' ' + idname + '_' + str(round(float(confidence), 2)) + '\n')
            # print('idname:', idname)

            # filedict[filename].write(' '.join(poly) + ' ' + idname + '_' + str(round(float(confidence), 2)) + '\n')

            filedict[filename].write(' '.join(poly) + ' ' + idname + '\n')


def polygonToRotRectangle(bbox):
    """
    :param bbox: The polygon stored in format [x1, y1, x2, y2, x3, y3, x4, y4]
    :return: Rotated Rectangle in format [cx, cy, w, h, theta]
    """
    bbox = np.array(bbox,dtype=np.float32)
    bbox = np.reshape(bbox,newshape=(2,4),order='F')
    angle = math.atan2(-(bbox[0,1]-bbox[0,0]),bbox[1,1]-bbox[1,0])

    center = [[0],[0]]

    for i in range(4):
        center[0] += bbox[0,i]
        center[1] += bbox[1,i]

    center = np.array(center,dtype=np.float32)/4.0

    R = np.array([[math.cos(angle), -math.sin(angle)], [math.sin(angle), math.cos(angle)]], dtype=np.float32)

    normalized = np.matmul(R.transpose(),bbox-center)

    xmin = np.min(normalized[0,:])
    xmax = np.max(normalized[0,:])
    ymin = np.min(normalized[1,:])
    ymax = np.max(normalized[1,:])

    w = xmax - xmin + 1
    h = ymax - ymin + 1

    return [float(center[0]),float(center[1]),w,h,angle]

运行这个程序
YOLO_Transform.py

import dota_utils as util
import os
import numpy as np
from PIL import Image

from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
Image.MAX_IMAGE_PIXELS = None


## trans dota format to format YOLO(darknet) required
def dota2darknet(imgpath, txtpath, dstpath, extractclassname):
    """
    :param imgpath: the path of images
    :param txtpath: the path of txt in dota format
    :param dstpath: the path of txt in YOLO format
    :param extractclassname: the category you selected
    :return:
    """
    filelist = util.GetFileFromThisRootDir(txtpath)
    for fullname in filelist:
        objects = util.parse_dota_poly(fullname)
        name = os.path.splitext(os.path.basename(fullname))[0]
        img_fullname = os.path.join(imgpath, name + '.png')
        img = Image.open(img_fullname)
        img_w, img_h = img.size
        # print img_w,img_h
        with open(os.path.join(dstpath, name + '.txt'), 'w') as f_out:
            for obj in objects:
                poly = obj['poly']
                bbox = np.array(util.dots4ToRecC(poly, img_w, img_h))
                if (sum(bbox <= 0) + sum(bbox >= 1)) >= 1:
                    continue
                if (obj['name'] in extractclassname):
                    id = extractclassname.index(obj['name'])
                else:
                    continue
                outline = str(id) + ' ' + ' '.join(list(map(str, bbox)))
                f_out.write(outline + '\n')


if __name__ == '__main__':
    dota2darknet('D:/SCI/DS/DOTA/train/images/images',
                 'D:/SCI/DS/DOTA/train/labelTxt-v1.0/trainset_reclabelTxt',  # 
                 'D:/SCI/DS/DOTA/train/labelTxt-v1.0/labels_yolo',      #这个是train数据集转化保存的路径
                 util.wordname_18)

    dota2darknet('D:/SCI/DS/DOTA/val/images/images',
                 'D:/SCI/DS/DOTA/val/labelTxt-v1.0',
                 'D:/SCI/DS/DOTA/val/images/labels_yolo',
                 util.wordname_18)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

dota数据集转换为YOLO格式的方法 的相关文章

随机推荐

  • C++中的结构体继承一个类

    2023年8月5日 周六上午 在C 中 结构体可以继承另一个类 include
  • C语言类型转换----有符号数截断问题

    程序员面试宝典中有这个一道题 下面程序的结果是多少 include
  • SSHDroid及sshpass简介

    一 SSHDroid简介 SSH为Secure Shell的缩写 是建立在应用层基础上的安全协议 SSH是目前较可靠 专为远程登录会话和其他网络服务提供安全性的协议 利用SSH协议可以有效防止远程管理过程中的信息泄露问题 SSH客户端适用于
  • 4、如何在flink任务中读取外部数据源(DataStream API)

    1 Flink读取外部数据源的方式 Flink是一个流批一体的分布式计算框架 它不会存储数据 编写Flink计算任务的第一步就是通过连接器去读取外部数据 Flink提供了多种 预定义 data sources 来读取外部数据 如 文件 目录
  • Windows与Linux利用系统自带实现共享文件夹的功能

    这里需要两台机器在同一局域网或者可互相ping通 系统以Windows11和Windows Subsystem for Linux Ubuntu22 04 1 或国产Linux发行版的统信UOS 版本号20 为例 其他的版本系统也类似 非L
  • 使用python实现反欺诈模型,不平衡采样so easy!

    小天导语 周五的夜晚 各位亲们是不是开始期待双休呢 小天今天会在不平衡数据基础上 利用python建立反欺诈模型和分析数据 模拟分类预测模型中因变量分类出现不平衡的情况并解决反欺诈以及客户违约和疾病监测等问题 只要是因变量中各分类占比悬殊
  • muduo学习(一)

    大并发服务器架构设计 如何降低数据库 提高数据库的并发能力 的方法 1 队列 连接池 DAL 2 主要的业务逻辑挪到应用服务器处理 数据库只做辅助的业务处理 3 缓存 使用缓存的问题 缓存更新 同步 见链接 https www cnblog
  • pat乙级真题给定一系列正整数,请按要求对数字进行分类,并输出以下5个数字

    题目描述 给定一系列正整数 请按要求对数字进行分类 并输出以下5个数字 A1 能被5整除的数字中所有偶数的和 A2 将被5除后余1的数字按给出顺序进行交错求和 即计算n1 n2 n3 n4 A3 被5除后余2的数字的个数 A4 被5除后余3
  • 默克尔树_默克尔树:正在使用中

    默克尔树 Ralph C Merkle not pictured above born 1952 is one of the founding fathers of Public Key Cryptography Throughout hi
  • geotools坐标转换

    报错 org geotools referencing operation MathTransformProvider geotools org postgresql ds PGSimpleDataSource geotools版本我使用的
  • LNK1169 LNK2005错误

    当我们在visual Studio 中编译时 经常会发生这两个错误 通常这两个错误是同时产生的 产生原因 找到一个或多个多重定义的符号 生成因一个或多个符号的多个定义而失败 该错误之前为错误 LNK2005 通常情况下 是因为不正确的使用导
  • 树莓派/PC实现实时摄像头数据共享—最优方法(搭建网络摄像头)

    目录 方法一 motion方式 方法二 MJPG streamer方式 之前做项目需要树莓派和PC进行视频传输 发现两种方法 方法一 Python OpenCv实现树莓派数据采集 树莓派搭建服务器 PC机作为客户端实现数据传输 结果发现传输
  • windows播放函数PlaySound

    在编写windows程序时 很多时候要用到播放音乐的函数 而windows下就提供了一个函数PlaySound 首先说下这个函数的使用范围 PlaySound函数用于播放一个音频文件 且这个文件时wav格式 且只能是wav格式 如果你需要混
  • 如何识别C++编译以后的函数名

    C C 语言在编译以后 函数的名字会被编译器修改 改成编译器内部的名字 这个名字会在链接的时候用到 如果用backtrace之类的函数打印堆栈时 显示的就是被编译器修改过的名字 比如说 Z3foov 那么这个函数真实的名字是什么呢 每个编译
  • 记录开发中遇到sonar以及相关思路解决

    sonar问题汇总 1 布尔常量使用 问题标题 How to fix the major issue in SonarQube needlessly boxes a boolean constant 如何解决 SonarQube 中的主要问
  • 【前端】CSS水平居中的6种方法

    文章目录 flex 绝对定位 margin auto 绝对定位 margin 负值 定位 transform text align center margin 0 auto 思维导图 后文 前端 CSS垂直居中的7种方法 karshey的博
  • about wParam and lParam

    这两个是Win16系统遗留下来的产物了在Win16API中WndProc有两个参数一个是WORD类型的16位整型变量另一个是LONG类型的32位整型变量 因此根据匈牙利命名法 16位的变量就被命名为wParam 而32位的变量就被命名为lP
  • zotero使用教程学习

    从b站找的视频中学习zotero 视频见 商小图学堂 文献管理神器之Zotero 1收集题录 1 1用浏览器插件 如何安装插件自行百度 因为我忘记了 而且在Google上我不会安装 有空仔细学一下 1 2通过标识符添加 1 3下载文献后拖拽
  • 520最浪漫表白:QQ打开基于Python实现的无法拒绝的音乐表白代码!别让等待,成了遗憾!

    520表白日 男人怎么送礼物 就怎么爱你 每个女孩都喜欢男孩对自己浪漫的表白 不过每个人性格不同 浪漫表白的方式也不尽相同 那么520怎样浪漫的表白好呢 程序员如何俘获心仪女神的心呢 当然是要用程序员的方法了 在2020年5月20日到来之际
  • dota数据集转换为YOLO格式的方法

    下载好dota数据集 运行下面代码 dota utils py import sys import codecs import numpy as np import shapely geometry as shgeo import os i