恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
基于GEE的雨季Sentinel-2城市土地覆盖分类与随机森林实现
首页
资讯中心
/
基于GEE的雨季Sentinel-2城市土地覆盖分类与随机森林实现
基于GEE的雨季Sentinel-2城市土地覆盖分类与随机森林实现
发布时间:2026/9/19 19:24:13
简介面向具备遥感与地理信息系统基础的研究人员和技术人员这份PDF资源以雨季哨兵二号影像为数据源系统讲解在谷歌地球引擎中实施面向对象的城市土地覆盖分类流程核心方法为随机森林分类器内容涵盖云掩膜、超像素聚类、数字高程模型与坡度变量组合、训练样本准备、模型训练与精度验证等完整环节。资源共一个PDF文件压缩包大小约751KB体量虽小但步骤紧凑适合作为城市土地覆盖制图与谷歌地球引擎实践的操作指南。目前已有八十五人学习下载。文档在说明每一步操作的同时强调关键参数设置的意义并附有额外练习和资源链接方便读者进一步尝试多季节影像分类和不同季节结果对比最终能够从数据导入、特征构建到结果导出获得完整可复现的实践方法。1. 雨季影像做城市土地覆盖分类为什么对象化随机森林更可靠Sentinel-2 影像一到雨季就是大片云和薄雾在 Google Earth Engine 里做城市土地覆盖分类可用像元肉眼可见地缩水。很多人把研究窗口挪到冬季落叶树又把随机森林的结果带偏。反直觉的是雨季影像不必等云散对象化分割配合随机森林精度往往比单期晴空影像更可靠代价只是预处理多写一些代码。对象化就是先把影像切成光谱均匀的超像素再以对象为单位提取特征、训练分类器而不是逐像元硬判。随机森林对高维、带噪声的多类别任务容忍度高两者叠加恰好对付雨季影像的云残留和阴影混淆。下文铺开整条链路影像筛选、云掩膜、SNIC 分割、对象特征提取、随机森林调参与精度验证适合遥感、GIS 从业者和城市监测方向的研究生。2. 随机森林与对象化分类的原理GEE 里决策树投票的对象统计闭环2.1 随机森林的分类逻辑决策树、Bagging 与特征随机性决策树和随机森林的关系一句话讲清随机森林就是一堆互不相同的决策树的投票集合。每一棵树用有放回抽样得到的样本子集训练大约 63% 的对象会被抽中剩下的对象可作为袋外数据估计泛化误差同时每次节点分裂只随机挑选一部分特征做候选降低树与树之间的相关性。分类任务里各树独立投票票数最多的类别胜出GEE 对应的接口是ee.Classifier.smileRandomForest。这里要区分两个高频搜索词随机森林回归算法、随机森林回归预测模型解决的是连续量预测比如不透水面覆盖率或生物量估算标题里的土地覆盖分类输出离散类别用的是随机森林分类器。对象化分类属于后者分类器输出的是类别标签和每个类别的概率不是回归值。遥感随机森林的实践里特征设计对精度的影响往往大于模型参数。随机森林不需要特征归一化可以吃混合类型特征训练后还能直接给出特征重要性排序这让特征筛选环节省掉大量试错。2.2 对象化对比像元级雨季阴影、椒盐噪声与特征维度像元级分类的问题在雨季被放大得很明显。一个阴影里的建筑屋顶与一片水体在近红外波段的反射特征可能非常接近逐像元硬判时相邻像元经常被分成不同类别形成细碎椒盐噪声。对象化先用分割算法把影像聚成超像素对象的平均光谱天然平滑了局部云残留更重要的是对象提供了像元没有的信息——面积、周长、对象内光谱方差这些几何与纹理特征是区分建设用地和裸地、水体和阴影的关键。维度像元级分类对象化分类分类单元单个像元分割后的超像素对象抗椒盐噪声差需要后处理滤波好分类结果即对象特征来源以光谱为主光谱、纹理、几何均可样本量需求大小但样本要覆盖对象多样性GEE 计算量低分割与归约环节较高表格里最后一行的计算量差异要记住GEE 上对象化不是一次采样就能完成分割、矢量化、逐对象统计三步都要跑处理城区尺度时要把maxPixels和导出任务分开考虑。2.3 从分割到分类的对象闭环SNIC、reduceRegions 与 smileRandomForest落到代码层面对象化随机森林是一条固定闭环先对多波段影像做 SNIC 分割得到对象编号用reduceToVectors把对象转成矢量再用reduceRegions按对象统计光谱指数与纹理特征采集带类别标签的样本训练随机森林最后对全部对象分类并栅格化出图。每一步输入输出独立可查出了问题好定位。var rf ee.Classifier.smileRandomForest({ numberOfTrees: 300, variablesPerSplit: 0, // 0 表示每次分裂随机取特征数的平方根 minLeafPopulation: 5, bagFraction: 0.6, seed: 42 });先记住这个接口长什么样numberOfTrees是树的棵数variablesPerSplit控制每次分裂的候选特征数minLeafPopulation限制叶节点最小样本数bagFraction是每棵树的抽样比例seed固定随机数种子保证结果可复现。这个闭环里最容易出错的是尺度匹配SNIC 分割、reduceToVectors、reduceRegions的scale必须保持一致否则对象边界的像元归属会错位后面调参全白费。3. 雨季 Sentinel-2 数据预处理Google Earth Engine 里筛影像、云掩膜与 SNIC 分割3.1 雨季影像筛选日期窗口、整景云量与中值合成数据源推荐COPERNICUS/S2_SR_HARMONIZED它是地表反射率产品对 Sentinel-2A 和 2B 做了波段一致性校正做城市分类比 L1C 大气层顶反射率更贴近真实地表。雨季不像冬季有稳定的晴空窗口单景影像很难同时满足云量低、覆盖完整两个条件常见做法是取一个时间窗口内的多景影像做中值合成。var roi ee.FeatureCollection(users/yourname/study_aoi).geometry(); // 替换为自己的研究区 var s2 ee.ImageCollection(COPERNICUS/S2_SR_HARMONIZED) .filterBounds(roi) .filterDate(2023-06-01, 2023-09-30) // 雨季节点 .filter(ee.Filter.lt(CLOUDY_PIXEL_PERCENTAGE, 30)) .map(maskClouds); // maskClouds 在 3.2 节定义 var composite s2.median().clip(roi);CLOUDY_PIXEL_PERCENTAGE是影像元数据里的整景云量比例先用它粗筛雨季南方城市阈值取 30 以下能留几景就留几景因为中值合成需要样本量。median()对云和薄雾的抗性来自分位数统计同一位置六景影像里即使有三景被云污染中值仍然接近真实地表反射率。注意roi不要用整省范围先裁剪到研究区否则后面maxPixels一炸全重来。提示窗口内可用影像少于三景时中值合成会失效优先拉长日期窗口而不是放宽云量阈值。3.2 s2cloudless 云掩膜MSK_CLDPRB 阈值与 QA60 补漏中值合成能压掉随机云残留但对厚云边缘仍然力不从心需要逐像元掩膜。S2_SR_HARMONIZED里MSK_CLDPRB是 s2cloudless 模型输出的云概率0–100QA60的 bit10 和 bit11 分别标记不透明白云与卷云。function maskClouds(img) { var qa img.select(QA60); var cloud qa.bitwiseAnd(1 10).gt(0); // bit10 为白云 var cirrus qa.bitwiseAnd(1 11).gt(0); // bit11 为卷云 var prob img.select(MSK_CLDPRB).gte(50); // s2cloudless 概率阈值 return img.updateMask(cloud.or(cirrus).or(prob).not()); }MSK_CLDPRB阈值 50 是常用起点雨季想激进一些可以放到 40代价是保留像元变少。QA60补的是 s2cloudless 容易漏掉的薄卷云两层一起用比只信一层放心。掩膜必须放在合成之前保证进入中值统计的都是干净像元。这条链路不处理阴影阴影是光谱混淆问题靠对象特征和类别设计去缓解不要指望掩膜把阴影抹掉。3.3 SNIC 分割的三个参数size、compactness 与 connectivity分割是对象化的核心。GEE 内置的 SNICSimple Non-Iterative Clustering是 SLIC 的非迭代版本在云端执行速度快、参数少。输入影像建议选 10m 波段加一两个指数全波段丢进分割会让compactness失去调节意义计算量还翻倍。var ndvi composite.normalizedDifference([B8, B4]).rename(NDVI); var ndwi composite.normalizedDifference([B3, B8]).rename(NDWI); var segImage composite.addBands([ndvi, ndwi]); var snic ee.Algorithms.Image.Segmentation.SNIC({ image: segImage.select([B2, B3, B4, B8, NDVI, NDWI]), size: 16, compactness: 2, connectivity: 8, neighborhoodSize: 256 }); var clusters snic.select(clusters); // 对象编号栅格 Map.addLayer(clusters.randomVisualizer(), {}, SNIC 对象);参数经验如下表size是超像素目标边长像元不是面积compactness越大对象越方正越小越贴合地物边界connectivity管对象连通方式8 邻域在城市里更贴合道路与建筑轮廓。参数作用常用范围雨季城市建议size超像素边长像元83216建筑密集区可降到 12compactness形状约束权重152优先贴合边界connectivity邻域连通方式4 / 88neighborhoodSize搜索窗口128512256过大内存开销高分割完成后把对象轮廓矢量化并顺手算面积和周界后面特征提取和面积过滤都要用var objects clusters.reduceToVectors({ geometry: roi, scale: 10, eightConnected: true, maxPixels: 1e8 }).map(function (f) { return f.set(area, f.area()).set(perimeter, f.length()); }); print(对象数量, objects.size());reduceToVectors是整条链路里最耗配额的一步。整景 10m 影像全量矢量化很容易触发maxPixels或内存超限先把roi裁小或者把size调到 16 以上降低对象数量。对象数量级别出来后特征提取才有东西可算。4. 对象特征提取与随机森林训练调参从 reduceRegions 到混淆矩阵4.1 样本怎么采对象级标签、类别体系与独立性对象化分类的样本单位是对象不是像元。点样本落进同一个对象时只代表一个对象验证精度会虚高。我一般先完成分割再让训练面与对象相交、取面积最大的类别作为对象标签每类至少 80150 个对象。城市土地覆盖推荐五类起步不透水面、植被、水体、裸土、阴影。阴影单独成类是雨季分类的关键技巧——阴影里的屋顶和树在光谱上很难与水体区分与其硬分不如先标出阴影类制图阶段再按专题需求归并。提示训练样本与验证样本必须按对象划分同一对象内的点不能一半进训练一半进验证否则 Kappa 会虚高。4.2 对象特征矩阵光谱均值分位数、指数与几何属性特征工程的目标是让每个对象被一组向量描述。光谱部分取原始波段加 NDVI、NDWI、BSI按对象归约出均值、标准差和分位数。var bsi composite.expression( ((b11 b4) - (b8 b2)) / ((b11 b4) (b8 b2)), {b11: composite.select(B11), b4: composite.select(B4), b8: composite.select(B8), b2: composite.select(B2)} ).rename(BSI); var featureImage composite.select([B2, B3, B4, B8, B11, B12]) .addBands([ndvi, ndwi, bsi]); var reducer ee.Reducer.mean() .combine(ee.Reducer.stdDev()) .combine(ee.Reducer.percentile([10, 50, 90])); var objectFeatures featureImage.reduceRegions({ collection: objects, reducer: reducer, scale: 10 });reduceRegions按对象矢量统计每个波段。标准差捕捉对象内部光谱异质性——屋顶上的空调机群会让对象标准差明显大于水面分位数比均值对异常像元更鲁棒。特征名会自动带上后缀如B8_p10训练前把含centroid等无关字段的列剔掉。几何特征直接用前一章算好的area和perimeter形状因子用perimeter.divide(area.sqrt())现场算对规则的人工地物和自然边界区分度很高。4.3 随机森林训练参数一张表看清 numberOfTrees 与 minLeafPopulation样本准备好后先用randomColumn按对象做 7:3 划分再训练。注意划分发生在对象集合上同一对象的特征不会跨集合这正是上一节强调的独立性。var sample objectFeatures.randomColumn(rand); var trainSet sample.filter(ee.Filter.lt(rand, 0.7)); var valSet sample.filter(ee.Filter.gte(rand, 0.7)); var rf ee.Classifier.smileRandomForest({ numberOfTrees: 300, variablesPerSplit: 0, // 0 特征数的平方根 minLeafPopulation: 5, bagFraction: 0.6, seed: 42 }).train({features: trainSet, classProperty: class}); print(特征重要性, rf.explain()); var classifiedImage objectFeatures .classify(rf) .reduceToImage({properties: [classification], reducer: ee.Reducer.first()}) .reproject({crs: composite.projection(), scale: 10});最后一段把分类结果从对象集合还原成栅格每个像元只属于一个对象ee.Reducer.first()取到的就是该对象的类别reproject保证与合成影像网格对齐。参数默认调参方向雨季场景说明numberOfTrees10100300超过 300 边际收益递减耗时线性上涨variablesPerSplit0√p特征多时试 5820 维左右特征用默认即可minLeafPopulation1515对象标签有噪声调大更稳bagFraction0.50.60.8样本少时调大单树更稳maxNodes不限30100主要用来限制过拟合print(特征重要性, rf.explain())返回的特征重要性排序可以直接用于降维把排末尾的纹理波段删掉重训精度往往不掉反升。4.4 精度验证混淆矩阵、Kappa 与类别级误差验证走errorMatrix输入是验证集上真实类别与预测类别的对比var validated valSet.classify(rf); var cm validated.errorMatrix(class, classification); print(总体精度, cm.accuracy()); print(Kappa, cm.kappa()); print(混淆矩阵, cm);accuracy()是总体精度kappa()是剔除随机一致后的 Kappa真正要逐类看的是混淆矩阵里的生产者精度和用户精度。雨季最常见的翻车点不是总体精度低而是水体类和阴影类互吞总体精度 90% 但阴影类用户精度不到 60%。这类类别级问题在混淆矩阵里一眼可见比只看总体精度有用得多。5. 雨季城市随机森林分类的三个排错技巧云残留、对象破碎与类别混淆5.1 云残留回查掩膜阈值、合成窗口与有效像元占比分类图上出现成片云斑被分进不透水面或裸土先回查两处MSK_CLDPRB阈值是否太松参与中值合成的影像到底有几景。雨季节点整景云量 30 的影像研究区里也可能整块被云压着。三个可靠做法把日期窗口拉长到四个月保证每处像元有五景以上参与合成把median()换成reduce(ee.Reducer.percentile([20]))低分位数对厚云更不敏感掩膜后统计每景有效像元占比低于 10% 的整景剔除。云影比云麻烦掩膜不处理只能靠类别体系里的阴影类兜底。5.2 对象破碎分割尺度、面积过滤与多数滤波分割过细时一个屋面被切出十几块分类结果像打补丁。先调 SNIC 的size12、16、20 逐步放大compactness往 2 以下调让边界更贴合地物对象矢量化后用面积过滤一次性清掉碎块objects.filter(ee.Filter.gte(area, 200))面积属性单位是平方米阈值根据研究区地物尺度调整。栅格输出仍有椒盐感时对分类结果做一次多数滤波var smoothed classifiedImage.focalMode({radius: 1, kernelType: square});半径 1 比半径 3 保守优先用小半径滤波半径过大反而会把细小的道路和河道抹掉。5.3 类别混淆定位混淆矩阵、特征重要性与类别合并水体与阴影互吞是雨季城市分类最高频的混淆。定位方法先看混淆矩阵哪两个类别交叉最高再回到rf.explain()看这两个类别更依赖哪些特征。常见解法是补充 NDWI 或 SWIR1 波段的分位数特征——水面在短波红外的吸收比阴影里的屋顶更强。加特征后混淆仍在就承认当前特征分不开把阴影类单独保留制图阶段按业务归并这是最务实的收尾。每次调完特征或参数用同一份seed重训、同一份验证集重算混淆矩阵纵向对比才有意义。本文还有配套的精品资源点击获取