GEE必须会教程——时间序列影像填补方法

“天气晴朗时,见个面吧。我心里储存的,有关你的影像档,已经旧了,需要更新”

——林婉瑜

今天是七夕,让我们和代码相伴,邂逅一段新的故事。

前段时间,有读者私信小编,当我们在对一些研究区域进行预处理后会发现影像存在缺失问题,导致结果没办法用,这个问题应该如何解决,小编翻阅了一些大佬的文章,学到一点本事,今天来当一回女娲,看看如何补补天吧~~~。

打开咱们的伙伴:Google Earth Engine,诶,今天发现,在打印栏出现一行醒目的绿色大字。

从2024年11月13日起,如果在GEE上没有云端项目,将限制使用GEE,这个GEE的新闻头条部分读者已经在其他的文章或者是GEE开发官网得到消息了,还没有云端项目的伙伴,赶紧找到网址创建好属于自己的新项目,从项目进入即可!https://developers.google.com/earth-engine/cloud/earthengine_cloud_project_setup

 

配置好项目后,我们打开GEE的编辑器,开始上代码。

1 创建研究区域

var roi = ee.FeatureCollection("users/hesuixinya511/Province")
                                 .filterMetadata("NAME","equals","重庆");
Map.centerObject(roi,7);
var styling = {color:"red",fillColor:"00000000"};
Map.addLayer(roi.style(styling),{},"CHONGQING");

代码解释:

第1~2行,从用户指定路径中加载一个要素集合(FeatureCollection)。这个集合包含中国各省的地理边界数据。利用filterMetadata命令从要素集合中过滤出名称为“重庆”的要素。“NAME”是要素集合中的一个属性字段,用来表示省份名称。

第3行,将地图视图的中心设置为重庆区域,并将缩放级别设置为7。这使得地图界面聚焦在指定区域,方便各位小伙伴查看。

第4行,定义了显示样式。color参数将边界线的颜色设置为红色,fillColor参数将填充颜色设置为透明(十六进制颜色代码一般为6位,此处8位,其中最后两位为透明度,00表示完全透明)。

第5行,将重庆区域的边界添加到地图中,并应用前面定义的样式。第三个参数“CHONGQING”是图层的名称,便于管理和识别。

上述代码,将得到重庆市的行政边界:

2 影像标准化处理

var img_normalize = function(img){ 
  var minMax = img.reduceRegion({ 
    reducer:ee.Reducer.minMax(), 
    geometry: roi, 
    scale: 30, 
    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;
  
};

 代码解释:

第1行,定义一个名为img_normalize 的函数,接收一个影像img作为参数。该函数的目的是对影像中的各个波段进行标准化处理。

第2~7行,计算影像在指定区域(geometry:roi)内的每个波段的最小值和最大值。其中包括的基本参数为计算器、研究区域、分辨率、计算时的最大像素数以及瓦片缩放比例。

第8行,从影像的属性中获取年份信息。这一步在当前代码中没有被进一步使用,可以用于标记或其他数据处理。

第9~14行:遍历影像中的每个波段,进行标准化处理,将影像波段范围映射到[0,1],并将标准化后的各个波段合并为一个影像,重命名为原来的波段名称。

这种标准化处理通常用于遥感影像的时间序列分析和多影像比较,可以有效减少光照、传感器差异和其他非目标因素的影响。

3 影像去云与校正预处理

function maskL457sr(image) {//l57去云
  // Bit 0 - Fill
  // Bit 1 - Dilated Cloud
  // Bit 2 - Unused
  // Bit 3 - Cloud
  // Bit 4 - Cloud Shadow
  var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0);
  var saturationMask = image.select('QA_RADSAT').eq(0);

  // Apply the scaling factors to the appropriate bands.
  var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2);
  var thermalBand = image.select('ST_B6').multiply(0.00341802).add(149.0);

  // Replace the original bands with the scaled ones and apply the masks.
  return image.addBands(opticalBands, null, true)
      .addBands(thermalBand, null, true)
      .updateMask(qaMask)
      .updateMask(saturationMask);
}

代码解释:

QA_PIXEL 波段:这是Landsat影像中用于质量评估的波段。该波段中的位(bits)用于标识影像中的各种质量问题,例如云、阴影、填充值等。

QA_RADSAT 波段:这是Landsat影像中用于指示饱和像素的波段。

上述波段通过位与操作和eq(0)即可达到目标效果。

第4行,光学波段校正,对光学波段应用缩放因子,将DN值转换为反射率。缩放因子和偏移量来源于Landsat影像的元数据。

第5行,热红外波段校正,对热红外波段应用缩放因子,将DN值转换为亮温(开尔文)。

第6~10行,更新影像,使用addBands用校正后的光学波段和热红外波段替换原始波段。null表示不设置新波段的名称,true 表示覆盖同名波段。使用updateMask,应用QA掩码和饱和掩码,去除有问题的像素。这一步确保输出影像仅包含有效数据。

此段代码对Landsat 4-5卫星影像进行预处理,以去除云、阴影和饱和像素,同时将影像值转换为物理意义的反射率和亮温。

Landsat8数据的预处理看下面:

