ArcPro制作遥感影像分类数据集

标签: 无 分类: 未分类 创建时间:2025-01-03 09:15:08 更新时间:2025-01-17 10:39:21

1.前言

在 ArcPro中自带了深度学习标注工具,就不需要像 ArcMap 中这么麻烦了。但是经过我的尝试,“标注对象以供深度学习使用,只能进行图像分类使用,不能坐分割使用。生成的 label 只有坐标的最大最小值信息。”

1.加载影像

就是通过工具栏,知道地图,加载一个 .tif 的影像数据。

2.新建方案

点击工具栏 “分类工具” -> “标注对象以供深度学习使用”,打开新的标注方案。

3.新建分类

新建新的分类,填写名称,数值,还有颜色,别名。

4.绘制图形

选择不同的图形类型,然后进行标注绘制,有 “方框”、“多边形”、”圆形”,还有手绘。

5.导出训练数据

通过 “导出训练数据”,可以将标注好的数据导出为需要的数据格式。

导出的数据格式可以有下面的一些方式:

  • KITTI 标注
    元数据遵循与卡尔斯鲁厄理工学院和丰田工业大学 (KITTI) 对象检测评估数据集相同的格式。 KITTI 数据集是一款视觉基准套件。 标注文件是纯文本文件。 所有的值(数值和字符串)均由空格分隔开,每行对应一个对象。

  • PASCAL 可视化对象类
    元数据遵循与模式分析、统计建模和计算学习、可视化对象类 (PASCAL VOC) 数据集相同的格式。 PASCAL VOC 数据集是用于对象类识别的标准化影像数据集。 标注文件是 .xml 文件,包含有关影像名称、类值和边界框的信息。 这是默认设置。

  • 导出切片
    输出将为不带标注的影像片。 此格式用于影像转换技术,例如 Pix2Pix 和超分辨率。

参考文章:
【1】.Python|遥感影像语义分割:使用Python(GDAL)制作遥感影像语义分割数据集 使用ArcGIS Pro标注得到标签图标注对象以供深度学习使用—ArcGIS Pro | 文档,由于我的任务是二分类任务,因此我得到的标签图是一张二值图。这里提供了 Python 代码,对二值图进行了切割,”滑动窗口裁剪函数“,这个其实可以作为后面分割的代码。
【2】.标注对象以供深度学习使用 这是官方工具说明,但是经过我不断的尝试,这里是用作分类的标注,而不是分割的标注。
【3】.目标检测:PASCAL VOC 数据集简介 SegmentationClass 存放按照 class 分割的图片,SegmentationObject 存放按照 object 分割的图片

6.格式转换

导出的数据格式可能并不是需要的,还需要进行数据格式转换。从 arcpro 中导出的 voc 格式,需要转换为 yolo 的 text 格式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import xml.etree.ElementTree as ET
import os
# 类别
classes = ['255']

def convert(size, box):
dw = 1./(size[0])
dh = 1./(size[1])
x = (box[0] + box[1])/2.0 - 1
y = (box[2] + box[3])/2.0 - 1
w = box[1] - box[0]
h = box[3] - box[2]
x = x*dw
w = w*dw
y = y*dh
h = h*dh
if w>=1:
w=0.99
if h>=1:
h=0.99
return (x,y,w,h)

