如何将DOTA数据集的标注坐标转换为地理坐标
在遥感图像分析和地理信息系统(GIS)中,将图像数据与其地理位置关联起来是一项关键技术。本教程将展示如何使用Python将DOTA数据集中的标注坐标转换为地理坐标。
·
在遥感图像分析和地理信息系统(GIS)中,将图像数据与其地理位置关联起来是一项关键技术。本教程将展示如何使用Python将DOTA数据集中的标注坐标转换为地理坐标。
数据准备
dota数据格式的标注文件以及标注文件所对应的jpg格式的图像和xml格式的地理信息文件。
1. dota格式的数据标注
标注文件名称示例:large_image_11_21_2010.txt,标注文件内容示例如下:
9200.6 9013.3 9211.4 9017.7 9191.4 9066.7 9180.6 9062.3 dam 0
4665.6 10331.5 4671.7 10325.7 4704.1 10360.3 4698.0 10366.0 dam 0
9904.5 11347.8 9916.5 11348.2 9915.5 11380.2 9903.5 11379.8 dam 0
11025.0 373.9 11040.0 381.1 10988.0 489.1 10973.0 481.9 dam 0
9431.8 10677.2 9447.3 10677.3 9447.0 10728.0 9431.5 10727.9 dam 0
2. jpg格式的图像
图像文件名称示例:large_image_11_21_2010.jpg
3. xml格式的地理信息
地理信息文件名称示例:large_image_11_21_2010.jpg.aux.xml,地理信息文件内容示例如下:
<PAMDataset>
<SRS dataAxisToSRSAxisMapping="2,1">GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]</SRS>
<GeoTransform> 28.14697265625, 2.1457672119140625e-05, 0, -25.5322265625, 0, -2.1457672119140625e-05</GeoTransform>
</PAMDataset>
代码输出
dota的四个点的像素坐标转化为地理坐标
28.344396114349365 -25.72563099861145 28.344627857208252 -25.725725412368774 28.34419870376587 -25.726776838302612 28.343966960906982 -25.726682424545288 dam 0
28.247085571289062 -25.7539165019989 28.24721646308899 -25.75379204750061 28.24791169166565 -25.754534482955933 28.247780799865723 -25.75465679168701 dam 0
28.35950016975403 -25.775723934173584 28.359757661819458 -25.77573251724243 28.35973620414734 -25.776419162750244 28.35947871208191 -25.776410579681396 dam 0
28.383543491363525 -25.540249586105347 28.383865356445312 -25.540404081344604 28.382749557495117 -25.54272150993347 28.38242769241333 -25.542567014694214 dam 0
28.34935712814331 -25.76133441925049 28.349689722061157 -25.7613365650177 28.34968328475952 -25.76242446899414 28.349350690841675 -25.76242232322693 dam 0
代码
import os
import cv2
import numpy as np
from xml.etree import ElementTree
def draw_boxes_on_image(image_path, boxes, color=(0, 255, 0), thickness=4):
"""在图像上绘制旋转矩形边框。
Args:
image_path (str): 图像文件路径。
boxes (list): 边框列表,每个边框由四个点坐标组成。
color (tuple): 绘制边框的颜色,默认为绿色。
thickness (int): 边框的厚度。
"""
# 从文件中读取图像并解码
image = cv2.imdecode(np.fromfile(image_path, dtype=np.uint8), cv2.IMREAD_COLOR)
# 遍历所有边框并在图像上绘制
for box in boxes:
points = np.array(box, np.int32)
points = points.reshape((-1, 1, 2))
cv2.polylines(image, [points], True, color, thickness)
print("Drawing box:", box)
# 指定输出文件夹和文件名
output_folder = os.path.dirname(image_path)
output_file_name = os.path.splitext(os.path.basename(image_path))[0] + '_boxed.jpg'
output_path = os.path.join(output_folder, output_file_name)
print(output_path)
# 将绘制好的图像保存到文件
cv2.imwrite(output_path, image)
def parse_xml_for_geotransform(xml_path):
"""从XML文件解析地理变换参数。
Args:
xml_path (str): XML文件的路径。
Returns:
list: 包含地理变换参数的列表。
"""
tree = ElementTree.parse(xml_path)
root = tree.getroot()
geotransform = []
# 解析XML以获取地理变换参数
for element in root.findall('.//GeoTransform'):
geotransform = list(map(float, element.text.split(',')))
return geotransform
def pixel_to_geo(geotransform, x_pixel, y_pixel):
"""将像素坐标转换为地理坐标。
Args:
geotransform (list): 地理变换参数。
x_pixel (float): x方向的像素坐标。
y_pixel (float): y方向的像素坐标。
Returns:
tuple: 包含经度和纬度的元组。
"""
lon = geotransform[0] + x_pixel * geotransform[1] + y_pixel * geotransform[2]
lat = geotransform[3] + x_pixel * geotransform[4] + y_pixel * geotransform[5]
return lon, lat
def img_pre_processing(image_path, xml_path):
"""图像预处理和解析XML以获取地理变换参数。
Args:
image_path (str): 图像文件的路径。
xml_path (str): XML文件的路径。
Returns:
list: 地理变换参数。
"""
# 从文件读取并解码图像
image = cv2.imdecode(np.fromfile(image_path, dtype=np.uint8), cv2.IMREAD_COLOR)
if image is None:
raise FileNotFoundError(f"Image {image_path} not found.")
# 解析XML文件以获取地理变换参数
geotransform = parse_xml_for_geotransform(xml_path)
return geotransform
def process_dotas(image_path, xml_path, type_folder, output_folder):
"""处理DOTA标注并转换为地理坐标标注。
Args:
image_path (str): 图像文件路径。
xml_path (str): XML文件路径。
type_folder (str): 包含DOTA标注的文件夹路径。
output_folder (str): 输出地理坐标标注的文件夹路径。
"""
geotransform_input = img_pre_processing(image_path, xml_path)
boxes = []
image_path_basename = os.path.splitext(os.path.basename(image_path))[0]
type_txt = image_path_basename + '.txt'
output_geo_txt_path = os.path.join(output_folder, image_path_basename + '_geo.txt')
# 读取DOTA标注文件并转换坐标
with open(os.path.join(type_folder, type_txt), 'r', encoding="utf-8") as t, open(output_geo_txt_path, 'w') as f:
for line in t:
parts = line.split()
dota_nodes = parts[:8]
dota_type = parts[8]
geo_coords = []
dota_coords = [(float(dota_nodes[i]), float(dota_nodes[i + 1])) for i in range(0, len(dota_nodes), 2)]
boxes.append(dota_coords)
for i in range(0, len(dota_nodes), 2):
x_pixel_input = float(dota_nodes[i])
y_pixel_input = float(dota_nodes[i + 1])
lon, lat = pixel_to_geo(geotransform_input, x_pixel_input, y_pixel_input)
geo_coords.append((lon, lat))
flat_coords = [coord for point in geo_coords for coord in point]
difficulty = 0
dota_line = ' '.join(map(str, flat_coords)) + f" {dota_type} {difficulty}\n"
print(dota_line)
f.write(dota_line)
draw_boxes_on_image(image_path, boxes)
if __name__ == '__main__':
jpg_xml_folder = r'D:\修复数据\研究生\project\代码\train_v4\data_v2\test\images'
# 包含jpg图像和xml类型的地理信息文件的文件夹
output_geo_folder = r'D:\修复数据\研究生\project\代码\train_v4\data_v2\test\geographic'
# 输出的地理信息文件的文件夹
type_folder = r'D:\修复数据\研究生\project\代码\train_v4\data_v2\test\labels'
# dota格式的标注好的数据文件夹
if not os.path.exists(output_geo_folder):
os.makedirs(output_geo_folder)
for image_filename in os.listdir(jpg_xml_folder):
if image_filename.endswith('.jpg'):
base_name = os.path.splitext(image_filename)[0]
image_path = os.path.join(jpg_xml_folder, image_filename)
xml_path = os.path.join(jpg_xml_folder, base_name + '.jpg.aux.xml')
print(image_filename)
process_dotas(image_path, xml_path, type_folder, output_geo_folder)

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)