基于 GEE 利用 Sentinel-2 数据反演叶绿素与冠层水分含量

目录

1 数据加载与预处理

2 叶绿素含量反演

3 冠层水分反演

4 数据可视化与导出

5 完整代码

6 运行结果


在生态学和环境科学领域,植被的健康状况是评估生态系统稳定性和功能的关键指标之一。而叶绿素含量和冠层水分含量作为反映植被生理状态的重要参数,一直是遥感监测的核心目标。接下来,将通过Google Earth Engine(GEE)平台,分享如何利用Sentinel-2卫星数据反演叶绿素含量和冠层水分含量,并通过代码实现这一过程。

1 数据加载与预处理

在进行生态参数反演之前,需要加载并预处理卫星数据。这里选择了Sentinel-2卫星的“COPERNICUS/S2_SR_HARMONIZED”数据集,它提供了高质量的地表反射率产品,具有10米至60米的空间分辨率,非常适合植被监测。

/******************** 数据加载与预处理 ********************/
var s2 = ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
    // 设置时间范围
    .filterDate('2023-01-01', '2023-11-30')
    // 限定研究区域
    .filterBounds(roi)
    // 筛选云量小于20%的影像
    .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
    // 波段名称标准化
    .map(function (img) {
        return img.rename([
            'B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7',
            'B8', 'B8A', 'B9', 'B11', 'B12',
            'AOT', 'WVP', 'SCL', 'TCI_R', 'TCI_G', 'TCI_B',
            'MSK_CLDPRB', 'MSK_SNWPRB', 'QA10', 'QA20', 'QA60',
            'MSK_CLASSI_OPAQUE', 'MSK_CLASSI_CIRRUS', 'MSK_CLASSI_SNOW_ICE'
        ]);
    })
    // 计算中值合成影像
    .median()
    // 裁剪至研究区域
    .clip(roi);

关键步骤解析:

  1. 时间范围筛选:通过filterDate方法,选择了2023年1月1日至11月30日的数据。您可以根据研究需求调整时间范围。

  2. 云量筛选:通过filter方法结合ee.Filter.lt,剔除了云量超过20%的影像,以减少云层对分析结果的干扰。

  3. 波段名称标准化:Sentinel-2数据的波段名称通常以“B04”、“B05”等形式出现。为了方便后续计算,将波段名称统一更正为“B4”、“B5”等。

  4. 中值合成:通过median方法,计算了中值合成影像,以减少噪声和异常值的影响。

  5. 裁剪至研究区域:使用clip方法将影像裁剪至感兴趣区域(roi

import ee import geemap # 身份验证 try: # 替换为你的实际项目 ID project_id = 'agile-apex-453421-i5' ee.Initialize(project=project_id) except Exception as e: print(f"Error: {e}") ee.Authenticate() ee.Initialize(project=project_id) # 研究区域定义 region = ee.Geometry.Polygon([ [105.17, 28.85], # 西南角 [107.43, 28.85], # 东南角 [107.43, 31.42], # 东北角 [105.17, 31.42] # 西北角 ]) # 时间范围和云量筛选阈值 start_date = '2020-01-01' end_date = '2024-12-31' max_cloud = 10 # % # 加载 Sentinel-2 影像集合(使用新的数据集sentinel = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED') \ .filterDate(start_date, end_date) \ .filterBounds(region) \ .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', max_cloud)) \ .select(['B3', 'B4', 'B8', 'B11']) # 绿、红、近红外、中红外波段 # 测试加载是否成功 print("Sentinel-2 image collection loaded successfully!") # (4) 定义预处理函数 def preprocess(image): # 辐射定标:将 DN 转换为反射率 image = image.multiply(0.0001) # 地形校正(可选) dem = ee.Image('USGS/SRTMGL1_003').select('elevation') slope = ee.Terrain.slope(dem) aspect = ee.Terrain.aspect(dem) corrected = image.divide(slope.sin().add(1e-6)).divide(aspect.cos().add(1e-6)) return corrected # 改进型水体指数 def calculate_mndwi(image): green = image.select('B3') swir = image.select('B11') mndwi = green.subtract(swir).divide(green.add(swir)) return mndwi.rename('MNDWI') # 叶绿素浓度反演 def calculate_chlorophyll(image): # OC3公式:log10(Chl) = -0.344 - 1.625*(Rrs(665)/Rrs(555)) rrs_555 = image.select('B3').multiply(0.0001) # 绿波段反射率 rrs_665 = image.select('B4').multiply(0.0001) # 红波段反射率 ratio = rrs_665.divide(rrs_555) ratio = ratio.where(ratio.lte(0), 1e-6) # 使用 ee.Image.expression 计算以 10 为底的指数 chlorophyll = ee.Image.expression( '10**(log10(ratio) * -1.625 - 0.344)', {'ratio': ratio} ) # 返回带有新波段的影像 return image.addBands(chlorophyll.rename('Chlorophyll')) # 按季度输出均值 def add_quarter(image): date = ee.Date(image.get('system:time_start')) quarter = date.format('YYYY-Qq') return image.set('quarter', quarter) sentinel = sentinel.map(preprocess) sentinel = sentinel.map(calculate_mndwi) sentinel = sentinel.map(calculate_chlorophyll) sentinel = sentinel.map(add_quarter) # 按季度统计 quarterly_stats = sentinel.group( groupField='quarter', groupName='quarter', reducer=ee.Reducer.mean() ) # 导出到本地 # 导出CSV task_csv = ee.batch.Export.table.toDrive( collection=quarterly_stats, description='mndwi_chlorophyll', folder='water_quality', fileFormat='CSV', selectors=['quarter', 'MNDWI_mean', 'Chlorophyll_mean'] ) # 导出GeoTIFF(时间序列) time_series = sentinel \ .map(calculate_mndwi) \ .toBands() task_tiff = ee.batch.Export.image.toDrive( image=time_series, description='mndwi_time_series', folder='water_quality', region=region, scale=10, fileFormat='GeoTIFF' ) # 启动任务 task_csv.start() task_tiff.start() # 后续的绘图代码可以根据实际情况进行调整和执行 哪有错
03-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值