Gdal实现分割多波段遥感影像,16位颜色深度,高清遥感栅格分割
import os
from osgeo import gdal
import numpy as np
from pathlib import Path
def split_raster(input_path, output_dir, tile_size=512):
"""
使用GDAL将大型栅格文件切分成小块并保存为PNG格式
Args:
input_path (str): 输入栅格文件路径
output_dir (str): 输出目录
tile_size (int): 切片大小(像素)
"""
gdal.AllRegister()
os.makedirs(output_dir, exist_ok=True)
dataset = gdal.Open(input_path)
if dataset is None:
raise Exception(f"无法打开文件: {input_path}")
width = dataset.RasterXSize
height = dataset.RasterYSize
bands = dataset.RasterCount
band1 = dataset.GetRasterBand(1)
datatype = band1.DataType
projection = dataset.GetProjection()
geotransform = dataset.GetGeoTransform()
print(f"原始数据类型: {gdal.GetDataTypeName(datatype)}")
print(f"图像大小: {width}x{height}")
print(f"波段数量: {bands}")
x_tiles = int(np.ceil(width / tile_size))
y_tiles = int(np.ceil(height / tile_size))
print(f"将生成 {x_tiles}x{y_tiles} = {x_tiles * y_tiles} 个图块")
for i in range(x_tiles):
for j in range(y_tiles):
try:
x_start = i * tile_size
y_start = j * tile_size
x_size = min(tile_size, width - x_start)
y_size = min(tile_size, height - y_start)
if x_size < tile_size or y_size < tile_size:
continue
temp_filename = f"temp_{i}_{j}.tif"
temp_path = os.path.join(output_dir, temp_filename)
output_filename = f"tile_{i}_{j}.png"
output_path = os.path.join(output_dir, output_filename)
translate_options = gdal.TranslateOptions(
format='GTiff',
srcWin=[x_start, y_start, x_size, y_size],
bandList=[1,2,3],
outputType=gdal.GDT_UInt16
)
gdal.Translate(temp_path, dataset, options=translate_options)
temp_ds = gdal.Open(temp_path)
if temp_ds is None:
raise Exception("无法打开临时文件")
scales = []
for b in range(3):
band = temp_ds.GetRasterBand(b + 1)
min_val, max_val = band.ComputeRasterMinMax()
scales.append([min_val, max_val])
temp_ds = None
png_options = gdal.TranslateOptions(
format='PNG',
outputType=gdal.GDT_Byte,
scaleParams=scales,
exponents=[0.5, 0.5, 0.5],
noData=None
)
gdal.Translate(output_path, temp_path, options=png_options)
os.remove(temp_path)
file_size = os.path.getsize(output_path) / (512 * 512)
print(f"已保存: {output_filename} ({file_size:.2f}MB)")
except Exception as e:
print(f"处理图块 {i}_{j} 时出错: {str(e)}")
if os.path.exists(temp_path):
os.remove(temp_path)
continue
dataset = None
print("切片完成!")
if __name__ == "__main__":
input_tiff = r"your_tif_path\yaogan1.tiff"
output_directory = r"your_output_path\yg_png"
split_raster(input_tiff, output_directory, tile_size=512)