GEE基于Landsat 8数据反演绿度/热度/湿度/干度,并计算生态遥感指数代码分享

2022-09-20 13:05:25 浏览数 (1)

本期也是GEE的时间,细心的朋友会发现,开了赞赏功能,每天都是干货,还不赏我一瓶啤酒?那么,本期分享如何用GEE基于Landsat 8数据反演绿度/热度/湿度/干度,并计算生态遥感指数,代码较长,如有不妥之处,后台私信即可。

代码语言:javascript复制
//导入自己的研究区,将其定义为roi
var star_date = '2018-01-01'//定义起始时间
var end_date = '2018-12-30'//定义终止时间
var L8_SR = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR")//加载L8_SR影像
var img_SR = L8_SR.filterBounds(roi)
           .filterDate(star_date, end_date)
           .filterMetadata('CLOUD_COVER', 'less_than',50)
          .mean()//按照条件进行筛选
           
//归一化函数
var img_normalize = function(img){
      var minMax = img.reduceRegion({
            reducer:ee.Reducer.minMax(),
            geometry: roi,
            scale: 100,
            maxPixels: 10e13,
            tileScale: 16
        })
      var year = img.get('year')
      var normalize  = ee.ImageCollection.fromImages(
            img.bandNames().map(function(name){
                  name = ee.String(name);
                  var band = img.select(name);
                  return band.unitScale(ee.Number(minMax.get(name.cat('_min'))), ee.Number(minMax.get(name.cat('_max'))));
                    
              })
        ).toBands().rename(img.bandNames());
        return normalize;
} 

// Load the image of landsat 8 data

var vizParams = {bands: ['B5', 'B4', 'B3'], min: 50, max: 1500, gamma: [0.95,1.1,1]};

var images = img_SR.clip(roi);

var thermal = images.select('B10').multiply(0.1)

var Emissivity = function(image, nir, red, min, max, de) {
  min = min || 0.2
  max = max || 0.5
  de = de || 0.005
  
  var ndvi_e = "(nir-red)/(nir red)"
  var ndvi =  ee.Image(0).expression(ndvi_e, {'nir': image.select(nir), 'red': image.select(red)}).rename('ndvi')
  
  var pv = ee.Image(0).expression("((ndvi-min)/(max-min))**2", {ndvi: ndvi, min: min, max: max})
  
  var exp = "ndvi < 0.2 ? 0.979 - (0.046 * b4) : 0.2 <= ndvi <= 0.5 ? (0.987 * pv)   0.971 * (1 - pv)   de : 0.987   de"
  
  return ee.Image(0).expression(exp, {ndvi: ndvi, b4: image.select(red).multiply(0.0001), pv: pv, de: de}).rename('EM')
}

var EMM1 = Emissivity(img_SR, 'B5', 'B4')
var EMM = EMM1.clip(roi);



//LST计算
var LST = thermal.expression(
    '(Tb/(1   (0.0010904 * (Tb / 1.438))*log(Ep)))-273.15', {
      'Tb': thermal.select('B10'),
      'Ep': EMM.select('EM'),
     
});
 LST = img_normalize(LST)
img_SR = img_SR.addBands(LST.rename('LST').toFloat())
var SR_LST= img_SR.select('LST')

// 去云函数 
function removeCloud(image){
  var qa = image.select('BQA')
  var cloudMask = qa.bitwiseAnd(1 << 4).eq(0)
  var cloudShadowMask = qa.bitwiseAnd(1 << 8).eq(0)
  var valid = cloudMask.and(cloudShadowMask)
  return image.updateMask(valid)
}
var L8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
var img = L8.filterBounds(roi)
           .filterDate(star_date, end_date)
           .filterMetadata('CLOUD_COVER', 'less_than',50)
           .map(removeCloud).mean()
           
//计算NDVI

var ndvi = img.normalizedDifference(['B5', 'B4']);
  img = img.addBands(ndvi.rename('NDVI'))

//计算WET

//WET
var Wet = img.expression('B*(0.1509)   G*(0.1973)   R*(0.3279)   NIR*(0.3406)   SWIR1*(-0.7112)   SWIR2*(-0.4572)',{
       'B': img.select(['B2']),
       'G': img.select(['B3']),
       'R': img.select(['B4']),
       'NIR': img.select(['B5']),
       'SWIR1': img.select(['B6']),
       'SWIR2': img.select(['B7'])
     })   
  Wet = img_normalize(Wet)
  img = img.addBands(Wet.rename('WET').toFloat())
  
  //计算NDBSI
  
  var ibi = img.expression('(2 * SWIR1 / (SWIR1   NIR) - (NIR / (NIR   RED)   GREEN / (GREEN   SWIR1))) / (2 * SWIR1 / (SWIR1   NIR)   (NIR / (NIR   RED)   GREEN / (GREEN   SWIR1)))', {
      'SWIR1': img.select('B6'),
      'NIR': img.select('B5'),
      'RED': img.select('B4'),
      'GREEN': img.select('B3')
    })
   
  var si = img.expression('((SWIR1   RED) - (NIR   BLUE)) / ((SWIR1   RED)   (NIR   BLUE))', {
      'SWIR1': img.select('B6'),
      'NIR': img.select('B5'),
      'RED': img.select('B4'),
      'BLUE': img.select('B2')
    }) 
  var ndbsi = (ibi.add(si)).divide(2)
   ndbsi= img_normalize(ndbsi)
  img = img.addBands(ndbsi.rename('NDBSI'))
  var L8_img = img.select(["NDVI","WET","NDBSI"])
  L8_img = SR_LST.addBands(L8_img)