function maskL8sr(image) {
  // Bit 0 - Fill
  // Bit 1 - Dilated Cloud
  // Bit 2 - Cirrus
  // Bit 3 - Cloud
  // Bit 4 - Cloud Shadow
  var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0);
  var saturationMask = image.select('QA_RADSAT').eq(0);

  // Apply the scaling factors to the appropriate bands.
  var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2);
  var thermalBands = image.select('ST_B.*').multiply(0.00341802).add(149.0);

  // Replace the original bands with the scaled ones and apply the masks.
  return image.addBands(opticalBands, null, true)
      .addBands(thermalBands, null, true)
      .updateMask(qaMask)
      .updateMask(saturationMask);
}*/

4 影像筛选与中值合成

var imageCollection = ee.ImageCollection('LANDSAT/LT05/C02/T1_L2').filterBounds(roi);//1111111
var monthCount = ee.List.sequence(0, 11);
// 通过图像收集,生成每月NDVI中值图像
var composites = ee.ImageCollection.fromImages(monthCount.map(function(m) {
  var startMonth = 1; // 从1月开始
  var startYear = ee.Number(2000); // 1993-1
  
  var month = ee.Date.fromYMD(startYear, startMonth, 1).advance(m,'month').get('month');
  var year = ee.Date.fromYMD(startYear, startMonth, 1).advance(m,'month').get('year')
  
  // 按年筛选,然后按月筛选
  var filtered = imageCollection.filter(ee.Filter.calendarRange({
    start: year.subtract(1), // 过去两年的平均数
    end: year,
    field: 'year'
  })).filter(ee.Filter.calendarRange({
    start: month,
    field: 'month'
  }));
  // mask for clouds and then take the median///
  var composite = filtered.map(maskL457sr).median().clip(roi);
  return composite.normalizedDifference(['SR_B4', 'SR_B3']).rename('NDVI')
      .set('month', ee.Date.fromYMD(startYear, startMonth, 1).advance(m,'month'))
      .set('system:time_start', ee.Date.fromYMD(startYear, startMonth, 1).advance(m,'month').millis());
}));
print(composites);

代码解释:

第1行:加载L5影像,并且按照研究区域筛选。

第2行:生成一个包含数字0到11的列表,用于表示每年的12个月。这将用于迭代每个月的处理。

第6-7行:根据基准日期(第五行定义的2000年1月1日)和m(月份偏移量)计算当前迭代的月份和年份。利用get函数提取当前迭代中的月份和年份。

第8-15行:在筛选过去两年的影像数据,筛选当前月份的影像数据。

第16行:应用之前定义的预处理函数maskL457sr,对影像进行去云和辐射校正。利用median方法计算当前月份的影像中值,以减少噪声和偶然变化的影响,最后使用clip将影像裁剪到roi。

第17行:计算NDVI。

第18行:设置元数据,为每张影像设置月份属性,方便后续的分析。

此段通过遍历一年中的每个月,计算Landsat 5影像在指定区域内的NDVI中值。敲黑板!!!这种方法可以用于时间序列分析,帮助研究区域内植被变化情况。通过使用中值和去云处理,能够有效减少影像中的噪声和误差,得到更加可靠的结果。

5 影像填补

// 用上个月和下个月的平均值替换被遮挡的像素 
var replacedVals = composites.map(function(image){
  var currentDate = ee.Date(image.get('system:time_start'));
  var meanImage = composites.filterDate(
                currentDate.advance(-2,'month'), currentDate.advance(2, 'month')).mean();//33333333333333333333333max min median
  // 替换所有被屏蔽的值
  return meanImage.where(image, image);
});

代码解释:

第1-6行,对composites中的每个图像进行逐一处理。map方法会将集合中的每个元素传递给函数,并返回一个新的集合。

第2行,获取当前的时间,将其转化为ee对象,方便后续的日期处理。

第3-4行,计算当前影像前后两个月的日期,过滤期间所有的影像,之后,计算其平均值,利用mean方法生成平均影像。

第5行,替换无效像素。where(condition,value):在条件为false的地方,用value替换原始影像的值.image作为条件:对于有效像素(即未被掩膜)的位置,条件为true,保留原始值。对于被掩膜的像素(即无效像素),条件为false,用meanImage中的值替换掉。

此代码在时间序列分析中用于填补由于云、阴影等原因导致的无效数据,以提高数据的完整性。

6 数据可视化

var palettes = require('users/gena/packages:palettes');
var Vis = {
  min: -1,
  max: 1.0,
  palette: palettes.colorbrewer.RdYlGn[5]
};
Map.addLayer(compos.select(6), Vis, '插值前');
// .0-11  分别代表1-12个月
Map.addLayer(stacked.select(6), Vis, 'NDVI');

这里就不用过多解释,就是对处理前后的影像调调配色而已,我们来看最后的结果吧

填补前的影像

填补后的影像

 效果还是挺不错的,只是在右小角有一小块还存在些差异,但是比起原始的影像就好多了。

好了,今天的GEE学习到这里就结束了。

“七”待已久,“夕”望是你,我是禾穗,祝正在学代码的朋友们早日遇见幸福噢~,不过单身的朋友也没关系啦,看看日历,今天没有早八,没有工作,是快乐周六呀!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值