Python遥感开发之变异系数

1 什么是变异系数

变异系数是衡量观测值与单位均 值 离散程度 的一 个统计量,标准差与均值的比值为变异系数 。其变异系数越大,说明NDVI/EVI/NPP/NEP/GPP时间序列数据波动比较大 ,时序不稳定; 反之, 说明指标时间序列数据波动比较小,时序稳定。

公式如下:

2 代码实现变异系数

python 复制代码
import numpy as np
import os
from osgeo import gdal

def read_tif(filepath):
    dataset = gdal.Open(filepath)
    col = dataset.RasterXSize  # 图像长度
    row = dataset.RasterYSize  # 图像宽度
    geotrans = dataset.GetGeoTransform()  # 读取仿射变换
    proj = dataset.GetProjection()  # 读取投影
    data = dataset.ReadAsArray()  # 转为numpy格式
    data = data.astype(np.float32)
    no_data_value = data[0][0]  # 设定NoData值
    data[data == no_data_value] = np.nan  # 将NoData转换为NaN
    return col, row, geotrans, proj, data

def save_tif(data, reference_file, output_file):
    ds = gdal.Open(reference_file)
    shape = data.shape
    driver = gdal.GetDriverByName("GTiff")
    dataset = driver.Create(output_file, shape[1], shape[0], 1, gdal.GDT_Float32)  # 保存的数据类型
    dataset.SetGeoTransform(ds.GetGeoTransform())
    dataset.SetProjection(ds.GetProjection())
    dataset.GetRasterBand(1).WriteArray(data)
    dataset.FlushCache()

def get_tif_list(directory):
    """
    获取目录下所有TIF文件的完整路径
    """
    return [os.path.join(directory, f) for f in os.listdir(directory) if f.endswith('.tif')]


def coefficient_of_variation(data): # 变异系数
    mean = np.mean(data) # 计算平均值
    std = np.std(data, ddof=0) # 计算标准差
    cv = std/mean
    return cv

if __name__ == '__main__':
    # 输入文件夹路径
    input_directory = r"E:\AAWORK\02-处理\ndvi-86-24"
    output_directory = r"E:\AAWORK\03-结果\01时空分析\cv"

    # 读取文件列表
    file_list = get_tif_list(input_directory)
    # 读取第一个文件获取基本信息(列、行、仿射变换、投影)
    col, row, geotrans, proj, _ = read_tif(file_list[0])
    # 预分配结果数组
    cv_data = np.zeros((row, col), dtype=np.float32)
    # 将所有 TIFF 文件的数据堆叠为一个三维数组 (时间, 行, 列)
    tif_stack = np.array([read_tif(f)[4] for f in file_list])
    # 遍历每个像素
    for i in range(row):
        print(f"Processing row {i+1}/{row}...")
        for j in range(col):
            pixel_values = tif_stack[:, i, j]  # 取出所有时间点的该像素值
            if not np.any(np.isnan(pixel_values)):  # 过滤掉包含NaN的像素
                CV_value = coefficient_of_variation(pixel_values)  # 变异系数计算
                cv_data[i, j] = CV_value
    # 输出文件路径
    save_tif(cv_data, file_list[0], os.path.join(output_directory, 'cv.tif'))
    print("Processing completed!")

3 变异系数分等级

分类参考某论文

python 复制代码
import numpy as np
from osgeo import gdal

def read_tif(filepath):
    dataset = gdal.Open(filepath)
    col = dataset.RasterXSize#图像长度
    row = dataset.RasterYSize#图像宽度
    geotrans = dataset.GetGeoTransform()#读取仿射变换
    proj = dataset.GetProjection()#读取投影
    data = dataset.ReadAsArray()#转为numpy格式
    data = data.astype(np.float32)
    a = data[0][0]
    data[data == a] = np.nan
    return [col, row, geotrans, proj, data]

def save_tif(data, file, output):
    ds = gdal.Open(file)
    shape = data.shape
    driver = gdal.GetDriverByName("GTiff")
    dataset = driver.Create(output, shape[1], shape[0], 1, gdal.GDT_Int16)#保存的数据类型
    dataset.SetGeoTransform(ds.GetGeoTransform())
    dataset.SetProjection(ds.GetProjection())
    dataset.GetRasterBand(1).WriteArray(data)

if __name__ == '__main__':
    # 调用
    cv_path = r"E:\AAWORK\03-结果\01时空分析\cv\cv01.tif"
    output_path = r"E:\AAWORK\03-结果\01时空分析\cv\cv_level.tif"
    col, row, geotrans, proj, cv_data = read_tif(cv_path)
    classified = np.zeros_like(cv_data, dtype=np.int16)
    classified[(cv_data > 0) & (cv_data < 0.05)] = 1
    classified[(cv_data >= 0.05) & (cv_data < 0.1)] = 2
    classified[(cv_data >= 0.1) & (cv_data < 0.15)] = 3
    classified[(cv_data >= 0.15) & (cv_data < 0.2)] = 4
    classified[(cv_data >= 0.2)] = 5
    save_tif(classified,cv_path,output_path)
相关推荐
等待着冬天的风1 年前
Python遥感开发之地理探测器的实现
python遥感开发·python地理探测器