有时计算的结果常常存储在一个tiff文件中,波段太多,数据较大,查看不方便,将其分离成单波段文件可以便于查看。
这里以计算得到的SPEI数据为例,我的计算结果包含了2000-2022年逐月的数据结果,共264个波段,下面代码可以进行波段分离,并按年月进行命名
# 导入需要的库
import numpy as np # 处理数组和矩阵
import os # 操作文件和目录
from osgeo import gdal # 取和写入地理空间数据
import tifffile as tif # 读取和写入.tif格式文件
# 定义读取图像像素矩阵函数,其中fileName为图像文件名
def readTif(fileName):
dataset = gdal.Open(fileName) # 使用gdal库打开图像文件
return dataset # 返回数据集对象
# 定义保存tif文件函数
def writeTiff(im_data, im_geotrans, im_proj, path):
if 'int8' in im_data.dtype.name: # 判断数据类型是否为int8
datatype = gdal.GDT_Byte # 设置数据类型为Byte
elif 'int16' in im_data.dtype.name: # 判断数据类型是否为int16
datatype = gdal.GDT_UInt16 # 设置数据类型为UInt16
else:
datatype = gdal.GDT_Float32 # 设置数据类型为Float32
if len(im_data.shape) == 3: # 判断数据维度是否为3
im_bands, im_height, im_width = im_data.shape # 获取波段数、高度和宽度
elif len(im_data.shape) == 2: # 判断数据维度是否为2
im_data = np.array([im_data]) # 将数据转换为3维数组
im_bands, im_height, im_width = im_data.shape # 获取波段数、高度和宽度
driver = gdal.GetDriverByName("GTiff") # 获取GTiff驱动
dataset = driver.Create(path, int(im_width), int(im_height), int(im_bands), datatype) # 创建.tif文件
if (dataset != None):
dataset.SetGeoTransform(im_geotrans) # 写入仿射变换参数
dataset.SetProjection(im_proj) # 写入投影
for i in range(im_bands): # 遍历波段
dataset.GetRasterBand(i + 1).WriteArray(im_data[i]) # 将波段数据写入.tif文件
del dataset # 删除数据集对象
# 定义波段分离函数
def bandsclip(path1, output_dir):
dataset_img = readTif(path1) # 读取图像数据集
width = dataset_img.RasterXSize # 获取图像宽度
height = dataset_img.RasterYSize # 获取图像高度
proj = dataset_img.GetProjection() # 获取图像投影
geotrans = dataset_img.GetGeoTransform() # 获取图像仿射变换参数
img = dataset_img.ReadAsArray(0, 0, width, height) # 读取图像数据
for i in range(img.shape[0]): # 遍历波段
year = 2000 + i // 12 # 计算年份
month = i % 12 + 1 # 计算月份
output_filename = f"{output_dir}/SPEI_{year}_{month:02d}.tif" # 构建输出文件名,例如:SPEI_2000_01.tif
img_out = np.array(img[i, ::]) # 获取当前波段数据
writeTiff(img_out, geotrans, proj, output_filename) # 将波段数据保存为.tif文件
# 切换当前工作目录
os.chdir(r'D://work//SPEI')
path1 = r'D://work//spei_12.tif' # 要分离波段的原始图像数据名称
output_dir = r'./SPEI-12' # 分离的各波段结果图像保存目录
if not os.path.exists(output_dir):
os.makedirs(output_dir) # 如果保存目录不存在,则创建目录
bandsclip(path1, output_dir) # 调用波段分离函数
print('Bandsclip END!') # 打印输出