如何使用Python GDAL API复现QGIS保存栅格为渲染图像的功能
实现逻辑
QGIS的「Save Raster as Rendered Image」功能核心是对原始GeoTIFF做三步处理:
- 对栅格像素值做值域拉伸(默认为2%累积截断拉伸,剔除异常极值后将剩余值域映射到0-255区间)
- 按需选择对应波段组合为RGB/A通道
- 导出为8位深度的常规图像格式
实现方式
方法1:GDAL命令行(适合快速批量处理)
直接使用gdal_translate命令即可完成转换,基础命令示例:
gdal_translate -of PNG -ot Byte -scale -b 1 -b 2 -b 3 输入文件.tif 输出文件.png
参数说明:
-of PNG:指定输出格式,可替换为JPEG、GTiff等你的模型支持的格式,需要保留地理信息可选择GTiff-ot Byte:设置输出位深为8位,匹配常规图像的位深要求-scale:默认将输入栅格的全局最小最大值线性映射到0-255,需要对齐QGIS默认的2%截断拉伸效果时,先通过gdalinfo -stats 输入文件.tif获取栅格的2%和98%分位值,将参数改为-scale 2%分位值 98%分位值 0 255即可-b 1 -b 2 -b 3:指定输入栅格的第1、2、3波段对应输出图像的R、G、B通道,可根据你的波段设置调整
方法2:GDAL Python API(适合集成到机器学习Python流程)
可以直接将转换逻辑嵌入你的数据预处理代码,示例代码如下:
from osgeo import gdal import numpy as np def render_geotiff_to_image(input_path, output_path, output_format='PNG', stretch_percent=2): # 打开输入GeoTIFF ds = gdal.Open(input_path) band_count = ds.RasterCount # 读取波段,默认取前3个波段作为RGB,可按需调整 arr_list = [] for i in range(1, min(band_count, 3)+1): band = ds.GetRasterBand(i) arr = band.ReadAsArray() # 计算拉伸上下限 min_val = np.percentile(arr, stretch_percent) max_val = np.percentile(arr, 100 - stretch_percent) # 截断+映射到0-255 arr_stretch = np.clip(arr, min_val, max_val) arr_stretch = ((arr_stretch - min_val) / (max_val - min_val) * 255).astype(np.uint8) arr_list.append(arr_stretch) # 合并通道 out_arr = np.dstack(arr_list) # 创建输出文件 driver = gdal.GetDriverByName(output_format) out_ds = driver.Create(output_path, ds.RasterXSize, ds.RasterYSize, len(arr_list), gdal.GDT_Byte) for i in range(len(arr_list)): out_ds.GetRasterBand(i+1).WriteArray(out_arr[:,:,i]) # 释放资源 out_ds = None ds = None # 调用示例 render_geotiff_to_image("输入.tif", "输出.png")
注意事项
若处理的是单波段栅格,只需调整波段选择参数,输出为单通道灰度图即可,不需要组合RGB通道。批量处理时遍历目标目录下的所有GeoTIFF文件,循环调用上述命令/函数即可。
内容的提问来源于stack exchange,提问作者Marco Conopio
相关产品推荐
相关产品推荐

