摘要:在GEE中以随机森林为例,基于Landsat 8影像进行地表覆盖分类,内容包括按比例分割训练样本和验证样本、提取训练样本的特征、验证分类器精度、分类结果可视化及导出、计算每一类面积。

在Google Earth Engine (GEE)中包含多种分类模型。

下面我将以随机森林为例,基于Landsat 8影像进行地表覆盖分类。

1.导入Landsat 8数据集:加载你需要的Landsat 8影像。

2.数据预处理:进行影像缩放、去云处理,计算植被指数。

教程可参考:在GEE中如何优雅的加载影像--以Landsat8为例

3.加载样本数据:你需要一些标记好的训练数据(如地表覆盖类型),然后按比例将样本分为训练样本和验证样本。

var sampleData = ee.FeatureCollection("users/lijian960708/examples/sampleData");
sampleData = sampleData.randomColumn("random");
var sample_training = sampleData.filter(ee.Filter.lte("random", 0.7));
var sample_validate = sampleData.filter(ee.Filter.gt("random", 0.7));

4.创建特征集合:提取训练样本的特征(如光谱波段)并构建特征集合。

var training = image_median.sampleRegions({
    collection: sample_training,
    properties: ["landcover"],
    scale: 30,
    tileScale: 16
});
var validation = image_median.sampleRegions({
    collection: sample_validate,
    properties: ["landcover"],
    scale: 30,
    tileScale: 16
});

其中properties参数要与样本数据中表示类型的字段名称保持一致。

5.训练随机森林分类器:使用训练样本训练分类器。

var classifier = ee.Classifier.smileRandomForest(100).train({

    features: training,

    classProperty: "landcover",

    inputProperties: SELECT_BANDS

  });

6.验证分类器精度:使用验证样本验证分类器精度。

var test = validation.classify(classifier);
var confusionMatrix = test.errorMatrix("landcover", "classification");
print("confusionMatrix", confusionMatrix);
print("overall accuracy", confusionMatrix.accuracy());
print("kappa accuracy", confusionMatrix.kappa());
print("User accuracy: ", confusionMatrix.consumersAccuracy());
print("Prod accuracy: ", confusionMatrix.producersAccuracy());

7.分类影像:使用分类器对影像进行分类,并将结果可视化及导出。

var classified = image_median.classify(classifier).clip(roi).toByte();
var color = {min: 1, max: 4, palette: ['green', 'yellow', 'blue', 'red']};
Map.addLayer(classified, color, "classified");
Export.image.toDrive({
  image: classified,
  description: "classified",
  folder: "test ",
  region: roi,
  scale: 30,
  crs: "EPSG:4326",
  maxPixels: 1e13
});

8.计算面积:计算分类结果每一类的面积。

教程参考:在GEE中如何优雅的计算地表覆盖面积

完整代码如下:

var roi = ee.Geometry.Polygon(
        [[[98.76874122458284, 27.476046782884104],
          [98.76874122458284, 26.36424630156598],
          [100.16400489645784, 26.36424630156598],
          [100.16400489645784, 27.476046782884104]]], null, false);
Map.centerObject(roi, 8);                 
var maskclouds = function (img) {
    var cloudShadowBitMask = 1 << 4;
    var cloudsBitMask = 1 << 3;
    var qa = img.select("QA_PIXEL");
    var mask = qa
      .bitwiseAnd(cloudShadowBitMask)
      .eq(0)
      .and(qa.bitwiseAnd(cloudsBitMask).eq(0));
    return img.addBands(img.updateMask(mask), null, true);
};

var applyScaleFactors = function (image) {
    var opticalBands = image
      .select(["Blue", "Green", "Red", "NIR", "SWIR1", "SWIR2"])
      .multiply(0.0000275)
      .add(-0.2).float();
    return image.addBands(opticalBands, null, true);
};

var imageCol = ee.ImageCollection("LANDSAT/LC08/C02/T1_L2")
                  .filterBounds(roi)
                  .filterDate('2021-01-01', '2021-12-31')
                  .map(maskclouds)
                  .select(
                    ["SR_B2", "SR_B3", "SR_B4", "SR_B5", "SR_B6", "SR_B7"],
                    ["Blue", "Green", "Red", "NIR", "SWIR1", "SWIR2"])
                  .map(applyScaleFactors);

