一文帮你搞懂Google Earth Engine上到底如何使用Tile-based的模型做分类并发表期刊论文

昨天的推文说我们的学员在一区Top期刊TGRS上发表了学术论文并致谢了本号(见云南大学博士生在一区Top期刊TGRS期刊上发表土地覆盖制图研究论文并致谢本号),其中文章中提到:

章同学在论文中开展了基于主被动遥感数据的云南省高度非均质区土地覆盖制图,并采用了我们之前反复强调的Tile-based的分类方式进行土地分类。可以发现,这些技术都是本号反复强调和分享过的

有人可能好奇,什么叫tile-based分类模型,为什么这个能够发表一篇学术论文呢?

我们来回答一下我们粗浅的理解哈,主要有几个方面的考虑。一、Google Earth Engine平台在使用的时候,经常会出现算力不足的情况,此时就需要使用分块操作,但是分块操作又有破坏整体性,最直观的影响是最终拼接效果会出现明显的马赛克效益,也就是块与块直接边界十分明显;二、官方和众多平台给出的分类模型,都是在整个研究区样本训练模型的基础上构建的,对局部地区的效果并不是十分友好,此时使用局部模型似乎更好;三、局部模型有时候样本又不够,导致模型性能下降,因此找到一张折中的处理方式似乎更好。这就是为什么使用tile-based模型的原因。

接下来,我们就进一步解释什么叫tile-based模型。所谓tile-based模型,就是对分块后的影像在训练模型时,不单单使用落在中心块内部的样本用于模型训练,还使用中心块的邻域像素块,例如3×3分块组合,如下图所示,下图来自文下面文章。不难看出,这个图和昨天推文介绍论文的分类模型图在核心分类部分是一样的呀。

Zhang M, Huang H, Li Z, et al. Automatic high-resolution land cover production in madagascar using sentinel-2 time series, tile-based image classification and google earth engine[J]. Remote Sensing, 2020, 12(21): 3663.

图片

图片

有了这一指导思想后,我们就可以在GEE中实现这种tile-based分类模型了。我们先放一下不使用和使用tile-based分类策略的效果图,如下所示。很明显,普通分块后分类结果出现了常见的mosaic效益,边界明显;而采样tile-based模型后分类几乎没有边界效益,分类效果非常棒!

图片

接下来,为了方便大家查看具体效果,我们非常代码,大家可以自行复现使用。

var roi = AOI;
Map.addLayer(roi, {'color':'grey'}, 'studyArea',false);
Map.centerObject(roi);

var samples = sampleData.filterBounds(roi);

Map.addLayer(samples,{'color':'blue'},'sampleData',false);

/**************************************************************************
generate the grid
***************************************************************************/
function generateGrid(xmin, ymin, xmax, ymax, dx, dy) {
  // var dx = (ee.Number(xmax).subtract(xmin)).divide(2); //4
  // var dy = (ee.Number(ymax).subtract(ymin)).divide(2);
  var xx = ee.List.sequence(xmin, ee.Number(xmax).subtract(0.0001), dx);
  var yy = ee.List.sequence(ymin, ee.Number(ymax).subtract(0.0001), dy);
  
  var cells = xx.map(function(x) {
    return yy.map(function(y) {
      var x1 = ee.Number(x);
      var x2 = ee.Number(x).add(ee.Number(dx));
      var y1 = ee.Number(y);
      var y2 = ee.Number(y).add(ee.Number(dy));
      var coords = ee.List([x1, y1, x2, y2]);
      var rect = ee.Algorithms.GeometryConstructors.Rectangle(coords);   //生成矩形
      return ee.Feature(rect);
    });
  }).flatten();   //变成单个数组

  return ee.FeatureCollection(cells);
}

var bounds = roi.geometry().bounds();
var coords = ee.List(bounds.coordinates().get(0));
var xmin = ee.List(coords.get(0)).get(0);
var ymin = ee.List(coords.get(0)).get(1);
var xmax = ee.List(coords.get(2)).get(0);
var ymax = ee.List(coords.get(2)).get(1);

// set the gaps for longitude and latitudes 
// you can choose to set the absolute lavues like dx=dy=0.02;
// or you can choose to set the study area by evenly splitting the area in the following ways
var dx = (ee.Number(xmax).subtract(xmin)).divide(4); //4
var dy = (ee.Number(ymax).subtract(ymin)).divide(4);
// var dx = 1;
// var dy = 1;
// print("dx, dy", dx, dy);

var grid = generateGrid(xmin, ymin, xmax, ymax, dx, dy);    //设置参数,生成格网
var grid = grid.filterBounds(roi); // filter out out-of-boundary tiles

print('grid size',grid.size()); //查看生成所有格网数量
Map.addLayer(grid, {color:'orange'}, 'grid',false);

