GEE利用SAR数据进行洪涝灾害提取以及水体识别

用SAR提取水体和洪涝灾害研究,现将成果分享(完整代码附在最后),代码完成参考了许多大佬的知识结晶。

功能一:得到水域

新建矩形区域aoi,步骤如下:

c6e90a6688ac0edb12a41a15ecd847b6.png

根据如下论文,获取了巢湖洪涝灾害发生的时间,以提取出水域时间。

999ed3d7d2597c4a0aba3a72ff1053f8.png

 

    绘制SAR的灰度直方图,就是后散射系数直方图,利用峰值阈值法(论文里有详细介绍)提取出水域。如下图峰值大概位于-25.

0c11353de089af634da0b7cf11ca9773.png

// ==========添加VH灰度直方图===========

// 获取影像集合
var collection = ee.ImageCollection('COPERNICUS/S1_GRD')
                  .filterBounds(aoi)
                  .filterDate('2020-06-01', '2020-06-10')
                  .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'));

// 选择一个影像
var image = collection.first().select('VH');


// 计算直方图数据
var histogramData = ui.Chart.image.histogram({
  image: image,
  region: aoi,
  scale: 10,
  maxPixels: 1e13 // 增加最大像素限制
});

// 设置横轴刻度间隔为10
var options = {
  title: 'VH Polarization Histogram',
  colors: ['#33a02c'], // 设置颜色
  hAxis: {
    title: 'VH Value',
    ticks: ee.List.sequence(-40, 0, 10), // 设置横轴坐标数值间隔为10
    viewWindow: {
      min: -40,
      max: 0
    }
  },
  vAxis: {
    title: 'Frequency'
  },
  chartArea: {
    backgroundColor: {
      stroke: '#CCCCCC',
      strokeWidth: 1
    }
  },
  legend: {
    position: 'none' // 隐藏图例,因为直方图通常不需要图例
  }
};

// 应用自定义的刻度间隔和颜色
var histogram = histogramData.setOptions(options);

// 添加直方图到控制台
print(histogram);

// ==========添加水体检测===========
// 设置水体阈值,基于 VH 极化数据
var water_threshold = -25; // 这个值可以根据具体情况调整

// 提取水体范围
var before_water = before_filtered.lt(water_threshold).selfMask();
var after_water = after_filtered.lt(water_threshold).selfMask();

// 显示水体范围
Map.addLayer(before_water, {palette: '0000FF'}, 'Water Before Flood', 0);
Map.addLayer(after_water, {palette: '00FF00'}, 'Water After Flood', 1);

// 计算洪水前后的水体面积
var before_water_area = before_water.multiply(ee.Image.pixelArea()).reduceRegion({
  reducer: ee.Reducer.sum(),
  geometry: aoi,
  scale: 10,
  bestEffort: true
}).getNumber('VH').divide(10000).round();

var after_water_area = after_water.multiply(ee.Image.pixelArea()).reduceRegion({
  reducer: ee.Reducer.sum(),
  geometry: aoi,
  scale: 10,
  bestEffort: true
}).getNumber('VH').divide(10000).round();

print('Water area before flood (ha):', before_water_area);
print('Water area after flood (ha):', after_water_area);

功能二:提取出洪涝区域。

利用两景影像的差异提取出洪涝发生区域。

代码如下:

