Python|遥感影像语义分割:使用Python(GDAL)制作遥感影像语义分割数据集

遥感影像标注

使用ArcGIS Pro标注得到标签图标注对象以供深度学习使用—ArcGIS Pro | 文档,由于我的任务是二分类任务,因此我得到的标签图是一张二值图,如下图所示。

image-20240707112134453

使用python滑动裁剪图像及标签

采用分块裁剪策略,将大区域影像分割成256256像素的块,并采用滑动窗口技术,步长为窗口宽度的一半,块间存在50%的重叠。裁剪自影像左上角开始,按顺序进行,如下图所示。同时标注数据也按此策略同步处理,保证数据集的有效性和样本量的增加。

image-20240707111240437

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)
posted @ 2024-07-07 11:33  Weltㅤ  阅读(100)  评论(0编辑  收藏  举报