// remove cloud from Sentinel-2
function rmS2cloud(image) {
  var qa = image.select('QA60');

  // Bits 10 and 11 are clouds and cirrus, respectively.
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;

  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
      .and(qa.bitwiseAnd(cirrusBitMask).eq(0));

  return image.updateMask(mask).toDouble()//.divide(10000)
              .copyProperties(image)
              .copyProperties(image, ["system:time_start", "system:time_end"]);
}

var S2_BANDS  = ['B2',   'B3',    'B4',  'B8',  'B11',   'B12']; // Sentinel-2
var STD_NAMES = ['blue', 'green', 'red', 'nir', 'swir1', 'swir2'];


var S2SRCol = ee.ImageCollection('COPERNICUS/S2_SR')//.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',50))
                .filterDate('2020-01-01', '2020-11-01')
                .filterBounds(roi)
                .map(rmS2cloud)
                .select(S2_BANDS, STD_NAMES)
                .median()
                .clip(roi);
                
var imgData =S2SRCol.clip(roi);
Map.addLayer(imgData, {'min':0,'max':3000,'bands':['red','green','blue']},'imgData',false);
var bands = imgData.bandNames();

// 通过要素集在imgData中选取样本,把sample属性赋予样本
var sampledPointSet = imgData.sampleRegions({
  collection: samples,
  properties: ['landcover'],
  scale: 30,
  tileScale:16,
  geometries: true
});
// 在sampledPointSet要素集中增加一个random属性,值为0到1的随机数
var sampledPointSet = sampledPointSet.randomColumn({
  columnName:'random',
  seed: 8
});

//把生成随机数大于0.7的分成测试数据,否则为训练数据
var split = 0.7; 
var trainPartSet = sampledPointSet.filter(ee.Filter.lt('random', split));
var testPartSet = sampledPointSet.filter(ee.Filter.gte('random', split));
print('trainPartSet info',trainPartSet.first());

// 开始tile-based分类
var gridSize = grid.size().getInfo();
// print("gridSize size:", gridSize);
var gridList = grid.toList(gridSize);

var gridImgList = ee.List([]);

for(var i=0; i<gridSize; i++){
  
  var localGrid = ee.Feature(gridList.get(i));
  var bounds = localGrid.geometry().bounds();
  var bufferedGrid = bounds.buffer(10000); // 请根据需要调整buffer半径数值,我们这里设置的是10000
  bufferedGrid = grid.filterBounds(bufferedGrid);
  Map.addLayer(bufferedGrid,{'color':'red'},'bufferedGrid_'+i,false);
  
  var trainedClassifier = ee.Classifier.smileRandomForest(50).train({
    features: trainPartSet.filterBounds(bufferedGrid),
    classProperty: 'landcover',
    inputProperties: bands
  });
  
  //对sentinel进行分类
  var class_img = imgData.clip(localGrid).classify(trainedClassifier);

  gridImgList = gridImgList.add(class_img);
}

var imgResult = ee.ImageCollection(gridImgList).mosaic();

// Define a palette for the IGBP classification.
var igbpPalette = [
  '#F5CA7A', // dryland,
  '#38A800', // forest, 
  '#98E600', // grass,
  '#007AFF', // waterbody
  '#e60000', // impervious
  '#DE9E66',  // nonCrop
  '#AEF1B0', // wetland
];
Map.addLayer(imgResult, {palette: igbpPalette, min: 1, max:7}, 'imgResult');

交流合作&科研搭子

团队简介:geeAI学习室是一群具有摄影测量与遥感和计算机等专业背景的高校博士生(含在读和已毕业)创办的用于分享科学前沿动态、专注智能计算和数据的平台。该平台主要结合Google Earth Engine(GEE)云平台和人工智能(AI)技术,实现对地理空间数据的高效处理和智能分析。截至目前,已经有好几千人参加了本平台的学习课程等,其中报名的会员人数已经超过400+,协助学员发表SCI一区/二区高级别论文20篇以上。

科研搭子:geeAI学习室创建了多个学习交流群,交流群成员来自各地高校和研究所,涵盖本科、硕士、博士和老师群体,可以在交流群交流讨论、积极碰撞、找到共同研究兴趣的“科研搭子”以及下载各种学术论文等。

想加入交流群的同学可加小编微信让其邀请进群(扫描下方二维码咨询报名或菜单栏“联系我们”选项框都可以找到小编哟)。注意,咨询加群验证信息请备注为“学位-研究方向-学校-加群”格式,否则不予通过。例如,假如你是武汉大学土地利用分类方向的博士研究生,则可以备注“博士-LULC-武大-加群”;假如你是北京大学生态学方向的硕士研究生,则可以备注“硕士-生态学-北大-加群”。

图片

如果有帮助,点赞、关注、转发一下呗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值