GEE之基于大津算法OTSU的MNDWI水体提取

GEE学习专栏(文章后附源码)

  • 效果图
  • 源码部分

GEE学习专栏(文章后附源码)

  • 效果图
  • 源码部分
NDWI水体提取)
本文是在武汉市梁子湖地区基于大津算法OTSU自动阈值分割对哨兵2号和陆地卫星8号进行了水体提取。从结果来看,哨兵2号提取结果更加精细,究其原因,哨兵2号和陆地卫星8号之间差异主要在于空间分辨率,哨兵2号空间分辨为10m,陆地卫星空间分辨率为30m。

效果图

1、哨兵2号水体提取结果
GEE之基于大津算法OTSU的MNDWI水体提取_第1张图片
2、Landsat 8 OLI 水体提取结果
GEE之基于大津算法OTSU的MNDWI水体提取_第2张图片

源码部分

/*
@author by Lbta
*/

///Landsat based Water Detection
function ND_WI(image,b1,b2,bName)
{
  var WI = image.normalizedDifference([b1,b2]).rename(bName);
  return WI.updateMask(WI.gt(-1).and(WI.lt(1)));
}
var sr = ee.Image('LANDSAT/LC08/C01/T1_SR/LC08_122039_20200828')
var MNDWI_Landsat=ND_WI(sr,'B3','B6','mNDWI');
print(MNDWI_Landsat,'MNDWI_Landsat')
Map.centerObject(MNDWI_Landsat.geometry(),7);
Map.addLayer(MNDWI_Landsat,{min:-1,max:1},'MNDWI_Landsat');//,palette:['red','orange','yellow','blue']

/******************************************************************************/
//Sentimel based water Detection
function maskS2clouds(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 the masked and scaled data, without the QA bands.
  return image.updateMask(mask).divide(10000)
      .select("B.*")
      .copyProperties(image, ["system:time_start"])
}

function addS2VIs(img)
{
  var MNDWI=ND_WI(img,'B3','B11','mNDWI')
  return img.addBands(MNDWI);
}
// Map the function over one year of data and take the median.
// Load Sentinel-2 TOA reflectance data.
var collection = ee.ImageCollection("COPERNICUS/S2_SR")
    .filterDate('2020-08-10', '2020-08-20')
    // Pre-filter to get less cloudy granules.
    .filterBounds(MNDWI_Landsat.geometry())
    .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
    //.map(maskS2clouds)
    .map(addS2VIs);
var MNDWI_S2=collection.select('mNDWI').median();
Map.addLayer(MNDWI_S2.clip(MNDWI_Landsat.geometry()),{min:-1,max:1},'MNDWI_S2');

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]);
}

//Landsat water extraction based on otsu
var histogram = MNDWI_Landsat.reduceRegion({
    reducer: ee.Reducer.histogram(), 
    geometry: MNDWI_Landsat.geometry(), 
    scale: 30,
    maxPixels: 1e13,
    tileScale: 8
  });
  var threshold_Lat = otsu(histogram.get("mNDWI"));
  print(threshold_Lat,'threshold_Landsat')
  var mask = MNDWI_Landsat.gte(threshold_Lat);
  var water_Lands = mask.rename("water");//.updateMask(mask)
Map.addLayer(water_Lands.clip(MNDWI_Landsat.geometry()),{min:0,max:1,palette:['#DDDDDD','#0099FF']},'water_Landsat_otsu_based');
  var water1 = water_Lands.clip(MNDWI_Landsat.geometry(),{min:0,max:1,palette:['#DDDDDD','#0099FF']},'water_Landsat_otsu_based');
//Export image Landsat
Export.image.toDrive({
  image:water1,
  description: 'water1',
  scale:30,
  region:MNDWI_Landsat.geometry(),
  fileFormat: 'GeoTIFF',
  maxPixels:1e13,
});
//Sentinel water extraction based on otsu
var histogram = MNDWI_S2.reduceRegion({
    reducer: ee.Reducer.histogram(), 
    geometry: MNDWI_Landsat.geometry(), 
    scale: 30,
    maxPixels: 1e13,
    tileScale: 8
  });

  var threshold_S2 = otsu(histogram.get("mNDWI"));
  var mask = MNDWI_S2.gte(threshold_S2);
  print(threshold_S2,'threshold_S2')
  var water_S2 = mask.rename("water");//.updateMask(mask) 
Map.addLayer(water_S2.clip(MNDWI_Landsat.geometry()),{min:0,max:1,palette:['#DDDDDD','#0099FF']},'water_S2_otsu_based');
//Export image Sentinel
Export.image.toDrive({
  image:water_S2,
  description: 'water_S2',
  scale:30,
  region:MNDWI_Landsat.geometry(),
  fileFormat: 'GeoTIFF',
  maxPixels:1e13,
});
//Area computer  Landsat
  var waterarea_Landsat_based=ee.Number((((water_Lands.eq(1)).multiply(ee.Image.pixelArea()))
                        .reduceRegion({
                        reducer: ee.Reducer.sum(),
                        geometry: MNDWI_Landsat.geometry(),
                        scale: 30,
                        maxPixels: 1e13,})).get('water'))
print('waterarea_Landsat_based',waterarea_Landsat_based)                       
//Area computer  Sentinel
var waterarea_S2_based=ee.Number((((water_S2.eq(1)).multiply(ee.Image.pixelArea()))
                        .reduceRegion({
                        reducer: ee.Reducer.sum(),
                        geometry: MNDWI_Landsat.geometry(),
                        scale: 30,
                        maxPixels: 1e13,})).get('water'))
print('waterarea_S2_based',waterarea_S2_based)    
   

你可能感兴趣的:(Google,Earth,Engine学习专栏,大数据,云计算,经验分享)