// ==========aoi设置===========
var aoi = ee.FeatureCollection(geometry4);
// ==========时间设置===========
// 洪水发生前的影像时间段
var before_start= '2020-06-01';
var before_end='2020-06-10';
// 洪水发生后的影像时间段
var after_start='2020-09-10';
var after_end='2020-09-15';
// Sentinel - 1 SAR极化方式设置, 这里选用 VH ,也可以使用 VV
var polarization = "VH";
// 设置轨道方式,有上轨道和下轨道,根据研究区的数据有无选择
var pass_direction = "ASCENDING"; // ASCENDING
// 设置变化的阈值,由于基本原理是利用SAR数据在洪水变化前后的差异
var difference_threshold = 1.25;
// ==========影像导入===========
// 选择SAR影像
var collection= ee.ImageCollection('COPERNICUS/S1_GRD')
.filter(ee.Filter.eq('instrumentMode','IW'))
.filter(ee.Filter.listContains('transmitterReceiverPolarisation', polarization))
.filter(ee.Filter.eq('orbitProperties_pass',pass_direction)) 
.filter(ee.Filter.eq('resolution_meters',10))
.filterBounds(aoi)
.select(polarization);
// 筛选洪水前后的SAR数据
// 洪水发生前
var before_collection = collection.filterDate(before_start, before_end);
// 洪水发生后
var after_collection = collection.filterDate(after_start,after_end);
// 对筛选的数据进行镶嵌和裁减
var before = before_collection.mosaic().clip(aoi);
var after = after_collection.mosaic().clip(aoi);
// 对数据进行滤波
// 设置滤波半径
var smoothing_radius = 50;
// 应用滤波
var before_filtered = before.focal_mean(smoothing_radius, 'circle', 'meters');
var after_filtered = after.focal_mean(smoothing_radius, 'circle', 'meters');
// 显示影像
Map.centerObject(aoi,8);
Map.addLayer(before_filtered, {min:-25,max:0}, 'Before Flood',0);
Map.addLayer(after_filtered, {min:-25,max:0}, 'After Flood',1);
// ==========两景影像的差别===========
// 利用洪水发生时的影像减去洪水发生前的影像
var difference = after_filtered.divide(before_filtered);
// 应用预定义的差分阈值并创建泛滥范围掩膜
var threshold = difference_threshold;
var difference_binary = difference.gt(threshold);
var difference_binary = difference_binary.updateMask(difference_binary.eq(1))
// 计算像素的连通性,以消除那些连接到8个或更少邻居的像素
// 这一操作降低了洪水范围的噪音(椒盐现象-小碎点)
var connections = difference_binary.connectedPixelCount()//.reproject(difference.projection(), null, 10);    
var flooded = difference_binary.updateMask(connections.gte(8));
//  去除上述洪水淹没范围中坡度大于5度的区域
// 计算坡度
var DEM = ee.Image('WWF/HydroSHEDS/03VFDEM');
var terrain = ee.Algorithms.Terrain(DEM);
var slope = terrain.select('slope');
// 创建一个图像,只包含高程波段
var elevation = DEM.select('b1');
// 导出图像
Export.image.toDrive({
  image: elevation,
  description: 'HydroSHEDS_Elevation',
  scale: 30, // 根据需要选择合适的缩放比例
  region: aoi
});
// 最终的洪水淹没范围
var flooded = flooded.updateMask(slope.lt(5));
Map.addLayer(flooded,{palette:"0000FF"},'Flooded areas');
// 计算洪水面积
// 将每个像素转化为像元面积
var flood_pixelarea = flooded.select(polarization)
                            .multiply(ee.Image.pixelArea());
 
// 统计所有像元的和,默认的面积是 ㎡
var flood_stats = flood_pixelarea.reduceRegion({
  reducer: ee.Reducer.sum(),              
  geometry: aoi,
  scale: 10, 
  bestEffort: true // 为true时可以减少计算时间
  });
  
// 将 平方米转化为 公顷
var flood_area_ha = flood_stats
  .getNumber(polarization)
  .divide(10000)
  .round();// 四舍五入
  
  // 显示淹没范围面积结果
  print('area/ha', flood_area_ha);
// 导出栅格格式 tif
Export.image.toDrive({
  image: flooded, 
  description: 'Flood_extent_raster',
  fileNamePrefix: 'flooded',
  region: aoi, 
  maxPixels: 1e10
});
 
// 导出shp格式
// 栅格转矢量
var flooded_vec = flooded.reduceToVectors({
  scale: 10,
  geometryType:'polygon',
  geometry: aoi,
  eightConnected: false,
  bestEffort:true,
  tileScale:2,
});
 
// 导出shp结果
Export.table.toDrive({
  collection:flooded_vec,
  description:'Flood_extent_vector',
  fileFormat:'SHP',
  fileNamePrefix:'flooded_vec'
});

根据需求导出文件,将洪涝以及水体的数据转为了shp。

// 导出水体范围栅格格式 tif
Export.image.toDrive({
  image: before_water, 
  description: 'Water_before_flood',
  fileNamePrefix: 'water_before_flood',
  region: aoi, 
  maxPixels: 1e10
});

Export.image.toDrive({
  image: after_water, 
  description: 'Water_after_flood',
  fileNamePrefix: 'water_after_flood',
  region: aoi, 
  maxPixels: 1e10
});

// 导出水体范围矢量格式 shp
var before_water_vec = before_water.reduceToVectors({
  scale: 10,
  geometryType: 'polygon',
  geometry: aoi,
  eightConnected: false,
  bestEffort: true,
  tileScale: 2,
});

var after_water_vec = after_water.reduceToVectors({
  scale: 10,
  geometryType: 'polygon',
  geometry: aoi,
  eightConnected: false,
  bestEffort: true,
  tileScale: 2,
});

Export.table.toDrive({
  collection: before_water_vec,
  description: 'Water_before_flood_vector',
  fileFormat: 'SHP',
  fileNamePrefix: 'water_before_flood_vec'
});

Export.table.toDrive({
  collection: after_water_vec,
  description: 'Water_after_flood_vector',
  fileFormat: 'SHP',
  fileNamePrefix: 'water_after_flood_vec'
});

