图像分割之数据处理二

标签: 无 分类: 未分类 创建时间:2025-01-04 11:14:19 更新时间:2025-01-17 10:39:23

1.仿射变换

将切割后的数据合并之后,还有一个问题那就是会出现丢失坐标的问题,还需要将其还原。

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
from osgeo import gdal
import os
os.environ['PROJ_LIB'] =r"C:/Soft/anaconda3/envs/yolo/Lib/site-packages/osgeo/data/proj"

def apply_reference_geotransform(reference_path, input_path, output_path):
"""
将参考图像的地理变换应用到待转换图像上。

:param reference_path: 参考图像路径
:param input_path: 待转换图像路径
:param output_path: 输出的已地理配准图像路径
"""
# 打开源数据集
ref_ds = gdal.Open(reference_path)
if ref_ds is None:
print(f"无法打开参考文件 {reference_path}")
return

# 获取参考图像的地理变换和投影信息
geo_transform = ref_ds.GetGeoTransform()
projection = ref_ds.GetProjection()

# 关闭参考图像数据集
ref_ds = None

# 打开待转换图像数据集
src_ds = gdal.Open(input_path)
if src_ds is None:
print(f"无法打开输入文件 {input_path}")
return

# 创建输出文件
driver = gdal.GetDriverByName('GTiff')
dst_ds = driver.CreateCopy(output_path, src_ds, strict=0)

# 设置地理变换和投影信息
dst_ds.SetGeoTransform(geo_transform)
dst_ds.SetProjection(projection)

# 关闭数据集
dst_ds = None
src_ds = None

print(f"成功将 {input_path} 地理配准并保存至 {output_path}")

# 示例调用函数
input_tif = r'D:\zlc\drone\图像分割\栅格\Images\merged_image2.tif'
output_tif = r'D:\zlc\drone\图像分割\栅格\Images\merged_image3.tif'
reference_tif = r'D:\zlc\drone\图像分割\栅格\影像.tif'

try:
apply_reference_geotransform(reference_tif, input_tif, output_tif)
except Exception as e:
print(f"发生错误: {e}")
参考文章:
【1】.python+GDAL给图像设置地理参考(GeoTransform和Projection的设置) 可以看出,设置地理参考后,能够将图像呈现在对的位置(左上角坐标和分辨率固定),但无法纠正其几何形变。对高分影像而言,几何校正需要结合提供的rpb文件完成。下一步将使用rpb文件完成几何校正。
【2】.遥感影像的像素坐标转地理坐标(仿射变换)
【3】.GDAL中地理坐标与像素坐标之间的转换 这里是地理坐标转换成了像素坐标

2.转成shp

参考文章:
【1】.Python|使用Python实现tif文件转shpfile格式文件 这里直接给出来了代码,因为分类结果中可能会含有背景类或者我们不需要转成矢量的类,所以这里增加了一个参数来实现删除不需要转成矢量的类别要素。
【2】.遥感影像处理工具集 这里有多种工具:1.coco2mask.py:用于将COCO格式的标注文件转换为PNG格式。2.mask2shape.py:用于将模型推理输出的PNG格式栅格标签转换为.shp矢量格式。3.geojson2mask.py:用于将GeoJSON格式标签转换为.tif栅格格式。4.match.py:用于实现两幅影像的配准。5.split.py:用于对大幅面影像数据进行切片。6.coco_tools:COCO工具合集,用于统计处理COCO格式标注文件。7.prepare_dataset:数据集预处理脚本合集。8.extract_ms_patches.py:从整幅遥感影像中提取多尺度影像块。9.generate_file_lists.py:对数据集生成file list。

3.masks可视化

下面的代码选自通义,主要就是获取到了mask的所有类别,随机生成了一个颜色列表,然后进行了着色,并绘制了一个图例。

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
61
62
63
64
65
66
import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap, BoundaryNorm

def create_color_map(num_classes):
"""创建一个随机颜色映射表"""
color_map = []
for _ in range(num_classes):
color = np.random.randint(0, 256, size=3).tolist()
color_map.append(color)
return color_map

def overlay_multi_class_mask_on_image(image_path, mask_path, alpha=0.5):
image = cv2.imread(image_path)
mask = cv2.imread(mask_path, cv2.IMREAD_GRAYSCALE)

if image is None or mask is None:
print(f"无法读取图像或mask: {image_path}{mask_path}")
return

# 确保mask和图像大小一致
if image.shape[:2] != mask.shape:
mask = cv2.resize(mask, (image.shape[1], image.shape[0]), interpolation=cv2.INTER_NEAREST)

# 获取mask中存在的类别
unique_classes = np.unique(mask)
num_classes = len(unique_classes)

# 创建颜色映射表
color_map = create_color_map(num_classes)

# 创建一个彩色mask图像
color_mask = np.zeros_like(image)
for i, class_id in enumerate(unique_classes):
if class_id == 0: # 跳过背景(假设0是背景)
continue
color_mask[mask == class_id] = color_map[i]

# 将彩色mask与原始图像混合
blended_image = cv2.addWeighted(image, 1 - alpha, color_mask, alpha, 0)

return blended_image, color_map, unique_classes

def visualize_overlay_with_legend(image_path, mask_path, alpha=0.5):
result_image, color_map, unique_classes = overlay_multi_class_mask_on_image(image_path, mask_path, alpha)

if result_image is not None:
plt.figure(figsize=(10, 5))

# 显示带有标注的图像
plt.imshow(cv2.cvtColor(result_image, cv2.COLOR_BGR2RGB))
plt.title('Overlay Multi-Class Mask on Image')
plt.axis('off')

# 添加图例
patches = [plt.Rectangle((0, 0), 1, 1, fc=np.array(color)/255) for color in color_map]
classes = [f'Class {cls}' for cls in unique_classes if cls != 0] # 排除背景类
plt.legend(patches, classes, loc='upper right', bbox_to_anchor=(1.1, 1))
plt.show()

# 测试函数
if __name__ == "__main__":
image_path = r'D:\zlc\drone\drone-train\data\2021LoveDA\train\images\7.png' # 替换为你的图像路径
mask_path = r'D:\zlc\drone\drone-train\data\2021LoveDA\train\masks\7.png' # 替换为你的mask路径
visualize_overlay_with_legend(image_path, mask_path)
参考文章:
【1】.【图像分割_数据集】mask可视化(标签文件png全黑怎么办)
【2】.【可视化】图像分割中标签label与预测mask的两种可视化方法 第一种是标签label填充样覆盖,预测mask采用勾线描边的方式,勾线描边利用 c v 2 {cv2} cv2 中的 c v 2. t h r e s h o l d {cv2.threshold} cv2.threshold、 c v 2. f i n d C o n t o u r s {cv2.findContours} cv2.findContours 和 c v 2. d r a w C o n t o u r s {cv2.drawContours} cv2.drawContours 函数。第二种是利用不用的颜色均采用勾线描边的方式, c v 2. d r a w C o n t o u r s {cv2.drawContours} cv2.drawContours 自带 hold on 功能,只需两个循环就搞定啦~
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 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.
幸福是年华的沉淀,微笑是寂寞的悲伤。