Python地理数据处理 十七:植被物候提取和分析(Savitzky-Golay)

2023-11-13

1. 引子

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import savgol_filter

np.set_printoptions(precision=0, suppress=True)

hist_equal = np.array([   0,    0,    0,    0,    2,    7,   13,   23,   35,   46,   56,   64,   72,   78,   82,   86,   89,   92,   95,   99,  102,  105,  108,  111,  113,  115,  117,  119,  121,  122,  124,  126,
 128,  129,  131,  133,  134,  136,  137,  139,  140,  142,  143,  145,  146,  148,  149,  151,  153,  155,  157,  159,  161,  163,  166,  168,  170,  172,  174,  175,  177,  178,  179,  180,
 181,  182,  182,  183,  184,  185,  185,  186,  187,  188,  189,  189,  190,  191,  192,  193,  193,  194,  195,  196,  197,  197,  198,  199,  200,  200,  201,  202,  202,  203,  204,  204,
 205,  205,  206,  207,  207,  208,  208,  209,  209,  210,  210,  211,  211,  212,  213,  213,  214,  214,  215,  215,  216,  216,  217,  217,  218,  218,  219,  219,  220,  221,  221,  222,
 222,  223,  224,  225,  225,  226,  227,  227,  228,  229,  230,  230,  231,  232,  233,  234,  235,  236,  236,  237,  238,  239,  239,  240,  241,  241,  242,  242,  243,  243,  244,  244,
 245,  245,  246,  246,  247,  247,  248,  248,  249,  249,  250,  250,  250,  251,  251,  251,  251,  251,  251,  251,  251,  251,  251,  251,  251,  251,  252,  252,  252,  252,  252,  252,
 252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  252,  253,
 253,  253,  253,  253,  253,  253,  253,  253,  253,  253,  253,  253,  253,  253,  254,  254,  254,  254,  254,  254,  254,  254,  254,  254,  254,  254,  254,  254,  254,  254,  254,  255])

# window_length即窗口长度:取值为奇数且不能超过len(x)。它越大,则平滑效果越明显;越小,则更贴近原始曲线。
# polyorder为多项式拟合的阶数:它越小,则平滑效果越明显;越大,则更贴近原始曲线
hist_equal_savg = savgol_filter(hist_equal, 90, 4)
x = np.arange(256)

fig, axes = plt.subplots(1, 1)

plt.plot(x, hist_equal, label = "hist")
plt.plot(x, hist_equal_savg, label = "Savitzky Golay")
plt.legend()
plt.show()

plt.show()

结果显示:

2. Savitzky-Golay滤波提取物候信息

在这里插入图片描述

import os
import math
import numpy as np
import pandas as pd
from osgeo import gdal
from datetime import datetime
from scipy.signal import savgol_filter

def jd_to_time(time):
    dt = datetime.strptime(time,'%Y%j').date()
    fmt = '%Y%m%d'
    return dt.strftime(fmt)

def readTif(filename):
    dataset = gdal.Open(filename)
    if dataset == None:
        print(filename + "文件无法打开")
    return dataset

def writeTiff(img, img_geotrans, img_proj, path):
    if 'int8' in img.dtype.name:
        datatype = gdal.GDT_Byte
    elif 'int16' in img.dtype.name:
        datatype = gdal.GDT_UInt16
    else:
        datatype = gdal.GDT_Float32
    if len(img.shape) == 3:
        img_bands, img_height, img_width = img.shape
    elif len(img.shape) == 2:
        img = np.array([img])
        img_bands, img_height, img_width = img.shape
    # 创建文件
    driver = gdal.GetDriverByName("GTiff")
    dataset = driver.Create(path, int(img_width), int(img_height), int(img_bands))
    if(dataset != None):
        dataset.SetGeoTransform(img_geotrans)# 写入仿射变换参数
        dataset.SetProjection(img_proj)#写入投影
    
    for i in range(img_bands):
        dataset.GetRasterBand(i+1).WriteArray(img[i])
        del dataset

