基于Python(Arcpy)对遥感影像(TIF)的Mann-Kendall算法突变检测实现

主体函数:

由多张影像先求每年的平均值,每年对应一个平均值,对这些值进行突变检测。

#coding=utf-8
import time
start = time.clock()
import arcpy
import math
import matplotlib.pyplot as plt
# 对每年的栅格数据求一个平均数值
def mean_year(workspace,zonal_mask):
    arcpy.env.workspace = workspace
    arcpy.env.overwriteOutput = True
    arcpy.CheckOutExtension("spatial")
    raster_list = arcpy.ListRasters("*","tif")
    name_table = "Temp_table"
    mean_ls = []
    if arcpy.Exists(name_table):
        arcpy.Delete_management(name_table)
    for raster in raster_list:
        #print raster
        arcpy.sa.ZonalStatisticsAsTable(in_zone_data=zonal_mask,\
                                        zone_field="name",\
                                        in_value_raster=raster,\
                                        out_table=name_table,\
                                        statistics_type="MEAN")
        cursor = arcpy.da.SearchCursor(name_table,["MEAN"])
        for row1 in cursor:
            mean = row1[0]
            #print mean
            mean_ls.append(mean)
    return mean_ls
# 计算UFK与UBK序列
def cal_UFKUBK(mean_ls):
    # 计算UFK 正序列计算完成
    s = 0
    # Sk = []
    UFk = []
    UFk.append(0)
    n = len(mean_ls)
    for i in range(1,n,1):
        for j in range(0,i,1):
            if mean_ls[i] > mean_ls[j]:
                s = s +1
            else:
                s = s + 0
        # Sk.append(s)
        ESk = (i+1)*(i)/4.0
        Var = (i+1)*i*(2*(i+1)+5)/72.0
        UF = (s-ESk)*1.0/math.sqrt(Var)
        UFk.append(UF)
    print UFk
    # 计算UBK 逆序列计算完成
    mean_lsT = list(reversed(mean_ls))
    s_T = 0
    UBk_T = []
    UBk_T.append(0)
    for i in range(1,n,1):
        for j in range(0,i,1):
            if mean_lsT[i] > mean_lsT[j]:
                s_T = s_T + 1
            else:
                s_T = s_T + 0
        ESk_T = (i + 1) * (i) / 4.0
        Var_T = (i + 1) * i * (2 * (i + 1) + 5) / 72.0
        UB_T = (s_T - ESk_T) * 1.0 / math.sqrt(Var_T)
        UBk_T.append(-1*UB_T)

    UBk = list(reversed(UBk_T))
    res_ls = []
    res_ls.append(UFk)
    res_ls.append(UBk)
    return res_ls
def cal_changePoint(res_ls,year_ls):
    # 找出突变点
    D = []
    change_point = []
    n = len(year_ls)
    for i in range(n):
        D.append(res_ls[0][i] - res_ls[1][i])
    for i in range(1, n, 1):
        if D[i - 1] * D[i] < 0:
            if math.fabs(D[i - 1]) > math.fabs(D[i]):
                change_point.append(i+year_ls[0])
            else:
                change_point.append(i - 1+year_ls[0])
    point = list(set(change_point))
    print "突变点为:"
    print point
    # 画出UFK与UBK的趋势图
    plt.plot(year_ls, res_ls[0], label="UFk", color="red")
    plt.plot(year_ls, res_ls[1], label="UBk", color="blue")

    x_lim = plt.xlim()
    plt.plot(x_lim, [-1.96, -1.96], "m--", color='r')
    plt.plot(x_lim, [0, 0], "m--")
    plt.plot(x_lim, [1.96, 1.96], "m--", color='r')

    plt.legend(loc="upper right")
    plt.ylabel("UFk-UBk")
    plt.show()
# 主函数
if __name__ == "__main__":
    path_tif = "F:/GPP_Temp/res_mean"
    zonal_mask = "F:/shp_water/china_water.shp"
    year_ls = []
    for year in range(1982,2016,1):
        year_ls.append(year)
    dt = mean_year(path_tif,zonal_mask)
    res_ls = cal_UFKUBK(dt)
    cal_changePoint(res_ls,year_ls)

总结:使用时把主函数中的数路径与年序列改成自己对应的。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值