Python|遥感影像语义分割:使用Python(GDAL)制作遥感影像语义分割数据集
遥感影像标注
使用ArcGIS Pro标注得到标签图标注对象以供深度学习使用—ArcGIS Pro | 文档,由于我的任务是二分类任务,因此我得到的标签图是一张二值图,如下图所示。
使用python滑动裁剪图像及标签
采用分块裁剪策略,将大区域影像分割成256256像素的块,并采用滑动窗口技术,步长为窗口宽度的一半,块间存在50%的重叠。裁剪自影像左上角开始,按顺序进行,如下图所示。同时标注数据也按此策略同步处理,保证数据集的有效性和样本量的增加。
Python代码
import os
from osgeo import gdal
import numpy as np
# 读取tif数据集
def readTif(fileName):
dataset = gdal.Open(fileName)
if dataset is None:
print(fileName + "文件无法打开")
return dataset
# 保存tif文件函数
def writeTiff(im_data, im_geotrans, im_proj, path):
if 'int8' in im_data.dtype.name:
datatype = gdal.GDT_Byte
elif 'int16' in im_data.dtype.name:
datatype = gdal.GDT_UInt16
else:
datatype = gdal.GDT_Float32
if len(im_data.shape) == 3:
im_bands, im_height, im_width = im_data.shape
elif len(im_data.shape) == 2:
im_data = np.array([im_data])
im_bands, im_height, im_width = im_data.shape
# 创建文件
driver = gdal.GetDriverByName("GTiff")
dataset = driver.Create(path, int(im_width), int(im_height), int(im_bands), datatype)
if dataset is not None:
dataset.SetGeoTransform(im_geotrans) # 写入仿射变换参数
dataset.SetProjection(im_proj) # 写入投影
for i in range(im_bands):
dataset.GetRasterBand(i + 1).WriteArray(im_data[i])
del dataset
def TifCrop(TifPath, SavePath, CropSize, RepetitionRate):
"""
滑动窗口裁剪函数
TifPath 影像路径
SavePath 裁剪后保存目录
CropSize 裁剪尺寸
RepetitionRate 重复率
"""
dataset_img = readTif(TifPath)
width = dataset_img.RasterXSize
height = dataset_img.RasterYSize
proj = dataset_img.GetProjection()
geotrans = dataset_img.GetGeoTransform()
img = dataset_img.ReadAsArray(0, 0, width, height) # 获取数据
# 获取当前文件夹的文件个数len,并以len+1命名即将裁剪得到的图像
new_name = len(os.listdir(SavePath))
# 裁剪图片,重复率为RepetitionRate
for i in range(int((height - CropSize * RepetitionRate) / (CropSize * (1 - RepetitionRate)))):
for j in range(int((width - CropSize * RepetitionRate) / (CropSize * (1 - RepetitionRate)))):
# 如果图像是单波段
if len(img.shape) == 2:
cropped = img[
int(i * CropSize * (1 - RepetitionRate)): int(i * CropSize * (1 - RepetitionRate)) + CropSize,
int(j * CropSize * (1 - RepetitionRate)): int(j * CropSize * (1 - RepetitionRate)) + CropSize]
# 如果图像是多波段
else:
cropped = img[:,
int(i * CropSize * (1 - RepetitionRate)): int(i * CropSize * (1 - RepetitionRate)) + CropSize,
int(j * CropSize * (1 - RepetitionRate)): int(j * CropSize * (1 - RepetitionRate)) + CropSize]
# 写图像
writeTiff(cropped, geotrans, proj, SavePath + "/%d.tif" % new_name)
# 文件名 + 1
new_name = new_name + 1
# 向前裁剪最后一列
for i in range(int((height - CropSize * RepetitionRate) / (CropSize * (1 - RepetitionRate)))):
if len(img.shape) == 2:
cropped = img[int(i * CropSize * (1 - RepetitionRate)): int(i * CropSize * (1 - RepetitionRate)) + CropSize,
(width - CropSize): width]
else:
cropped = img[:,
int(i * CropSize * (1 - RepetitionRate)): int(i * CropSize * (1 - RepetitionRate)) + CropSize,
(width - CropSize): width]
# 写图像
writeTiff(cropped, geotrans, proj, SavePath + "/%d.tif" % new_name)
new_name = new_name + 1
# 向前裁剪最后一行
for j in range(int((width - CropSize * RepetitionRate) / (CropSize * (1 - RepetitionRate)))):
if len(img.shape) == 2:
cropped = img[(height - CropSize): height,
int(j * CropSize * (1 - RepetitionRate)): int(j * CropSize * (1 - RepetitionRate)) + CropSize]
else:
cropped = img[:, (height - CropSize): height,
int(j * CropSize * (1 - RepetitionRate)): int(j * CropSize * (1 - RepetitionRate)) + CropSize]
writeTiff(cropped, geotrans, proj, SavePath + "/%d.tif" % new_name)
# 文件名 + 1
new_name = new_name + 1
# 裁剪右下角
if len(img.shape) == 2:
cropped = img[(height - CropSize): height, (width - CropSize): width]
else:
cropped = img[:, (height - CropSize): height, (width - CropSize): width]
writeTiff(cropped, geotrans, proj, SavePath + "/%d.tif" % new_name)
new_name = new_name + 1
# 训练集和验证集都要裁剪
# 裁剪图像特征。拿到影像数据增强中进行数据增强
# 将影像1裁剪为重复率为0.5的256×256的数据集
if __name__ == '__main__':
TifCrop("D:\Dataset_Authoring\EnShi.tif",
"D:\Dataset_Authoring\EnShi_data", 512, 0.5)