GEE|基于时间序列特征的山东省玉米随机森林分类代码

主题思路:

       本实验为二分类实验,分类目标包括:玉米、其他(建筑、水体、水稻、 裸地、森林、小麦、道路、大蒜等),采用人工设计的特征指数的时间序列特征为分类依据,选取分类器为:随机森林分类器,并选取样本集中 70%作为训练样本,30%作为测试样本,通过调整随机森林棵数,调整分类器结构。选取以下参数进行分类:

⚫ 时间尺度:1990 年 4 月 15 日 - 1990 年 9 月 30 日

⚫ 空间尺度:山东省

⚫ 影像融合时间间隔:16天

⚫ 特征值选择:['nir','ndvi','lswi','gcvi']

⚫ RF 超参数:35

       实验最终得到山东省 1990 年的玉米分布图,分类精度达到 90.1%,Kappa 系数达到 0.800,同时得到整体影像、玉米区域、其他区域 NDVI 时序变化曲线。实验精度结果良好,制图分析后局部地区出现条带效应,经过研究发现,1990 年 Landsat 5 影像在 1990 年时存在较大面积的缺失现象。 

成果展示:

GEE|基于时间序列特征的山东省玉米随机森林分类代码_第1张图片  GEE|基于时间序列特征的山东省玉米随机森林分类代码_第2张图片

代码:

//============================创建函数==================================
exports.GetTimeSeriesImages = function(startDate, endDate, interval,
                                       shpfile, bandsName, newBandsName,
                                       classBands, qualityMosaic, qmValue, 
                                       unmasked){
//=====================增加特征值(NDVI\GCVI\LSWI\MNDWI)===============
  var addVI = function(img){
        var time_start = img.get('system:time_start');
        var ndvi = img.normalizedDifference(['nir','red']).rename('ndvi');
        ndvi = ndvi.set('system:time_start', time_start);
        
        var gcvi = img.expression(
          'NIR / GREEN - 1',{
          'NIR': img.select('nir'),
          'GREEN': img.select('green'),
        });
        gcvi = gcvi.set('system:time_start', time_start);
        
        var lswi = img.expression(
          '(NIR - SWIR1) / (NIR + SWIR1)',{
          'NIR': img.select('nir'),
          'SWIR1': img.select('swir1'),
        });
        lswi = lswi.set('system:time_start', time_start);

        var mndwi = img.normalizedDifference(['blue', 'swir1']);//计算MNDWI
        mndwi = mndwi.set('system:time_start', time_start);
        // var ndbi = img.normalizedDifference(['swir1', 'nir']);//计算NDBI
        // ndbi = ndbi.set('system:time_start', time_start);
        //加入波段信息
        return img.addBands(ndvi.rename("ndvi"))
                  .addBands(lswi.rename('lswi'))
                  .addBands(gcvi.rename('gcvi'))
                  .addBands(mndwi.rename('mndwi'))
                  // .addBands(ndbi.rename('ndbi'))
                  
    };
//============================创建时间序列===============================
  var start = ee.Date(startDate);
  var end = ee.Date(endDate);
  var step = end.difference(start,'day').divide(interval).ceil();
  var dateList = ee.List.sequence(0, step.multiply(interval), interval).map(function(date){
    return start.advance(date, 'day');
    
  });
  var images_list = dateList.map(function(date){
    var start_date = ee.Date(date);
    var end_date = start_date.advance({delta: interval, unit: 'day'});
    var l5 = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR')
                .filterDate(start_date, end_date)
                .filterBounds(shpfile)
                .select(bandsName, newBandsName)
                .map(exports.maskl5Clouds);

var S_result = l5.map(addVI);
//=================以NDVI质量为判断依据,对重叠部分进行融合================
    var l5_result = ee.Algorithms.If(
        ee.Algorithms.IsEqual(ee.Number(qualityMosaic), 1),
        ee.Algorithms.If(
          ee.Algorithms.IsEqual(unmasked, 1),
//=====================缺少部分用0填充,重叠部分用NDVI高的影像============
ee.ImageCollection(S_result).qualityMosaic(ee.String(qmValue)).unmask(ee.Number(0)).select(classBands),
          ee.ImageCollection(S_result).qualityMosaic(ee.String(qmValue)).select(classBands)
          
          ),
//===================重叠部分用像素值高的影像=============================
        ee.Algorithms.If(
          ee.Algorithms.IsEqual(unmasked, 1),
          
          ee.ImageCollection(S_result).max().unmask(ee.Number(0)).select(classBands),
          ee.ImageCollection(S_result).max().select(classBands)
          )
      );
//==============================裁剪====================================
    l5_result = ee.Image(l5_result).clip(shpfile.geometry());
//==============================制作时相集===============================
    l5_result = l5_result.set('system:time_start', start_date);
    return l5_result;
  });

    return images_list;
};
//==============================去云函数=================================
function bitwiseExtract(value, fromBit, toBit) {
  if (toBit === undefined) toBit = fromBit
  var maskSize = ee.Number(1).add(toBit).subtract(fromBit)
  var mask = ee.Number(1).leftShift(maskSize).subtract(1)
  return value.rightShift(fromBit).bitwiseAnd(mask)
}