//掩膜,有些研究区可能需要使用到
// var mask = L8_img.select('NDVI').gte(0)
// var L8img = L8_img.updateMask(mask)
  var bands = ["WET","NDVI","NDBSI","LST"]
var sentImage =L8_img.select(bands)

  
//输入基本信息 

var region = roi;
var image =  sentImage.select(bands);
var scale = 100;
var bandNames = image.bandNames();

// 图像波段重命名函数
var getNewBandNames = function(prefix) {
    var seq = ee.List.sequence(1, bandNames.length());
    return seq.map(function(b) {
      return ee.String(prefix).cat(ee.Number(b).int());
    });
  };
//数据平均

var meanDict = image.reduceRegion({
    reducer: ee.Reducer.mean(),
    geometry: region,
    scale: scale,
    maxPixels: 1e9
});
var means = ee.Image.constant(meanDict.values(bandNames));
var centered = image.subtract(means);


//主成分分析函数
var getPrincipalComponents = function(centered, scale, region) {
    // 图像转为一维数组
    var arrays = centered.toArray();

    // 计算相关系数矩阵
    var covar = arrays.reduceRegion({
      reducer: ee.Reducer.centeredCovariance(),
      geometry: region,
      scale: scale,
      maxPixels: 1e9
    });

    // 获取“数组”协方差结果并转换为数组。
    // 波段与波段之间的协方差
    var covarArray = ee.Array(covar.get('array'));

    // 执行特征分析,并分割值和向量。
    var eigens = covarArray.eigen();

    // 特征值的P向量长度
    var eigenValues = eigens.slice(1, 0, 1);
   

    //计算主成分载荷
    var eigenValuesList = eigenValues.toList().flatten()
    var total = eigenValuesList.reduce(ee.Reducer.sum())
    var percentageVariance = eigenValuesList.map(function(item) {
      return (ee.Number(item).divide(total)).multiply(100).format('%.2f')
    })
 print(eigenValues ,'特征值')
    print("贡献率", percentageVariance)  

    // PxP矩阵,其特征向量为行。
    var eigenVectors = eigens.slice(1, 1);

    // 将图像转换为二维阵列
    var arrayImage = arrays.toArray(1);

    //使用特征向量矩阵左乘图像阵列
    var principalComponents = ee.Image(eigenVectors).matrixMultiply(arrayImage);

    // 将特征值的平方根转换为P波段图像。
    var sdImage = ee.Image(eigenValues.sqrt())
      .arrayProject([0]).arrayFlatten([getNewBandNames('sd')]);

    //将PC转换为P波段图像,通过SD标准化。
    principalComponents=principalComponents
      // 抛出一个不需要的维度,[[]]->[]。
      .arrayProject([0])
      // 使单波段阵列映像成为多波段映像,[]->image。
      .arrayFlatten([getNewBandNames('pc')])
      // 通过SDs使PC正常化。
      .divide(sdImage);
    return principalComponents
  };
//进行主成分分析,获得分析结果
var pcImage = getPrincipalComponents(centered, scale, region);
//RESI
var img = img.addBands(ee.Image(1).rename('constant'))

var rsei = img.expression('constant - pc1' , {
             constant: img.select('constant'),
             pc1: pcImage.select('pc1')
         })
  rsei = img_normalize(resi)
rsei = pcImage.addBands(resi.rename('rsei'))



print(rsei,"RSEI")
var visParam = {
    palette: 'FFFFFF, CE7E45, DF923D, F1B555, FCD163, 99B718, 74A901, 66A000, 529400,'  
        '3E8601, 207401, 056201, 004C00, 023B01, 012E01, 011D01, 011301'
 };
//添加图层
 Map.addLayer(rsei.select('rsei').clip(roi), visParam, 'rsei')
//计算RSEI平均值
var rsei_mean = image.reduceRegion({
  reducer: ee.Reducer.mean(),
  geometry:roi,
  scale: 30,
  maxPixels: 1e13
});
print(rsei_mean,'平均值')
var rsei_std = image.reduceRegion({
  reducer: ee.Reducer.stdDev(),
  geometry:roi,
  scale: 30,
  maxPixels: 1e13
});
print(resi_std,'标准差')
// var resimax = resi.select('rsei').reduceRegion({
//   reducer: ee.Reducer.max(),
//   geometry:roi,
//   scale: 30,
//   maxPixels: 1e13
// });
//下载函数
Export.image.toDrive({
//   image: rsei.select(["rsei"]),
//   description: 'rsei',
//   scale: 30,
//   region:roi,
//   fileFormat: 'GeoTIFF',
// });
/////////////////下载掩膜过后的RSEI图像,只需要在下函数适用unmask(-1), 就能将掩膜掉的部分给转换为-1
// Export.image.toDrive({
//   image: L8_img.select(["LST"]),
//   description: 'LST',
//   scale: 30,
//   region:roi,
//   fileFormat: 'GeoTIFF',
// });

本期“GEE基于Landsat 8数据反演绿度/热度/湿度/干度,并计算生态遥感指数代码”分享结束,感谢您的阅读!

0 人点赞