Python实现遥感生态指数计算

最近在做一些遥感相关的图像处理项目,涉及到遥感生态指数的计算。由于项目要求Python实现,搜索互联网关于Python实现的遥感生态指数计算程序资料很少,于是就自己实现了一个并分享在这里,供需要的朋友参考。
首先需要了解遥感生态指数是什么,不是很清楚的朋友可以参考下面的几篇文章:
城市遥感生态指数的创建及其应用
区域生态环境变化的遥感评价指数
基于遥感生态指数的南京市生态变化分析
知道了遥感生态指数是什么后,程序实现其实比较简单,这里直接贴出程序。

"""
利用湿度、绿度、热度、干度计算遥感生态指数
"""
import os
import time
import numpy as np
from scipy import misc
from osgeo import gdal, gdalconst
from sklearn.decomposition import PCA


class CalIntegratedEcoIndex:

    def __init__(self, img_path, res_save_dir):
        self.img_width, self.img_height, self.img = self.read_img(img_path)
        self.deno_bias = 0.00001  # 分母偏置,防止除0
        self.res_save_dir = res_save_dir

    def read_img(self, img_path):
        """读取遥感数据信息"""
        dataset = gdal.Open(img_path, gdalconst.GA_ReadOnly)

        img_width = dataset.RasterXSize
        img_height = dataset.RasterYSize
        img_data = np.array(dataset.ReadAsArray(0, 0, img_width, img_height), dtype=float)  # 将数据写成数组,对应栅格矩阵

        del dataset

        return img_width, img_height, img_data

    def get_wet_degree(self):
        """获取湿度指标"""
        return 0.2626 * self.img[0] + 0.2141 * self.img[1] + 0.0926 * self.img[2] + \
              0.0656 * self.img[3] - 0.7629 * self.img[4] - 0.5388 * self.img[6]

    def get_green_degree(self):
        """获取绿度指标"""
        return (self.img[3] - self.img[2]) / (self.img[3] + self.img[2] + self.deno_bias)

    def get_temperature(self):
        """获取热度指标"""
        gain = 3.20107  # landsat5 第6波段的增益值
        bias = 0.25994  # 第6波段的偏置值

        K1 = 606.09
        K2 = 1282.71
        _lambda = 11.45
        _rho = 1.438e10-2
        _epsilon = 0.96  # 比辐射率

        DN = self.img[4] * 299/1000 + self.img[3] * 587/1000 + self.img[2] * 114/1000  # 获取象元灰度值

        L6 = gain * DN + bias
        T = K2 / np.log(K1 / L6 + 1)
        LST = T / (1 + (_lambda * T / _rho) * np.log(_epsilon))

        return LST

    def get_dryness_degree(self):
        """获取干度指标"""
        band5_plus_band3 = self.img[4] + self.img[2]
        band4_plus_band1 = self.img[3] + self.img[0]

        SI = (band5_plus_band3 - band4_plus_band1) / (band5_plus_band3 + band4_plus_band1 + self.deno_bias)

        left_expr = 2 * self.img[4] / (self.img[4] + self.img[3] + self.deno_bias)
        right_expr = self.img[3] / (self.img[3] + self.img[2] + self.deno_bias) + \
                     self.img[1] / (self.img[1] + self.img[4] + self.deno_bias)
        IBI = (left_expr - right_expr) / (left_expr + right_expr + self.deno_bias)

        NDBSI = (IBI + SI) / 2

        return NDBSI

    def arr2img(self, save_path, arr):
        misc.imsave(save_path, arr)

    def normlize(self, img_arr):
        arr = np.array(img_arr)
        return (arr - arr.min()) / (arr.max() - arr.min())

    def get_rsei(self):
        """获取遥感生态指数"""
        wet = self.get_wet_degree()
        ndvi = self.get_green_degree()
        lst = self.get_temperature()
        ndbsi = self.get_dryness_degree()

        data = np.array([self.normlize(wet), self.normlize(ndvi), self.normlize(lst), self.normlize(ndbsi)])
        data = data.reshape(data.shape[0], -1).T

        pca = PCA(n_components=1)
        rsei = self.normlize(1 - np.reshape(pca.fit_transform(data), newshape=(self.img_height, self.img_width)))

        return wet, ndvi, lst, ndbsi, 1 - rsei

    def save_result(self, wet, ndvi, lst, ndbsi, rsei):
        """将各指数结果保存为图片"""
        res_dict = {"wet": wet, "green": ndvi, "temperature": lst, "dry": ndbsi, "rsei": rsei}

        for k, v in res_dict.items():
            self.arr2img(os.path.join(self.res_save_dir, k + ".jpg"), v)

    def get_average_index(self, wet, ndvi, lst, ndbsi, rsei):
        """获取归一化后各指标的平均值"""
        return np.mean(self.normlize(wet)), np.mean(self.normlize(ndvi)), \
               np.mean(self.normlize(lst)), np.mean(self.normlize(ndbsi)), np.mean(self.normlize(rsei))

程序可以按照下面的方式进行使用(注意输入图像是Landsat七波段的图像):

if __name__ == '__main__':
    start = time.time()
    cal = CalIntegratedEcoIndex("/your/path/to/Landsat/image", "./result")
    wet, ndvi, lst, ndbsi, rsei = cal.get_rsei()
    aver_wet, aver_ndvi, aver_lst, aver_ndbsi, aver_rsei = cal.get_average_index(wet, ndvi, lst, ndbsi, rsei)
    cal.save_result(wet, ndvi, lst, ndbsi, rsei)
    end = time.time()

    print("归一化后各指数的平均值\n湿度", aver_wet, "绿度", aver_ndvi, "热度", aver_lst, "干度", aver_ndbsi,
          "遥感生态指数", aver_rsei, "Total cost time %.2f s" % (end - start))

因为对遥感领域不很了解,这也是我的初次尝试。如果程序中有什么错误及不足,欢迎读者朋友们在评论区批评指正。

你可能感兴趣的:(遥感生态指数,生态变化,图像处理,Python,计算机视觉CV)