GDAL栅格数据重采样示例

前言

栅格重采样:不改变影像的空间范围/尺度,仅仅改变影像像元的分辨率和像元数量(分辨率和像元个数密切相关)

可参考文档

示例代码

"""
 数据重采样
"""
from osgeo import gdal, gdalconst
import os


def resampling(source_file, target_file, scale=1.0):
    """
      栅格影像重采样
    :param source_file: 源文件
    :param target_file: 输出影像
    :param scale: 像元缩放比例
    :return:
    """
    dataset = gdal.Open(source_file, gdalconst.GA_ReadOnly)
    # 波段数
    band_count = dataset.RasterCount

    if band_count == 0 or not scale > 0:
        print("Exception occur: band_count:%s"%band_count)
        return
    # 源栅格数据列数
    cols = dataset.RasterXSize 
    # 源栅格数据行数
    rows = dataset.RasterYSize 
    # 计算新的行列数
    cols = int(cols * scale)  
    rows = int(rows * scale)

    geotrans = list(dataset.GetGeoTransform())
    # print(dataset.GetGeoTransform())
    # 像元宽度变为原来的scale倍
    geotrans[1] = geotrans[1] / scale
    # 像元高度变为原来的scale倍
    geotrans[5] = geotrans[5] / scale
    # print(geotrans)

    if os.path.exists(target_file) and os.path.isfile(target_file):
        os.remove(target_file)

    band1 = dataset.GetRasterBand(1)
    data_type = band1.DataType
    target = dataset.GetDriver().Create(target_file, xsize=cols, ysize=rows, bands=band_count,eType=data_type)
    # 设置投影坐标
    target.SetProjection(dataset.GetProjection())
    # 设置地理变换参数
    target.SetGeoTransform(geotrans)
     # 针对每个波段,读取波段数据(重采样到指定分辨率)、写入输出文件对象
    for index in range(1, band_count + 1):

        # buf_xsize和buf_ysize:需要将影像读取到的缓存图片的宽和高,如果其与读取的原始影像宽高不一致,ReadAsArray方法会对其进行重采样
        # ReadAsArray底层调用C++接口_gdal_array.BandRasterIONumPy(band, bWrite, xoff, yoff, xsize, ysize, psArray, buf_type, resample_alg, callback, callback_data)
        data = dataset.GetRasterBand(index).ReadAsArray(buf_xsize=cols, buf_ysize=rows, resample_alg=gdalconst.GRIORA_NearestNeighbour)
        out_band = target.GetRasterBand(index)
        # 写入数据到新影像中
        out_band.WriteArray(data)
        # 把缓存数据写到硬盘
        out_band.FlushCache()
        # 计算统计信息
        out_band.ComputeBandStats(False)  
    del dataset
    del target


if __name__ == "__main__":

    scale = 0.05
    source_file = r"data\tif\ORI.tif"
    target_file = r"F:data\tif\RES_0p05.tif"
    resampling(source_file, target_file, scale=scale)

梳理

示例代码中重采样步骤在Dataset对象的ReadAsArray方法中完成,其底层调用C++的接口,当buf_xsize与buf_ysize与原数据集的宽高不一致,则会使用重采样方法(默认采用最近邻采样)将源影像缩放到(buf_xsize, buf_ysize)的大小。

验证重采样的正确性:

  1. 结果导向:分辨率是原来的$1/scale$倍;

  2. 结果导向:重采样 后文件大小约为原来文件大小的的$1/scale^2$。

  3. 可视化验证(定性)

  4. 重采样算法正确性验证(关键)

CoolCats
CoolCats
理学学士

我的研究兴趣是时空数据分析、知识图谱、自然语言处理与服务端开发