// 导出遥感影像
Export.image.toDrive({
  image: before_filtered,
  description: 'BeforeFloodFiltered',
  scale: 10, // 导出比例尺,与影像分辨率一致
  region: aoi, // 导出区域
  maxPixels: 1e9 // 最大像素数限制,根据需要调整
});

Export.image.toDrive({
  image: after_filtered,
  description: 'AfterFloodFiltered',
  scale: 10,
  region: aoi,
  maxPixels: 1e9
});

结果图:

31da2aa67e238647f541d37151314ffe.png

完整代码:

// ==========aoi设置===========
var aoi = ee.FeatureCollection(geometry4);
// ==========时间设置===========
// 洪水发生前的影像时间段
var before_start= '2020-06-01';
var before_end='2020-06-10';
// 洪水发生后的影像时间段
var after_start='2020-09-10';
var after_end='2020-09-15';
// Sentinel - 1 SAR极化方式设置, 这里选用 VH ,也可以使用 VV
var polarization = "VH";
// 设置轨道方式,有上轨道和下轨道,根据研究区的数据有无选择
var pass_direction = "ASCENDING"; // ASCENDING
// 设置变化的阈值,由于基本原理是利用SAR数据在洪水变化前后的差异
var difference_threshold = 1.25;
// ==========影像导入===========
// 选择SAR影像
var collection= ee.ImageCollection('COPERNICUS/S1_GRD')
.filter(ee.Filter.eq('instrumentMode','IW'))
.filter(ee.Filter.listContains('transmitterReceiverPolarisation', polarization))
.filter(ee.Filter.eq('orbitProperties_pass',pass_direction)) 
.filter(ee.Filter.eq('resolution_meters',10))
.filterBounds(aoi)
.select(polarization);
// 筛选洪水前后的SAR数据
// 洪水发生前
var before_collection = collection.filterDate(before_start, before_end);
// 洪水发生后
var after_collection = collection.filterDate(after_start,after_end);
// 对筛选的数据进行镶嵌和裁减
var before = before_collection.mosaic().clip(aoi);
var after = after_collection.mosaic().clip(aoi);
// 对数据进行滤波
// 设置滤波半径
var smoothing_radius = 50;
// 应用滤波
var before_filtered = before.focal_mean(smoothing_radius, 'circle', 'meters');
var after_filtered = after.focal_mean(smoothing_radius, 'circle', 'meters');
// 显示影像
Map.centerObject(aoi,8);
Map.addLayer(before_filtered, {min:-25,max:0}, 'Before Flood',0);
Map.addLayer(after_filtered, {min:-25,max:0}, 'After Flood',1);
// ==========两景影像的差别===========
// 利用洪水发生时的影像减去洪水发生前的影像
var difference = after_filtered.divide(before_filtered);
// 应用预定义的差分阈值并创建泛滥范围掩膜
var threshold = difference_threshold;
var difference_binary = difference.gt(threshold);
var difference_binary = difference_binary.updateMask(difference_binary.eq(1))
// 计算像素的连通性,以消除那些连接到8个或更少邻居的像素
// 这一操作降低了洪水范围的噪音(椒盐现象-小碎点)
var connections = difference_binary.connectedPixelCount()//.reproject(difference.projection(), null, 10);    
var flooded = difference_binary.updateMask(connections.gte(8));
//  去除上述洪水淹没范围中坡度大于5度的区域
// 计算坡度
var DEM = ee.Image('WWF/HydroSHEDS/03VFDEM');
var terrain = ee.Algorithms.Terrain(DEM);
var slope = terrain.select('slope');
// 创建一个图像,只包含高程波段
var elevation = DEM.select('b1');
// 导出图像
Export.image.toDrive({
  image: elevation,
  description: 'HydroSHEDS_Elevation',
  scale: 30, // 根据需要选择合适的缩放比例
  region: aoi
});
// 最终的洪水淹没范围
var flooded = flooded.updateMask(slope.lt(5));
Map.addLayer(flooded,{palette:"0000FF"},'Flooded areas');
// 计算洪水面积
// 将每个像素转化为像元面积
var flood_pixelarea = flooded.select(polarization)
                            .multiply(ee.Image.pixelArea());
 
// 统计所有像元的和,默认的面积是 ㎡
var flood_stats = flood_pixelarea.reduceRegion({
  reducer: ee.Reducer.sum(),              
  geometry: aoi,
  scale: 10, 
  bestEffort: true // 为true时可以减少计算时间
  });
  
// 将 平方米转化为 公顷
var flood_area_ha = flood_stats
  .getNumber(polarization)
  .divide(10000)
  .round();// 四舍五入
  
  // 显示淹没范围面积结果
  print('area/ha', flood_area_ha);
// 导出栅格格式 tif
Export.image.toDrive({
  image: flooded, 
  description: 'Flood_extent_raster',
  fileNamePrefix: 'flooded',
  region: aoi, 
  maxPixels: 1e10
});
 
