利用GEE(Google Earth Engine)在线处理NDVI、EVI、SAVI、NDMI等指数归一化教程!

1.首先进行“去云”函数的准备

//landsat5、7 EVI指数计算
// SR数据去云  
function rmCloud(image) {  
  var cloudShadowBitMask = (1 << 3);  
  var cloudsBitMask = (1 << 5);  
  var qa = image.select("pixel_qa");  
  var mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0)  
                 .and(qa.bitwiseAnd(cloudsBitMask).eq(0));  
  return image.updateMask(mask);  
} 

以上这一步都是最简单的操作,对于处理landsat-sr系列数据都基本用到。

 2.数据的选择

//这是我自己的行政矢量边界,这回用的是山西省界

var hh= ee.FeatureCollection("users/bqt2000204051/shanxijie");

//这部分代码是进行数据的选择和EVI指数的遍历计算,我进行的是年统计

var image= ee.ImageCollection("LANDSAT/LT05/C01/T1_SR")
          .filterBounds(hh)
          .filterDate("1986-1-1","1987-1-1")
          .map(rmCloud)
          .map(function(image) {
            var evi = image.expression(  
    '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', {  
      'NIR': image.select('B4'),  
      'RED': image.select('B3'),  
      'BLUE': image.select('B1')  
}); 
return image.addBands(evi.rename('EVI')).clip(hh);
})
;
print("image",image);
Map.centerObject(hh, 3);

//在这里进行自己影像的选择,这里选择第一张影像,另外,裁剪自己的边界。
var scol_clip1 =image.first().clip(hh);


//其他指数可以参照一下函数
//NDVI  
function NDVI(image) {  
  return image.addBands(  
    image.normalizedDifference(["B5", "B4"])  
         .rename("NDVI"));  
}  
  
//NDWI  
function NDWI(image) {  
  return image.addBands(  
    image.normalizedDifference(["B3", "B5"])  
         .rename("NDWI"));  
}  
    
//NDBI  
function NDBI(image) {  
  return image.addBands(  
    image.normalizedDifference(["B6", "B5"])  
         .rename("NDBI"));  
}  

以上部分各指数的计算过程我就不一一解释了,因为指数就是波段运算的结果,自己进行公式表达就行了。

 3.数据的归一化处理函数

function normalization(image,region,scale){
var mean_std = image.reduceRegion({
  reducer: ee.Reducer.mean()
            .combine(ee.Reducer.stdDev(),null, true),
  geometry: region,
  scale: scale,
  maxPixels: 10e9,
  // tileScale: 16
}); 
// use unit scale to normalize the pixel values
var unitScale = ee.ImageCollection.fromImages(
  image.bandNames().map(function(name){
    name = ee.String(name);
    var band = image.select(name);
    var mean=ee.Number(mean_std.get(name.cat('_mean')));
    var std=ee.Number(mean_std.get(name.cat('_stdDev')));
    var max=mean.add(std.multiply(3));
    var min=mean.subtract(std.multiply(3));
    var band1=ee.Image(min).multiply(band.lt(min)).add(ee.Image(max).multiply(band.gt(max)))
                        .add(band.multiply(ee.Image(1).subtract(band.lt(min)).subtract(band.gt(max))));
    var result_band=band1.subtract(min).divide(max.subtract(min));
    return result_band;
})).toBands().rename(image.bandNames());
  return unitScale;
}

这一段代码来自Pyrs大神:(2条消息) Google Earth Engine笔记-影像归一化与异常值去除_Pyrs的博客-CSDN博客主要思路是通过计算均值、标准差和在3倍标准差之内的误差来剔除异常值。

 3.数据的归一化处理函数

//归一化前的结果
var before_chart=ui.Chart.image.histogram(scol_clip.select(["B4","EVI"]), hh, 1000);
print(before_chart);
//让影像进行归一化函数处理后的结果
var normal_image=normalization(scol_clip,hh,1000)
print(normal_image)
//归一化后的结果
var after_chart=ui.Chart.image.histogram(normal_image.select(["B4","EVI"]), hh, 1000)
print(after_chart)

这里有一点问题,在于=ui.Chart.image.histogram()中1000代表的是像素值:

scale (Number, optional):

The pixel scale used when applying the histogram reducer, in meters.

当你的运行范围超出了最大计算量的时候,选择把自己的像素值调大,可以解决这个问题!

以上是归一化前的统计量,为了和EVI波段明显对比,我使用了一个B4波段作为参照!

这是归一化后的统计量分布图! 

 4.数据的下载和导出

Export.image.toDrive({
  image:normal_image.select("EVI"),
  description: '1986_shanxi_EVI_sr',
  folder: 'hulunbeier',
  scale: 1000,
  region:hh
});

Map.addLayer(image, {},'EVI');

猜你喜欢

转载自blog.csdn.net/qq_31988139/article/details/118418607