var index_dict = {
  'EVI': '2.5 * ((NIR - Red) / (NIR + 6 * Red - 7.5 * Blue + 1))',
  'NDVI': '(NIR - Red) / (NIR + Red)',
  'DVI': 'NIR - Red',
  'RVI': 'NIR / Red',
  'NDWI': '(Green - NIR) / (Green + NIR)',
  'MNDWI': '(Green - SWIR1) / (Green + SWIR1)',
  'NDBI': '(SWIR1 - NIR) / (SWIR1 + NIR)',
  'NDSI': '(Green - SWIR1) / (Green + SWIR1)',
  'LSWI': '(NIR-SWIR1)/(NIR+SWIR1)',
  'AWEI_nsh': '4*(Green-SWIR1)-(0.25*NIR+2.75*SWIR2)',
  'AWEI_sh': 'Blue+2.5*Green-1.5*(NIR+SWIR1)-0.25*SWIR2',
  'NWI': '(Blue-(NIR+SWIR1+SWIR2)) / (Blue+(NIR+SWIR1+SWIR2))',
  'RRI': '(NIR - Red) / (NIR + Red)',
  'BSI': '(Red - Blue) / (Red + Blue)',
  'HUE': '(Green - NIR) / (Green + NIR)'
};                  
var culIndexs = function (imageCol, index_dict) {
    for (var key in index_dict) {
      var map_function = function (image) {
        return image.addBands(
          image.expression(index_dict[key], {
              Blue: image.select("Blue"),
              Green: image.select("Green"),
              Red: image.select("Red"),
              NIR: image.select("NIR"),
              SWIR1: image.select("SWIR1"),
              SWIR2: image.select("SWIR2"),
            }).float().rename(key)
        );
      };
      imageCol = imageCol.map(map_function);
    }
    return imageCol;
};
imageCol = culIndexs(imageCol, index_dict);
var image_median = imageCol.median().clip(roi);
var SELECT_BANDS = image_median.bandNames();
var sampleData = ee.FeatureCollection("users/lijian960708/examples/sampleData");
sampleData = sampleData.randomColumn("random");
var sample_training = sampleData.filter(ee.Filter.lte("random", 0.7));
var sample_validate = sampleData.filter(ee.Filter.gt("random", 0.7));
var training = image_median.sampleRegions({
    collection: sample_training,
    properties: ["landcover"],
    scale: 30,
    tileScale: 16
});
var validation = image_median.sampleRegions({
    collection: sample_validate,
    properties: ["landcover"],
    scale: 30,
    tileScale: 16
});
/**
* 训练
**/
var classifier = ee.Classifier.smileRandomForest(100).train({
    features: training,
    classProperty: "landcover",
    inputProperties: SELECT_BANDS
  });
print(classifier.explain());
/**
* 精度验证
**/
var test = validation.classify(classifier);
var confusionMatrix = test.errorMatrix("landcover", "classification");
print("confusionMatrix", confusionMatrix);
print("overall accuracy", confusionMatrix.accuracy());
print("kappa accuracy", confusionMatrix.kappa());
print("User accuracy: ", confusionMatrix.consumersAccuracy());
print("Prod accuracy: ", confusionMatrix.producersAccuracy());
/**
* 出图
**/
var classified = image_median.classify(classifier).clip(roi).toByte();
var color = {min: 1, max: 4, palette: ['green', 'yellow', 'blue', 'red']};
Map.addLayer(classified, color, "classified");
Export.image.toDrive({
  image: classified,
  description: "classified",
  folder: "test ",
  region: roi,
  scale: 30,
  crs: "EPSG:4326",
  maxPixels: 1e13
});
/**
* 面积
**/
var areaImage = ee.Image.pixelArea().addBands(classified);
var areas = areaImage.reduceRegion({
  reducer: ee.Reducer.sum().group({ groupField: 1, groupName: "landcover" }),
  geometry: roi,
  scale: 30,
  maxPixels: 1e13,
  tileScale: 16
});
var groups = ee.List(areas.get("groups"));
print('各类面积',groups);

var featureList = groups.map(function (group) {
  group = ee.Dictionary(group);
  var area = ee.Number(group.get("sum"));
  area = area.divide(1000000);//转为平方千米
  var landcover = ee.Number(group.get("landcover"));
  var f = ee.Feature(ee.Geometry.Point([0, 0]), {
    landcover: landcover,
    area: area
  });
  return f;
});
var areaFCol = ee.FeatureCollection(featureList);
Export.table.toDrive({
  collection: areaFCol,
  description: 'area',
  folder: 'test'
});

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