def SG_filter(tifFolder, suffix, efolder):
    '''
    
    tifFolder:tif所在文件夹
    suffix:生成结果文件后缀
    
    '''
    # 获取文件夹内的文件名
    tifNameList = os.listdir(tifFolder)
    phe = []
    for p in tifNameList:
        pt = os.path.splitext(p)[0]  # 获取tiff图像的文件名
        pt = int(pt[10:])
        phe.append(pt)
      
    # 获取第一张TIFF图像的信息:宽度、高度、投影、坐标系
    tifPath = tifFolder + "/" + tifNameList[0]
    dataset = readTif(tifPath)    # 获取第一个tiff图像文件信息
    width = dataset.RasterXSize   # 栅格矩阵的列数
    height = dataset.RasterYSize  # 栅格矩阵的行数
    Tif_geotrans = dataset.GetGeoTransform()
    Tif_proj = dataset.GetProjection()
    Tif_data = dataset.ReadAsArray(0, 0, width, height)
    Tif_datas = np.zeros((len(tifNameList),Tif_data.shape[0], Tif_data.shape[1])) # 多张TIFF数据保存到 Tif_datas中
    
    for i in range(len(tifNameList)):
        tifPath = tifFolder + "/" +tifNameList[i]
        dataset = readTif(tifPath)
        Tif_data = dataset.ReadAsArray(0, 0, width, height)
        Tif_datas[i] = Tif_data
        
    # 切换维度:宽、高、图像个数
    # [0,1,2]->[1,0,2]->[1,2,0]类似于汉诺塔[宽,高,46]
    Tif_datas = Tif_datas.swapaxes(1, 0)
    Tif_datas = Tif_datas.swapaxes(1, 2)
    #定义空集合
    SGfilter = np.zeros(Tif_datas.shape)
    sos = np.zeros(Tif_data.shape)
    eos = np.zeros(Tif_data.shape)
 
    # 读取每张图像的信息,所有图像相同位置的计算
    for i in range(Tif_datas.shape[0]):  # 行
        for j in range(Tif_datas.shape[1]): # 列
            value = Tif_datas[i][j]
            m = 0
            for k in value:
                if math.isnan(k) == True: # 空值判断,若有空值,则不计算该像素(全部图像的该像素)
                    m = m+1
                if m == 0:
                    sif = Tif_datas[i][j]
                    sif = pd.DataFrame(sif)
                    sif[sif<0] = 0
                    sif[sif>32766] = 0
                    sif = sif * 0.0001
                    sif = sif.values.flatten()
                    SGfilter[i][j] = savgol_filter(sif, window_length = 9, polyorder = 3) # 拟合阶数为3
                    ysg = SGfilter[i][j]
                    _y2 = list(ysg)
                    maxy = max(_y2)
                    miny = min(_y2)
                    th = 0.2    # 设置阈值
                    amplitude = maxy - miny    # 振幅
                    thresh = amplitude * th + miny
                    newnums = list(filter(lambda x: x >= thresh, _y2))
                    r = newnums[0]
                    r2 = newnums[-1]
                    index1 = _y2.index(r)
                    index2 = _y2.index(r2)
                    sos[i][j] = phe[index1]
                    eos[i][j] = phe[index2]
        
    sos[np.where(sos == 1)] = np.NAN
    sos[np.where(eos == 1)] = np.NAN
    savePaths = efolder + "sos.tif"
    savePathe = efolder + "eos.tif"
    writeTiff(sos, Tif_geotrans, Tif_proj, savePaths)
    writeTiff(eos, Tif_geotrans, Tif_proj, savePathe)
    
    # 维度还原为原来的维度
    SGfilter = SGfilter.swapaxes(1,0)
    SGfilter = SGfilter.swapaxes(0,2)
    for i in range(SGfilter.shape[0]):
        savePath = os.path.splitext(tifNameList[i])[0] + suffix + ".tif"
        savePath = efolder + savePath
        writeTiff(SGfilter[i], Tif_geotrans, Tif_proj, savePath)

数据导入:

np.random.seed(10)
import time
start = time.time()

SG_filter(r"E:/dataset/sif/2008sif_SG", "_SGFilter", "E:/dataset/sif/2008sifphe/")

end = time.time()
print(end - start)      

结果显示:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python地理数据处理 十七:植被物候提取和分析(Savitzky-Golay) 的相关文章

