背景:有小伙伴需要计算近20年间每月的MNDWI合成图,大津算法OTSU提取水体,并自动导出水体二值图。
该程序实现了,计算每个月的合成图像组合成imageCollection,再计算该集合的MNDWI,大津算法OTSU提取水体,并自动导出水体二值图。
话不多说,直接上代码。
// author by lvbta;
// email: z20160108@s.upc.edu.cn;
var geometry =
/* color: #d63000 */
/* shown: false */
/* displayProperties: [
{
"type": "rectangle"
}
] */
ee.Geometry.Polygon(
[[[112.98527995989568, 30.082709101129765],
[112.98527995989568, 29.59669322410755],
[113.63896648333318, 29.59669322410755],
[113.63896648333318, 30.082709101129765]]], null, false);
// landsat8 2013-04-11-------2020-12-31
var landsat8 = ee.ImageCollection("LANDSAT/LC08/C02/T1_L2").filterBounds(geometry);
// computer mndwi for landsat8
function computermNdwi(image)
{
var mndwi = image.normalizedDifference(['SR_B3','SR_B5']).rename('mndwi');
return mndwi.updateMask(mndwi.gt(-1).and(mndwi.lt(1)));
}
//otsu算法
function otsu(histogram) {
var counts = ee.Array(ee.Dictionary(histogram).get('histogram'));
var means = ee.Array(ee.Dictionary(histogram).get('bucketMeans'));
var size = means.length().get([0]);
var total = counts.reduce(ee.Reducer.sum(), [0]).get([0]);
var sum = means.multiply(counts).reduce(ee.Reducer.sum(), [0]).get([0]);
var mean = sum.divide(total);
var indices = ee.List.sequence(1, size);
var bss = indices.map(function(i) {
var aCounts = counts.slice(0, 0, i);
var aCount = aCounts.reduce(ee.Reducer.sum(), [0]).get([0]);
var aMeans = means.slice(0, 0, i);
var aMean = aMeans.multiply(aCounts)
.reduce(ee.Reducer.sum(), [0]).get([0])
.divide(aCount);
var bCount = total.subtract(aCount);
var bMean = sum.subtract(aCount.multiply(aMean)).divide(bCount);
return aCount.multiply(aMean.subtract(mean).pow(2)).add(
bCount.multiply(bMean.subtract(mean).pow(2)));
});
return means.sort(bss).get([-1]);
}
// landsat8 2014-2020
function seclectMonthly(imageCol,startYear){
for(var i=1;i<=7;i++){
for(var j=1;j<=12;j++){
var NN = startYear+i-1
var imN = ee.String(NN.toString()).cat('-').cat(ee.String(j.toString()))
var yearName = ee.String(NN.toString()).cat('year').cat(ee.String(j.toString()).cat('month'))
yearName = ee.Image(computermNdwi(imageCol.filterDate(ee.String(NN.toString()).cat('-01-01'),ee.String(NN.toString()).cat('-12-31')).filter(ee.Filter.calendarRange(j,j,'month')).mean().clip(geometry)));
//print(ee.Image(yearName).select('mndwi'))
var histogram = yearName.reduceRegion({
reducer: ee.Reducer.histogram(),
geometry: geometry,
scale: 30,
maxPixels: 1e13,
tileScale: 8
});
var threshold = otsu(histogram.get("mndwi"));
var mask = yearName.gte(threshold);
var water = mask.rename("water").setMulti({'time':imN});//.updateMask(mask)
new_imageCol = new_imageCol.add(water)
}
}
return ee.ImageCollection(new_imageCol)
}
var new_imageCol = ee.List([]);
var new_imag = seclectMonthly(landsat8,2014,new_imageCol);
print(new_imag)
Map.addLayer(new_imag.first(),{min:0,max:1,palette:['black','blue']},'water_landsat8_otsu_based')
//export water
function exportImageCollection(imgCol) {
var indexList = imgCol.reduceColumns(ee.Reducer.toList(), ["system:index"])
.get("list");
var namE = ee.List(imgCol.reduceColumns(ee.Reducer.toList(), ["time"])
.get("list"));
namE.evaluate(function(indexs) {
for (var i=0; i<indexs.length; i++) {
var fileN = ee.String(namE.get(i))
var image = imgCol.filter(ee.Filter.eq("system:index", indexs[i])).first();
image = image.toInt16();
Export.image.toDrive({
image: image,
description:indexs[i] ,
fileNamePrefix: indexs[i],
//region: table.geometry().bounds(),
scale: 30, //分辨率
crs: "EPSG:4326",
fileFormat:'GeoTIFF',
maxPixels: 1e13
});
}
});
}
exportImageCollection(new_imag)