HRSC2016绘制Ground Truth

利用DOTA的脚本绘制HRSC数据集的真实框,首先将HRSC的标注文件转换为DOTA格式,然后利用DOTA的脚本绘制目标框

新建文件

进入到HRSC2016的Test目录,新建两个文件夹:
在这里插入图片描述

mkdir DOTA_labels DOTA_labels_drawed

新建3个py文件

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 allfilesdef 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 outpolydef 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 = fdelif (sys.version_info >= 2.7):fd = codecs.open(filename, 'r')f = fd# count = 0while True:line = f.readline()# count = count + 1# if count < 2:#     continueif 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):continueif (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'] = 0object_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 + 1objects.append(object_struct)else:breakreturn objectsdef dots4ToRecC(poly, img_w, img_h):xmin, ymin, xmax, ymax = dots4ToRec4(poly)x = (xmin + xmax)/2y = (ymin + ymax)/2w = xmax - xminh = ymax - yminreturn x/img_w, y/img_h, w/img_w, h/img_hdef 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 objectsdef 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'] = bboxreturn objects
## bounding box transfer for varies formatdef 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, ymaxdef groundtruth2Task1(srcpath, dstpath):filelist = GetFileFromThisRootDir(srcpath)# names = [custombasename(x.strip())for x in filelist]filedict = {}for cls in wordname_15:fd = open(os.path.join(dstpath, 'Task1_') + cls + r'.txt', 'w')filedict[cls] = fdfor 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':continueif 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.1filedict = {}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.0R = 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 + 1h = ymax - ymin + 1return [float(center[0]),float(center[1]),w,h,angle]

hrsc2dota.py

import xml.etree.ElementTree as ET
import os
import math
import cv2
import numpy as np
def get_label(xml_path):in_file = open(xml_path)tree=ET.parse(in_file)root = tree.getroot()labels = []for obj in root.iter('HRSC_Object'):difficult = obj.find('difficult').textclass_id = int(obj.find('Class_ID').text) % 100# class_id = 0 # 标签对应关系自行修改# if int(difficult) == 1:#     continuembox_cx, mbox_cy, mbox_w, mbox_h, mbox_ang = (float(obj.find('mbox_cx').text),float(obj.find('mbox_cy').text),float(obj.find('mbox_w').text),float(obj.find('mbox_h').text),float(obj.find('mbox_ang').text))labels.append([class_id,mbox_cx, mbox_cy, mbox_w, mbox_h,mbox_ang])return labels
# 计算旋转框四个顶点的坐标
def get_rotated_box_vertices(labels,label_path):with open(label_path,'w') as f:for i in range(len(labels)):class_id,mbox_cx, mbox_cy, mbox_w, mbox_h,angle_rad= labels[i]rotation_matrix = np.array([[np.cos(angle_rad), -np.sin(angle_rad)],[np.sin(angle_rad), np.cos(angle_rad)]])box_half_width = mbox_w / 2box_half_height = mbox_h / 2box_vertices = np.array([[-box_half_width, -box_half_height],[box_half_width, -box_half_height],[box_half_width, box_half_height],[-box_half_width, box_half_height]])rotated_vertices = np.dot(box_vertices, rotation_matrix.T)rotated_vertices[:, 0] += mbox_cxrotated_vertices[:, 1] += mbox_cyrotated_vertices = np.round(rotated_vertices).astype(np.int32)# print(rotated_vertices)# f.write(" ".join([str(a) for a in rotated_vertices]) + '\n')rotated_vertices = rotated_vertices.reshape(-1)f.write(" ".join([str(a) for a in rotated_vertices]) + " " + str(class_id) + '\n')# return rotated_vertices_listxml_root = r"Annotations"
txt_root = r"DOTA_labels"xml_name = os.listdir(xml_root)
# print(len(xml_name))
for i in range(len(xml_name)):xml_path = os.path.join(xml_root,xml_name[i])if xml_path == "Annotations/.ipynb_checkpoints":continuetxt_path = os.path.join(txt_root,xml_name[i].split('.')[0]+'.txt')get_rotated_box_vertices(get_label(xml_path),txt_path)

dota_drawed.py

