Gdal实现分割多波段遥感影像,16位颜色深度,高清遥感栅格分割

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驱动
    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
                
                # 创建临时文件名(用于中间TIFF文件)
                temp_filename = f"temp_{i}_{j}.tif"
                temp_path = os.path.join(output_dir, temp_filename)
                
                # 创建最终输出文件名(PNG格式)
                output_filename = f"tile_{i}_{j}.png"
                output_path = os.path.join(output_dir, output_filename)
                
                # 首先创建TIFF格式的切片,只选择前三个波段(RGB)
                translate_options = gdal.TranslateOptions(
                    format='GTiff',
                    srcWin=[x_start, y_start, x_size, y_size],
                    bandList=[1,2,3],  # 只选择前三个波段作为RGB
                    outputType=gdal.GDT_UInt16  # 保持16位深度
                )
                
                # 创建切片
                gdal.Translate(temp_path, dataset, options=translate_options)
                
                # 读取临时TIFF文件的统计信息以确定缩放范围
                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
                
                # 将TIFF转换为PNG,进行16位到8位的转换
                png_options = gdal.TranslateOptions(
                    format='PNG',
                    outputType=gdal.GDT_Byte,  # 8位输出
                    scaleParams=scales,  # 使用每个波段的实际范围进行缩放
                    exponents=[0.5, 0.5, 0.5],  # gamma校正,提高暗部细节
                    noData=None  # 不设置NoData值
                )
                
                # 转换为PNG
                gdal.Translate(output_path, temp_path, options=png_options)
                
                # 删除临时文件
                os.remove(temp_path)
                
                # 验证文件大小
                file_size = os.path.getsize(output_path) / (512 * 512)  # 转换为MB
                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"  # 输出目录
    
    # 执行切片,tile_size=512
    split_raster(input_tiff, output_directory, tile_size=512)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值