遥感影像批量裁剪(语义分割样本制作)

文章目录

  • 前言
  • 一、实现思路
  • 二、使用步骤
    • 1.引入库
    • 2.裁剪函数
    • 3.引用函数裁剪
  • 总结


前言

        前不久遇到一个需求,即对遥感影像进行批量裁剪。其实这个需求在arcgis中等一些gis软件中就可以实现,但是吧,他需要手动点比较麻烦,而且中间还生成一些我并不需要的其他文件(.tfw等等)。基于此,我就想这个能不能自己用python写一个程序实现批量裁剪,且不生成其他文件。说干就干,详见下文.


一、实现思路?

       其实我主要基于gdal以及numpy和os实现的。gdal是一个开源的图像处理库,主要用于读取、写入和处理地理空间数据。numpy是一个用于科学计算的Python库,可以用来进行数据处理、数值计算、线性代数、随机数生成等操作。os库就不详细介绍了,标准库。

二、使用步骤

1.引入库

from osgeo import gdal, gdalconst
import numpy as np
import os

2.裁剪函数

     代码如下:这里介绍一下几个参数:

     input_tiff:需要裁剪的tif路径

     output_folder:裁剪的小图需要保存的文件夹路径

     tile_size_x:裁剪小图的宽

     tile_size_y:裁剪小图的长

     name:裁剪小图的名称

def crop_images_tiff(input_tiff, output_folder, tile_size_x, tile_size_y, name):
    # 打开输入的TIFF文件
    input_ds = gdal.Open(input_tiff, gdalconst.GA_ReadOnly)

    # 获取输入TIFF的基本信息
    width = input_ds.RasterXSize
    height = input_ds.RasterYSize
    projection = input_ds.GetProjection()

    # 计算水平和垂直方向上分别有多少个tile
    if width % tile_size_x == 0:
        num_tiles_x = width // tile_size_x
    else:
        num_tiles_x = width // tile_size_x + 1
    if height % tile_size_y == 0:
        num_tiles_y = height // tile_size_y
    else:
        num_tiles_y = height // tile_size_y + 1
    # 创建输出文件夹
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    for i in range(num_tiles_x):
        for j in range(num_tiles_y):
            # 计算当前tile的偏移
            offset_x = i * tile_size_x
            offset_y = j * tile_size_y
            if offset_x + tile_size_x >= width:
                tile_size_x_ = width - offset_x
            else:
                tile_size_x_ = tile_size_x
            if offset_y + tile_size_y >= height:
                tile_size_y_ = height - offset_y
            else:
                tile_size_y_ = tile_size_y
            # 读取tile数据
            tile_data = input_ds.ReadAsArray(offset_x, offset_y, tile_size_x_, tile_size_y_)
            # 将小于0的值变为0
            tile_data[tile_data <= 0] = 0
            # 使用nan_to_num函数将NaN值替换为0
            tile_data = np.nan_to_num(tile_data, nan=0.0)
            tile_data = tile_data[:3, :, :]
            print(tile_data.shape)

            # 创建输出文件
            output_tiff = os.path.join(output_folder, name+f'_{i}_{j}.TIF')
            output_ds = gdal.GetDriverByName('GTiff').Create(output_tiff, tile_size_x_, tile_size_y_, 3, gdalconst.GDT_Byte)

            # 设置投影坐标信息
            output_ds.SetProjection(projection)

            # 计算新的地理坐标信息
            geo_transform = list(input_ds.GetGeoTransform())
            geo_transform[0] = geo_transform[0] + offset_x * geo_transform[1]
            geo_transform[3] = geo_transform[3] + offset_y * geo_transform[5]
            output_ds.SetGeoTransform(tuple(geo_transform))

            # 将tile数据写入输出文件
            for band in range(3):
                output_ds.GetRasterBand(band+1).WriteArray(tile_data[band, :, :])

            # 关闭输出文件
            output_ds = None

    # 关闭输入文件
    input_ds = None

3.引用函数裁剪

if __name__ == "__main__":
    # image.tif路径
    input_folder1 = r'images.tif'
    # 输出images文件夹路径(保存裁剪后的图像)
    output_folder1 = r'images'

    dir1 = os.path.exists(output_folder1)
    if dir1 != True:
        os.makedirs(output_folder1)
    print('正在裁剪image...')
    crop_images_tiff(input_folder1, output_folder1, 512, 512, 'image')

总结

通过gdal以及numpy实现了图像批量裁剪功能。有需要的可以参考用一下。

你可能感兴趣的:(python,python,计算机视觉,arcgis)