exports.maskl5Clouds = function(image){
  var qa = image.select('pixel_qa');
  var time_start = image.get('system:time_start');
  var cloudState = bitwiseExtract(qa, 5);
  var cloudShadowBitMask = (1 << 3);
  var cloudsBitMask = (1 << 5);
  var mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0)
                .and(qa.bitwiseAnd(cloudsBitMask).eq(0));
  image = image.set('system:time_start', time_start);
  return image.updateMask(mask);
}
//==============================建立分类模型=============================
exports.GetClassifier = function(composition, training, label, trees){
  var bands = composition.bandNames(); 
  var classifier = ee.Classifier.smileRandomForest({numberOfTrees: trees}).train({
    features: training,
    classProperty: label,
    inputProperties: bands
  });
  return classifier;
}

exports.GenerateGrid = function(xmin, ymin, xmax, ymax, dx, dy) {
  var xx = ee.List.sequence(xmin, xmax, dx);
  var yy = ee.List.sequence(ymin, ymax, dy);
  var cells = xx.map(
    function(x){
      return yy.map
      (
        function(y){
          var x1 = ee.Number(x).subtract(ee.Number(dx).multiply(0.5));
          var x2 = ee.Number(x).add(ee.Number(dx).multiply(0.5));
          var y1 = ee.Number(y).subtract(ee.Number(dy).multiply(0.5));
          var y2 = ee.Number(y).add(ee.Number(dy).multiply(0.5));
      
          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 corn_samples = ee.FeatureCollection('users/wenqikou/corn')//
var other_samples = ee.FeatureCollection('users/wenqikou/other') //包括水稻大豆建筑森林等等
var samples = corn_samples.merge(other_samples);
//==============================导入山东shp=============================
var shpfile = ee.FeatureCollection("users/wenqikou/shandong");
Map.centerObject(shpfile);
//=======================定义时间序列影像参数============================
var start_date = '1990-04-15';
var end_date = '1990-9-30';
var interval = 15
var bandsName = ['B1','B2', 'B3', 'B4', 'B5', 'pixel_qa'];
var newBandsName = ['blue','green', 'red','nir', 'swir1', 'pixel_qa'];
var classBands = ['ndvi','lswi','gcvi','nir'];
//var classBands = ['blue','green', 'red','ndvi','lswi','gcvi','mndwi'];
var timeSeries = exports.GetTimeSeriesImages(start_date, end_date, interval, shpfile, 
                                            bandsName, newBandsName, classBands, 1, 'ndvi', 1);
print(timeSeries);
var ndvi = ee.Image(ee.ImageCollection(timeSeries).select("ndvi").toList(13).get(12)).select("ndvi")

print(ndvi)
var shp = shpfile.geometry();
var NDVIValue_region1 = ndvi.reduceRegion({
        reducer: ee.Reducer.mean(),
        geometry: shp,
        scale:30,
        crs:'EPSG:4326',
        maxPixels:1e13,
        })
print(NDVIValue_region1,'NDVIValue_region1')

//==============================可视化显示 =============================
//Map.addLayer(ee.ImageCollection(timeSeries).mean(), //{bands:["red","green","blue"],min:0,max:3000}, "union1")
//==============================训练模型=============================
// 坡度作为特征加入
var srtm = ee.Image('USGS/SRTMGL1_003'); 
var slope = ee.Terrain.slope(srtm).clip(shpfile);
var composition = ee.ImageCollection.fromImages(timeSeries).toBands();
composition = composition.addBands(slope);
// 样本数据集70%训练,30%测试
var trainData = composition.sampleRegions({
  collection : samples,
  properties : ['uta'],
  scale : 30,
  tileScale: 16
});

var withRandom = trainData.randomColumn("random");
var split = 0.7;
var trainingPart = withRandom.filter(ee.Filter.lt("random", split));
var testingPart = withRandom.filter(ee.Filter.gte("random", split));

// 训练分类器
var classifier = exports.GetClassifier(composition, trainingPart, 'uta', 35);
//==============================测试集精度 =============================
var test = testingPart.classify(classifier)
var confusionMatrix = test.errorMatrix('uta', 'classification');
var testaccuracy = ee.Feature(null,{
  test_confusionmatrix: confusionMatrix.array(),
  test_overallaccuracy: confusionMatrix.accuracy(),
  test_consumeraccuracy: confusionMatrix.consumersAccuracy(),
  test_produceraccuracy: confusionMatrix.producersAccuracy(),
  test_kappa: confusionMatrix.kappa()
});
print(testaccuracy)
Export.table.toDrive({
  collection: ee.FeatureCollection(testaccuracy),
  description: 'xinmin_corn_acc',
  folder: 'xinmin_corn',
});


//==============================分区计算 =============================
// var bounds = shpfile.geometry().bounds().getInfo().coordinates[0];
// var xmin = bounds[0][0];
// var xmax = bounds[1][0];
// var ymin = bounds[0][1];
// var ymax = bounds[2][1];
// //zhegeshi  0.7duma 

// var dx = 2.3,dy = 1.75;

// // hebei:dx = 2,dy = 1.8; henan:dx = 2,dy = 1.5; shanxi:dx = 3.0,dy = 1.8;
// // shandong,jiangsu,hubei,anhui,shangxi,jiangxi:dx = 2.3,dy = 1.75; xinjiang,gansu:dx = 2.3,dy = 1.8;

// var grid = exports.GenerateGrid(xmin, ymin, xmax, ymax, dx, dy)
//           .filterBounds(shpfile.geometry());
// //fenqude list     
// var GridList = grid.toList(100).length().getInfo();

// print('GridList: ', GridList);

// Map.addLayer(grid, {min: 1, max: 2, palette:['green','red']}, 'grid_all');

// // 分区计算
// for(var i = 0; i < GridList; i++){
//   var grid_ = grid.toList(100).get(i);
//   var shp_grid = ee.Feature(grid_).geometry().difference(shpfile);
//   var grid_single = ee.Feature(ee.Feature(grid_).geometry().difference(shp_grid));
//   // if(i == 0){ Map.addLayer(shp_grid,{},'shp_grid');Map.addLayer(grid_single,{},'grid_single') }
//   var gridcomposition = composition.clip(grid_single.geometry())
  
//   var classified = gridcomposition.classify(classifier);
//   Map.addLayer(gridcomposition,{min: 1, max: 2, palette:['green','red']},"class"+i);

// //daochu
//   Export.image.toDrive({
//     image: classified,
//     description: 'xinmin_corn_grid_'+ i,
//     folder: 'xinmin_corn',
//     fileNamePrefix: 'xinmin_corn_grid_'+ i,
//     region: grid_single,
//     scale: 30,
//     maxPixels: 1e13
//   });
// }

//==============================不分区计算 =============================
// 不分区(区域较小时可不分区)
var classified = composition.classify(classifier);
//==============================可视化显示 =============================
Map.addLayer(classified, {min: 1, max: 2, palette:['green','red']}, 'grid_all');
Export.image.toDrive({
  image: classified,
  description: 'xinmin_corn',
  folder: 'xinmin_corn',
  fileNamePrefix: 'xinmin_corn',
  region: shpfile,
  scale: 30,
  maxPixels: 1e13
});

你可能感兴趣的:(GEE,分类,数据挖掘,人工智能,google,earth,javascript)