def convert_annotation(rootpath,xmlname):
xmlpath = rootpath + '/labels'
xmlfile = os.path.join(xmlpath,xmlname)
with open(xmlfile, "r", encoding='UTF-8') as in_file:
txtname = xmlname[:-4]+'.txt'
print(txtname)
txtpath = rootpath + '/worktxt'#生成的.txt文件会被保存在worktxt目录下
if not os.path.exists(txtpath):
os.makedirs(txtpath)
txtfile = os.path.join(txtpath,txtname)
with open(txtfile, "w+" ,encoding='UTF-8') as out_file:
tree=ET.parse(in_file)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
out_file.truncate()
for obj in root.iter('object'):
cls = obj.find('name').text
if cls not in classes:
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
bb = convert((w,h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')

if __name__ == "__main__":
rootpath=r'D:\zlc\drone\drone-train\data\segment'
xmlpath=rootpath+'/labels'
list=os.listdir(xmlpath)
for i in range(0,len(list)) :
path = os.path.join(xmlpath,list[i])
if ('.xml' in path)or('.XML' in path):
convert_annotation(rootpath,list[i])
print('done', i)
else:
print('not xml file',i)
参考文章:
【1】.PASCAL VOC 数据集转化为yolo数据集格式 1.PASCAL VOC数据格式;2.yolo 数据格式;3.文件布局如图所示。
【2】.YOLO与voc格式互转,超详细
【3】.VOC格式数据集转yolo格式数据集 这里也提到了一个 Annotations 的文件夹,我看代码像是转换目标识别的代码,而不是图像分割的代码。开始我以为是这个样子,后来我发现好像图像分割和图像分类是一样的,只不过我的转换代码有问题罢了。
【4】.目标检测:数据集划分 & XML数据集转YOLO标签 这个代码我感觉和转换的策略还是挺正常的。
【5】.label_convert 一个数据转换工具。
【6】.PaddleX GUI 当前PaddleX GUI支持ImageNet格式的图像分类数据集、VOC格式的目标检测数据集、COCO格式的实例分割数据集、Seg格式的语义分割的数据集,当使用LabelMe、EasyData、标注精灵这3个工具标注数据时,PaddleX提供了相应接口可将数据转换成与PaddleX GUI想适配的数据集,使用方式如下所示:
【7】.支持的数据集格式 这是yolo支持的数据集格式,官方说明:1.每幅图像一个文本文件:数据集中的每幅图像都有一个相应的文本文件,文件名与图像文件相同,扩展名为”.txt”。2.每个对象一行:文本文件中的每一行对应图像中的一个对象实例。3.每行对象信息:每行包含对象实例的以下信息,对象类别索引:代表对象类别的整数(如 0 代表人,1 代表汽车等),对象边界坐标:遮罩区域周围的边界坐标,归一化后介于 0 和 1 之间。
【8】. ultralytics / JSON2YOLO Welcome to the COCO2YOLO repository! This toolkit is designed to help you convert datasets in JSON format, following the COCO (Common Objects in Context) standards, into YOLO (You Only Look Once) format, which is widely recognized for its efficiency in real-time object detection tasks.

问题

(1)只有具有单波段或三波段且没有色彩映射的 8 位无符号或 16 位无符号数据支持 JPEG 压缩
yolo训练的时候,只支持 jpeg 格式的数据,不支持 tiff 格式,在创建供深度学习的数据集的时候,可以选择导出为jpg格式,但是使用 arcpro 转换为 jpg,又出现相应的错误。tif为多波段数据,一般包括4波段(蓝、绿、红、近红外)。我使用了 python转换成了 jpg 格式,结果倒是能转换,但是丢失了大部分的地理信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import os
from PIL import Image

def tif_to_jpg(input_dir, output_dir):
if not os.path.exists(output_dir):
os.makedirs(output_dir)
for filename in os.listdir(input_dir):
if filename.endswith('.tif'):
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename.replace('.tif', '.jpg'))
image = Image.open(input_path)
image.convert('RGB').save(output_path, 'JPEG')

input_dir = r'D:\zlc\drone\drone-train\data\tif'
output_dir = r'D:\zlc\drone\drone-train\data\tif'
tif_to_jpg(input_dir, output_dir)

【解决方案】
解决方案其实不是解决方案,yolo是支持tif检测的,只是因为我的坐标转换的时候,出现了问题,没有加载进来图片,所以导致问题了。

参考文章:
【1】.解决ERROR 001523: 只有具有单波段或三波段且没有色彩映射的 8 位无符号或 16 位无符号数据支持 JPEG 压缩 1.使用的arcmap 在图层窗口中 选中tif ,选择导出,选 使用渲染器和强制为RGB颜色!其余内容默认即可,输出位置根据自己需要保存。2.直接在gispro 中 导出栅格然后选择,使用渲染器和强制为RGB颜色。
【2】.Yolov8改为高光谱多通道图像输入 这里修改了模型配置,代码处理等,还是挺麻烦的。
【3】.基于yolov10完成对遥感影像的屋顶光伏检测识别 这里直接用的 tif 裁剪然后进行预测。
【4】.Python + Opencv 实现图像tif格式转jpg 这里提供了一个 tif 转 jpg 的代码。
【5】.【板栗糖GIS】arcmap—如何批量将4波段影像转换为3波段
【6】.准备影像和栅格数据以供分析
【7】.将高分二四波段影像提取为三波段影像 1.用Arcmap打开高分影像,查看影像为4波段,右键影像,选择导出数据,勾选强制转换成RGB,输入保存路径和保存名称,点击save。2.波段融合,工具箱,找到 “数据管理工具” -> “栅格” -> “栅格处理” -> Composite Bands(波段合成)
【8】.在 Python 中将 TIFF转换为JPG 将库引用(导入库)添加到您的Python项目,在Python打开源TIFF文件,调用save()方法,传递带有JPG扩展名的输出文件名,TIFF转换的结果JPG。
【9】.python tif图片转为jpg 这里用了 PIL 库,可以执行成功。
【10】.Python + Opencv 实现图像tif格式转jpg 这里用了 opencv,看似简单,实际上没有用的。
【11】.踩坑实录——多光谱影像(.tif)输入深度学习网络训练 这里有很多的问题出现了,也解决了不少问题。
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。