主题思路:
本实验为二分类实验,分类目标包括:玉米、其他(建筑、水体、水稻、 裸地、森林、小麦、道路、大蒜等),采用人工设计的特征指数的时间序列特征为分类依据,选取分类器为:随机森林分类器,并选取样本集中 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 年时存在较大面积的缺失现象。
成果展示:
代码:
//============================创建函数==================================
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
});