首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SLC代码没有填补Landsat7 SR的所有空白

SLC代码没有填补Landsat7 SR的所有空白
EN

Stack Overflow用户
提问于 2019-03-20 16:51:05
回答 1查看 1.9K关注 0票数 1

我是Google Earth引擎代码的初学者,正在尝试将SLC-gap代码应用于Landsat7表面反射比图像。使用StackOverflow上的可用资源,我生成了以下代码;但是,当我将图像带入QGIS时,似乎仍然存在差距。是我的代码不正确,还是我没有正确地将其应用于图像?

首先,我根据陆地卫星SR数据的pixel_qa波段对云进行了掩蔽:

代码语言:javascript
复制
var cloudMaskL7 = function(image) {
var qa = image.select('pixel_qa');
var cloud = qa.bitwiseAnd(1 << 5)
                  .and(qa.bitwiseAnd(1 << 7))
                  .or(qa.bitwiseAnd(1 << 3));

然后,我删除了不会出现在所有波段中的边缘像素:

代码语言:javascript
复制
var mask2 = image.mask().reduce(ee.Reducer.min());
return image.updateMask(cloud.not()).updateMask(mask2);
 };
var l7 = ee.ImageCollection('LANDSAT/LE07/C01/T1_SR')
              .filterDate('2004-09-15', '2004-12-31')
              .map(cloudMaskL7);

var visParams = {
bands: ['B3', 'B2', 'B1'],
min: 0,
max: 3000,
gamma: 1.4,
};
Map.setCenter(36.197, 31.701,7);
Map.addLayer(l7.median(), visParams);

然后,我绘制了超过一年的Landsat7 TOA数据的函数,取中位数并将其映射到约旦。

代码语言:javascript
复制
var composite = l7.map(cloudMaskL7)
    .median();
Map.setCenter(36.124, 31.663);
Map.addLayer(composite, {bands: ['B4', 'B3', 'B2'], max: 0.3});

然后,我尝试通过应用美国地质勘探局L7阶段2差距填充协议,使用单一的内核大小来填补SLC Landsat7的空白。

代码语言:javascript
复制
var MIN_SCALE = 1/3;
var MAX_SCALE = 3;
var MIN_NEIGHBORS = 144;
var GapFill = function(src, fill, kernelSize) {
var kernel = ee.Kernel.square(kernelSize * 30, 'meters', false);
var common = src.mask().and(fill.mask());
var fc = fill.updateMask(common);
var sc = src.updateMask(common);

然后,我通过回归找到了主要的比例因子,并对回归的波段进行了交错(假设这些波段具有相同的名称)。

代码语言:javascript
复制
   var regress = fc.addBands(sc);
    regress = regress.select(regress.bandNames().sort());
    var fit = regress.reduceNeighborhood(ee.Reducer.linearFit().forEach(src.bandNames()),  kernel, null, false);
    var offset = fit.select('.*_offset');
    var scale = fit.select('.*_scale');

然后,我使用means和stddev找到了辅助比例因子。

代码语言:javascript
复制
 var reducer = ee.Reducer.mean().combine(ee.Reducer.stdDev(), null, true);
    var src_stats = src.reduceNeighborhood(reducer, kernel, null, false);
    var fill_stats = fill.reduceNeighborhood(reducer, kernel, null, false);
    var scale2 = src_stats.select('.*stdDev').divide(fill_stats.select('.*stdDev'));
    var offset2 = src_stats.select('.*mean').subtract(fill_stats.select('.*mean').multiply(scale2));

    var invalid = scale.lt(MIN_SCALE).or(scale.gt(MAX_SCALE));
    scale = scale.where(invalid, scale2);
    offset = offset.where(invalid, offset2);

我对没有足够邻居的像素进行了缩放和遮罩。

代码语言:javascript
复制
var count = common.reduceNeighborhood(ee.Reducer.count(), kernel, null, true, 'boxcar');
var scaled = fill.multiply(scale).add(offset)
      .updateMask(count.gte(MIN_NEIGHBORS));

  return src.unmask(scaled, true);
};

var source = ee.ImageCollection('LANDSAT/LE07/C01/T1_SR');
var fill = ee.ImageCollection('LANDSAT/LE07/C01/T1_SR');

我加载了一个边界和过滤器的表。

代码语言:javascript
复制
var Jordan = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017')
    .filter(ee.Filter.or(
        ee.Filter.eq('country_co', 'JO')));
        var clippedJordan = composite.clipToCollection(Jordan);

我显示了Jordan的结果;但是,SLC的空白似乎没有被填补。我继续使用这些图像计算MSAVI2值,因此剩余的间隙会影响结果。

代码语言:javascript
复制
var mc = Map.setCenter(36.274, 31.682, 6);
var visParams = {bands: ['B3', 'B2', 'B1']};
Map.addLayer(clippedJordan, visParams, 'clipped composite');

任何建议都将不胜感激!

EN

回答 1

Stack Overflow用户

发布于 2019-03-21 07:02:18

对于SLC-off图像,我不了解最新的Landsat7填充技术,但这里是您尝试做的一个大大简化的版本。我删除了很多(不必要的?)填充,内核大小增加了很多,并增加了生成中值替换的时间范围。它可能会接近你想要的:

代码语言:javascript
复制
var cloudMaskL7 = function(image) {
  var qa = image.select('pixel_qa');
  var cloud = qa.bitwiseAnd(1 << 5)
                    .and(qa.bitwiseAnd(1 << 7))
                    .or(qa.bitwiseAnd(1 << 3));
  var mask2 = image.mask().reduce(ee.Reducer.min());
  return image.updateMask(cloud.not()).updateMask(mask2);
};

var l7 = ee.ImageCollection('LANDSAT/LE07/C01/T1_SR')
    .map(cloudMaskL7);

var kernelSize = 10;
var kernel = ee.Kernel.square(kernelSize * 30, 'meters', false);

var GapFill = function(image) {
  var start = image.date().advance(-1, 'year');
  var end = image.date().advance(1, 'year');
  var fill = l7.filterDate(start, end).median();
  var regress = fill.addBands(image); 
  regress = regress.select(regress.bandNames().sort());
  var fit = regress.reduceNeighborhood(ee.Reducer.linearFit().forEach(image.bandNames()), kernel, null, false);
  var offset = fit.select('.*_offset');
  var scale = fit.select('.*_scale');
  var scaled = fill.multiply(scale).add(offset);
  return image.unmask(scaled, true);
};

// TESTING CODE
var point = ee.Geometry.Point(36.124, 31.663);
Map.centerObject(point, 11);

var check = ee.ImageCollection('LANDSAT/LE07/C01/T1_SR')
    .filterBounds(point)
    .filterDate('2004-09-15', '2004-12-31');
var checkImage = ee.Image(check.first());
var visParams = {bands: ['B4', 'B3', 'B2'], min: 200, max: 5500};
Map.addLayer(checkImage, visParams, 'source');

// Test composite.
var checkStart = checkImage.date().advance(-1, 'year');
var checkEnd = checkImage.date().advance(1, 'year');
var composite = l7.filterDate(checkStart, checkEnd).median();
Map.addLayer(composite, visParams, 'median');

// Rough implementation for comparison.
var replaced = checkImage.unmask(composite);
Map.addLayer(replaced, visParams, 'simple');

// Fancy implementation.
var filled = ee.Image(check.map(GapFill).first());
Map.addLayer(filled, visParams, 'filled');

编辑:答案现在展示了如何将其映射到集合上。当心,因为我不知道这会有多大的伸缩性。如果你决定将它映射到一个大区域或长时间序列,你已经得到了警告。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55256739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档