import xml.etree.ElementTree as ET
import os
import math
import cv2
import numpy as np
import dota_utils as util
import random# 手动输入cx cy w h angle进行绘制
# from HRSC_to_DOTA import get_rotated_box_vertices
# cx = 569.5045
# cy = 263.4875
# w = 261.0578
# h = 65.08137
# angle = -1.562451
# vertices = get_rotated_box_vertices(cx, cy, w, h, angle)
# vertices = np.array(vertices,dtype=np.int32)
# img = cv2.imread(r'AllImages\100000640.bmp')
# cv2.polylines(img,[vertices], isClosed=True, color=(255, 0, 0), thickness=2)
# cv2.imshow('test',img)
# cv2.waitKey(0)
# cv2.destroyAllWindows()img_root = r"AllImages"
label_root = r"DOTA_labels"
drawed_img_root = r"DOTA_labels_drawed"
image_name = os.listdir(img_root)
for i in range(len(image_name)):img_path = os.path.join(img_root,image_name[i])label_path = os.path.join(label_root,image_name[i].split('.')[0]+'.txt')drawed_img_path = os.path.join(drawed_img_root,image_name[i])objects = util.parse_dota_poly(label_path)print(objects)img = cv2.imread(img_path)poly = []for i in range(len(objects)):poly.append(np.array(objects[i]['poly'],dtype=np.int32))print(poly)cv2.polylines(img,poly, isClosed=True, color=(35, 37, 133), thickness=2)drawed_img_path = drawed_img_path.replace('.bmp','.png')cv2.imwrite(drawed_img_path,img)

运行

conda activate mmrotate
python hrsc2dota.py

可以看到已经转换好的DOTA格式标注文件
在这里插入图片描述

python dota_drawed.py

可以看到绘制好的图片
在这里插入图片描述
说明:在dota_drawed.py文件中,40行我改了一下图片后缀,默认是bmp格式
在39行可以改标注框的颜色:在线取色器
在这里插入图片描述
参考:
《HRSC2016_dataset 旋转框 + 划分数据集》
《深度学习|dota格式的txt文件转化为yolo格式的txt文件》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1534480.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【TabBar嵌套Navigation案例-cell重用 Objective-C语言】

一、我们来说这个cell重用(重复使用)的问题啊 1.我们这个比分直播推送页面, 这个里边呢,现在这个cell,涉及到两个样式,上面呢,是Default的,下面呢,是Value1的,然后,我们在这个里边啊,我们每一组就一个cell啊,然后呢,我把这个组,多给它复制几份儿,现在是三个组…

Linux-Makefile的编写、以及编写第一个Linux程序:进度条(模拟方便下载的同时,更新图形化界面)

目录 一、Linux项目自动化构建工具-make/Makefile ​编辑 背景&#xff1a; makefile小技巧&#xff1a; 二、Linux第一个小程序&#xff0d;进度条 先导&#xff1a; 1.如何利用/r,fflush(stdout)来实现我们想要的效果&#xff1b; 2.写一个倒计时&#xff1a; 进度条…

恭喜!龙蜥社区2024年中三大奖项评选名单新鲜出炉

近日&#xff0c;在 2024 龙蜥操作系统大会上&#xff0c;龙蜥社区公布了 2024 年中三大奖项评选名单——“最佳合作伙伴奖”“最佳用户案例奖”“最佳应用实践奖&#xff08;个人&#xff09;”&#xff0c;并邀请清华大学计算机系教授、龙蜥社区高级顾问史元春&#xff0c;海…

地市专利申请及授权数据集合(2000-2023年)xlsx+dta格式

包括发明专利、实用新型、外观专利的申请和授权等。专利作为衡量一个地区科技创新能力和水平的重要指标&#xff0c;不仅反映了地方企业在技术研发、产品创新方面的活跃程度&#xff0c;也是推动产业升级、促进经济高质量发展的关键力量 一、数据介绍 数据名称&#xff1a;地…

ImportError: DLL load failed while importing _ssl: 找不到指定的模块的解决方法

ImportError: DLL load failed while importing _ssl: 找不到指定的模块的解决方法 现象解决办法 现象 在命令行中&#xff0c;可以正常导入_ssl模块&#xff0c;如下&#xff1a; Python 3.9.0 (default, Nov 15 2020, 08:30:55) [MSC v.1916 64 bit (AMD64)] :: Anaconda, …

落地扶持丨云微客山西临汾落地会销圆满收官

2024年9月6日&#xff0c;云微客落地扶持走进山西临汾红星美凯龙《助力家居行业营销数智化研讨会》&#xff0c;活动吸引了近百家家居品牌商户的参与&#xff0c;现场气氛热烈&#xff0c;签约不断&#xff0c;为当地家居行业打开短视频矩阵营销新思路。 短视频成为全行业必争…

界面控件DevExpress中文教程:如何PDF图形对象的可见性?

DevExpress拥有.NET开发需要的所有平台控件&#xff0c;包含600多个UI控件、报表平台、DevExpress Dashboard eXpressApp 框架、适用于 Visual Studio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpress 近期重要版本v24.1已正式发布&#xff0c;该版本拥有众多新产…

单机快速部署开源、免费的分布式任务调度系统——Apache DolphinScheduler

本文主要为大家介绍Apache DolphinScheduler的单机部署方式&#xff0c;方便大家快速体验。 环境准备 需要Java环境&#xff0c;这是一个老生常谈的问题&#xff0c;关于Java环境的安装与配置期望大家都可以熟练掌握。 验证java环境 java -version 下载安装包并解压 使用wg…