随机推荐

  • TensorFlow之双隐含层多层感知器(MLP)

    程序改自上一篇博客 使用了双隐含层 第二层隐含层初始w需要和第一层类似 否则程序正确率一直在0 1左右 修改后的程序正确率也在98 左右 coding utf 8 from tensorflow examples tutorials mni
  • 整理一些windows的bat命令及语法

    ver 在DOS窗口下显示版本信息 winver 弹出一个窗口显示版本信息 内存大小 系统版本 补丁版本 计算机名 format 盘符 FS 类型 格式化磁盘 类型 FAT FAT32 NTFS 例 Format D FS NTFS md
  • python基础系列之元组

    元组应用场景 储存多个数据 但是这些数据不可修改 我们知道列表可以储存多个数据 但是数据可增加 修改 删除 这也是元组和列表不一样的地方 如何定义一个元组 多个数据元组 t1 10 20 30 单个数据元组 t2 10 注意在定义单个数据的
  • 常量表达式函数

    我们可以在函数返回类型前加入关键字constexpr来使其成为常量表达式函数 但并非所有的函数都有资格成为常量表达式函数 事实上 常量表达式函数的要求非常严格 总结如下 函数体只有单一的return返回语句 函数必须返回值 不能是void函
  • 合并排序-递归分治

    按我的想法 简单地说 合并排序的思路就是 先递归 后排序 include
  • Java中的运算符

    1 算术运算符 基本四则运算符 1 规则比较简单 需要注意的是除法 int int 的结果还是 int 要想结果中有小数需要使用 double 类型 0 不能用来做除数 2 在Java中 表示取余 不仅可以对 int 求模 也可以对 dou
  • Tomcat Server处理一个http请求的过程

    Tomcat Server处理一个http请求的过程 假设来自客户的请求为 http localhost 8080 wsota wsota index jsp 1 请求被发送到本机端口8080 被在那里侦听的Coyote HTTP 1 1
  • 爬虫逆向实战(13)-某课网登录

    一 数据接口分析 主页地址 某课网 1 抓包 通过抓包可以发现登录接口是user login 2 判断是否有加密参数 请求参数是否加密 通过查看 载荷 模块可以发现有一个password加密参数 还有一个browser key这个可以写死不
  • C++ Pat甲级1013 Battle Over Cities (25 分)(求图的连通分量dfs)

    1013 Battle Over Cities 25 分 It is vitally important to have all the cities connected by highways in a war If a city is
  • 数字SOC设计之低功耗设计入门(六)——门级电路低功耗设计优化

    三 门级电路低功耗设计优化 1 门级电路的功耗优化综述 门级电路的功耗优化 Gate Level Power Optimization 简称GLPO 是从已经映射的门级网表开始 对设计进行功耗的优化以满足功耗的约束 同时设计保持其性能 即满
  • 【STM32篇】驱动MXL90614红外测温模块

    本次实验使用的测温模块型号GY 906 DCC模块 测距为10cm左右 一 简介 MLX90614 是一款红外非接触温度计 TO 39 金属封装里同时集成了红外感应热电堆探测器芯片和信处理专用集成芯片 由于集成了低噪声放大器 17 位模数转
  • 文件读/写操作 import pickle

    文件写 开 文件变量 open 文件路径文件名 web 存 pickle dump 待写入的变量 文件变量 关 文件变量 close 文件读 开 文件变量 open 文件路径文件名 rb 取 放内容的变量 pickle load 文件变量
  • 小程序 -- 分包

    来源 1 什么是分包 分包指的是把一个完整的小程序项目 按照需求划分为不同的子包 在构建时打包成不同的分包 用户在使用时按需进行加载 2 分包的好处 对小程序进行分包的好处主要有以下两点 可以优化小程序首次启动的下载时间 在多团队共同开发时
  • 二叉树之层次遍历(js)

    二叉树之层次遍历 输入一棵二叉树 你的任务是从上到下 从左到右的顺序输出各个结点的值 每个结点都是按照从根节点到它移动序列给出 L表示左 R表示右 在输入中 每个结点的左右括号之间没有空格 相邻节点之间用一个空格隔开 输入 11 LL 7
  • GameFi 大爆发?五款令人期待的链游

    大家好 我是晴天defi 在今年 有许多游戏公司陆续推出自家的IP大作 像是任天堂出的宝可梦 阿尔宙斯 Sony 的地平线 西域禁地 Techland 的垂死之光 2 就连那位喜欢虐待玩家的宫崎英高 也跟着推出他的全新虐待新作 艾二登 法环
  • Qt使用QGraphicsView实现滑动窗体效果 .

    源码已上传至CSDN http download csdn net source 2808505 QGraphicsView用来显示一个滚动视图区的QGraphicsScene内容 QGraphicsScene提供了QGraphicsIte
  • 深入理解mongodb和hbase区别

    最近公司想要做数据分析 之前我们公司用的是免费的growing IO 他们分析仅限于界面跳转的转化率 不能详细地分析业务数据 我研究了一个需要埋点的产品 搞明白他们是在每个接口的调用埋点 将用户对接口的调用行为记录下来 进行分析 由于接口众
  •  Linux下读写文件操作

    Linux下读写文件操作 include
  • Error: Could not create the Java Virtual Machine. Error: A fatal exception h.....

    我处理的问题的方法 换成8解决的
  • Python地理数据处理 十七:植被物候提取和分析(Savitzky-Golay)

    Savitzky Golay滤波 1 引子 2 Savitzky Golay滤波提取物候信息 1 引子 import numpy as np import matplotlib pyplot as plt from scipy signal