// 导出shp格式
// 栅格转矢量
var flooded_vec = flooded.reduceToVectors({
  scale: 10,
  geometryType:'polygon',
  geometry: aoi,
  eightConnected: false,
  bestEffort:true,
  tileScale:2,
});
 
// 导出shp结果
Export.table.toDrive({
  collection:flooded_vec,
  description:'Flood_extent_vector',
  fileFormat:'SHP',
  fileNamePrefix:'flooded_vec'
});

// ==========添加VH灰度直方图===========

// 获取影像集合
var collection = ee.ImageCollection('COPERNICUS/S1_GRD')
                  .filterBounds(aoi)
                  .filterDate('2020-06-01', '2020-06-10')
                  .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'));

// 选择一个影像
var image = collection.first().select('VH');


// 计算直方图数据
var histogramData = ui.Chart.image.histogram({
  image: image,
  region: aoi,
  scale: 10,
  maxPixels: 1e13 // 增加最大像素限制
});

// 设置横轴刻度间隔为10
var options = {
  title: 'VH Polarization Histogram',
  colors: ['#33a02c'], // 设置颜色
  hAxis: {
    title: 'VH Value',
    ticks: ee.List.sequence(-40, 0, 10), // 设置横轴坐标数值间隔为10
    viewWindow: {
      min: -40,
      max: 0
    }
  },
  vAxis: {
    title: 'Frequency'
  },
  chartArea: {
    backgroundColor: {
      stroke: '#CCCCCC',
      strokeWidth: 1
    }
  },
  legend: {
    position: 'none' // 隐藏图例,因为直方图通常不需要图例
  }
};

// 应用自定义的刻度间隔和颜色
var histogram = histogramData.setOptions(options);

// 添加直方图到控制台
print(histogram);

// ==========添加水体检测===========
// 设置水体阈值,基于 VH 极化数据
var water_threshold = -25; // 这个值可以根据具体情况调整

// 提取水体范围
var before_water = before_filtered.lt(water_threshold).selfMask();
var after_water = after_filtered.lt(water_threshold).selfMask();

// 显示水体范围
Map.addLayer(before_water, {palette: '0000FF'}, 'Water Before Flood', 0);
Map.addLayer(after_water, {palette: '00FF00'}, 'Water After Flood', 1);

// 计算洪水前后的水体面积
var before_water_area = before_water.multiply(ee.Image.pixelArea()).reduceRegion({
  reducer: ee.Reducer.sum(),
  geometry: aoi,
  scale: 10,
  bestEffort: true
}).getNumber('VH').divide(10000).round();

var after_water_area = after_water.multiply(ee.Image.pixelArea()).reduceRegion({
  reducer: ee.Reducer.sum(),
  geometry: aoi,
  scale: 10,
  bestEffort: true
}).getNumber('VH').divide(10000).round();

print('Water area before flood (ha):', before_water_area);
print('Water area after flood (ha):', after_water_area);




// 导出水体范围栅格格式 tif
Export.image.toDrive({
  image: before_water, 
  description: 'Water_before_flood',
  fileNamePrefix: 'water_before_flood',
  region: aoi, 
  maxPixels: 1e10
});

Export.image.toDrive({
  image: after_water, 
  description: 'Water_after_flood',
  fileNamePrefix: 'water_after_flood',
  region: aoi, 
  maxPixels: 1e10
});

// 导出水体范围矢量格式 shp
var before_water_vec = before_water.reduceToVectors({
  scale: 10,
  geometryType: 'polygon',
  geometry: aoi,
  eightConnected: false,
  bestEffort: true,
  tileScale: 2,
});

var after_water_vec = after_water.reduceToVectors({
  scale: 10,
  geometryType: 'polygon',
  geometry: aoi,
  eightConnected: false,
  bestEffort: true,
  tileScale: 2,
});

Export.table.toDrive({
  collection: before_water_vec,
  description: 'Water_before_flood_vector',
  fileFormat: 'SHP',
  fileNamePrefix: 'water_before_flood_vec'
});

Export.table.toDrive({
  collection: after_water_vec,
  description: 'Water_after_flood_vector',
  fileFormat: 'SHP',
  fileNamePrefix: 'water_after_flood_vec'
});

// 导出遥感影像
Export.image.toDrive({
  image: before_filtered,
  description: 'BeforeFloodFiltered',
  scale: 10, // 导出比例尺,与影像分辨率一致
  region: aoi, // 导出区域
  maxPixels: 1e9 // 最大像素数限制,根据需要调整
});

Export.image.toDrive({
  image: after_filtered,
  description: 'AfterFloodFiltered',
  scale: 10,
  region: aoi,
  maxPixels: 1e9
});

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值