现代 Web 开发工具箱:Element-UI 表单组件全攻略(一)

现代 Web 开发工具箱&#xff1a;Element-UI 表单组件全攻略&#xff08;一&#xff09; 一 . Radio 单选框1.1 创建 Radio 按钮① 注册路由② 创建 radio 组件 1.2 Radio 的相关属性① 是否禁用② 是否显示边框③ 原生 name 属性④ 按钮的样式 1.3 Radio 相关事件1.4 Radio 按…

从 TF卡升级 f1c100s spinand

开发GUI 便宜好用的ARM 不多见了&#xff0c;f1c100s 作为首选&#xff0c;搜索相关spinand 启动支持 的uboot 帖子大多相当久远&#xff0c;随着uboot的升级 已经支持spinand 启动&#xff0c;但是spl 部分支持任然需要查询相关资料才行&#xff1b; 参考该博主文章&#xff…

Kubernetes从零到精通(07-工作负载-StatefulSet)

StatefulSet示例 正如Deployment管理无状态应用程序的资源&#xff0c;StatefulSet用来管理有状态应用程序&#xff08;如kafka、redis、zookeeper集群等&#xff09;的资源&#xff0c;它为每个 Pod 分配一个固定的名称和存储&#xff0c;以确保它们可以保留状态&#xff0c;无…

PHP仓库物资出入库管理系统小程序源码

仓库物资出入库管理系统&#xff1a;让库存管理变得井井有条 **&#x1f4e6; 开篇&#xff1a;告别混乱&#xff0c;拥抱智能库存时代 还在为仓库里堆积如山的物资和繁琐的出入库记录而头疼吗&#xff1f;是时候告别那些混乱的日子了&#xff01;“仓库物资出入库管理系统”应…

Redis的持久化和高可用性

目录 一、淘汰策略 1、背景 2、淘汰策略 二、持久化 1、背景 2、fork进程写时复制机制 3、Redis持久化方式 1、aof 2、rdb 三、高可用 1、主从复制 2、Redis哨兵模式 3、Redis cluster集群 一、淘汰策略 1、背景 首先Redis是一个内存数据库&#xff0c;将所有数…

【Python机器学习】序列到序列建模和注意力机制——编码-解码架构

LSTM非常擅长处理序列&#xff0c;但我们需要一对而不是一个LSTM。我们将构建一个模块化的架构&#xff0c;称为编码-解码架构。 编码-解码架构的前半部分是序列编码器&#xff0c;该网络将序列&#xff08;如自然语言文本&#xff09;转换为较低维的表示形式&#xff08;如思…

重生奇迹MU 红龙剑士的风采 游戏玩家的记忆

在重生奇迹MU游戏中&#xff0c;剑士是一个老牌职业&#xff0c;而其中红龙剑士更是备受瞩目的角色。红龙剑士选手身着一身红色龙王装&#xff0c;仿佛已经沐浴了敌人的鲜血&#xff0c;是一个经验丰富的剑手。很多老玩家都信任剑士这个职业&#xff0c;并视其为忠实的伙伴&…

[每周一更]-(第114期):介绍GitLab不同角色对应的权限

文章目录 GitLab 角色及其权限项目级别角色组级别角色 使用场景示例 工作中一直使用Gitlab搭建了公司内网的代码管理工具&#xff0c;但是不同的用户会分配相应的权限&#xff0c;来管理不同用户及角色的权限信息&#xff0c;我们来介绍下角色的信息&#xff0c;方便我们管理公…

C++教程(一):超详细的C++矩阵操作和运算(附实例代码,与python对比)

python教程&#xff08;一&#xff09;&#xff1a;超详细的numpy矩阵操作和运算&#xff08;附实例代码&#xff09; 在之前的章节中&#xff0c;我们详细介绍了python中numpy的矩阵操作。但在自动驾驶开发中&#xff0c;我们一般采用C进行功能开发&#xff0c;因此C矩阵运算…

重学SpringBoot3-集成RocketMQ(二)

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成RocketMQ&#xff08;二&#xff09; 1. 基础概念2. 准备工作3. 实现事务消息的生产者4. 事务监听器实现5. 消费者示例6. 发送事务消息7. 测试7.1 模…

【新片场-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

如何用SQL Server和Oracle进行数据同步?

数据同步是大数据应用中非常重要的环节&#xff0c;它可以保证数据的实时性和一致性&#xff0c;为数据分析和决策提供重要依据。常见的数据同步方式包括ETL实时同步和实时ETL工具&#xff0c;其中实时ETL工具又可以分为基于日志追踪和基于触发器两种。 针对不同的数据库系统&…