使用GEE处理EUCROPMAP 2018欧洲10米分辨率21类土地分类数据全流程
1. 先说重点这套数据解决了什么问题做欧洲尺度的农业遥感最头疼的一件事就是地物类别不够细。全球通用的土地覆盖产品像 ESA WorldCover 那种能告诉你哪块是农田、哪块是森林但没人告诉你这块农田种的是玉米还是油菜。如果只是宏观看一下够用一旦进入作物种植结构分析、补贴核查、产量估算这类业务场景粒度完全不够。EUCROPMAP 2018 就是为这个缺口设计的。它由欧洲委员会联合研究中心Joint Research Centre简称 JRC发布基于 Sentinel-1 和 Sentinel-2 时序影像生产空间分辨率 10 米覆盖整个欧洲把地表划分为 21 类。注意谷歌地球引擎GEE上直接搜索 EUCROPMAP 往往找不到官方托管的影像集合但数据可以从 JRC 官网下载后上传到 GEE 处理。标题里“Google Earth EngineGEE——欧洲10米分辨率土地分类21种分类EUCROPMAP 2018 数据”这个表述实际对应的就是这条“官网下载 GEE 上传分析”的完整链路。给不熟悉的朋友说人话你可以把它理解成一张覆盖全欧洲的“农作物地图”每个 10 米×10 米的像素都被贴上一个标签告诉大家这里是什么。这张图能支撑的需求场景包括国家或大区尺度的作物种植面积统计特定作物的空间分布提取比如找出所有向日葵田多年度种植结构变化分析需要配合 2019、2020 等年份数据与气象、土壤数据叠加做适宜性评估作为样本点生成工具辅助训练更精细的分类模型。这篇文章面向的读者是已经在 GEE 里跑过一些基础代码、想上手处理大区域土地分类数据但被“怎么把外部数据弄进 GEE”“坐标系怎么整”“类别编号怎么对应”这类问题卡住的人。我会把从下载、预处理、上传到计算的完整路径讲清楚顺手把这条路上几个坑填平。2. 21 类到底是什么分类体系和生产思路2.1 分类体系不是空泛的“土地利用”而是细化到作物类型EUCROPMAP 2018 的 21 类包含两个层次农业用地内的具体作物类型和非农业用地覆盖类型。下面这份映射表是我在实际处理中整理出来的不同分发版本的字段名可能略有差异类别编号类别名称说明1夏季谷物以春小麦、春大麦为主2玉米整个欧洲的粒用玉米和青贮玉米3冬季谷物冬小麦、冬大麦、黑麦等4油菜冬油菜为主少量春油菜5向日葵通常夏季播种6根茎类作物马铃薯、甜菜等7苜蓿多年生豆科牧草8其他豆类豌豆、蚕豆等9草地/牧场永久性草地非轮作10果园苹果、梨、核果类11葡萄园酿酒葡萄和鲜食葡萄12橄榄园地中海沿岸典型作物13休耕地当年未种植14其他多年生作物坚果、其他浆果类15温室/大棚设施农业用地16林地所有森林类型17水域河流、湖泊、水库18城市建成区不透水面为主19其他土地裸地、岩石等20湿地永久性沼泽21其他作物无法归入上述类别的作物提示类别编号在不同年份的 EUCROPMAP 产品中可能有调整。比如 2019 年份的编码和 2018 就不完全一致下载后第一件事是打开类别说明文档核对而不是想当然拿去年的表去套。后面第 4 节会专门讲这个坑。这套分类体系生产时核心思路是把 Sentinel-1 的 SAR 后向散射时间序列和 Sentinel-2 的光谱指数时间序列拼接成特征张量再用随机森林训练。JRC 训练时用了大量 LUCAS 实地调查点作为样本这是它能覆盖 21 类的主要原因——纯靠遥感光谱很难稳定区分小麦和大麦这种光谱相近的作物必须有足够的样本支撑。2.2 分辨率、坐标系和瓦片组织三个必须较真的硬指标官方数据采用的投影是 ETRS89 / LAEA Europe即 EPSG:3035。这是欧洲标准的等积投影好处是面积变形小做面积统计时非常友好。但问题也来了EPSG:3035 不是 Web Mercator直接扔进 GEE 的 WGS84 逻辑里不做重投影处理会出现错位和面积误差。分辨率方面EPSG:3035 投影下的真实地面分辨率是 10 米这是等积投影下的定义如果强行转成 EPSG:4326经纬度每个像素的经度方向实际宽度随纬度变化不再是严格的 10 米。所以很多人在 GEE 里计算面积时喜欢靠scale10参数一算在 DGG 投影下误差不明显但放到欧洲这么靠北的地区误差能到百分之几到百分之十几后面专门展开。数据瓦片组织上JRC 官网按地理格网分块提供下载一块大约是 2°×2°经纬度格网全欧洲有几百个 GeoTIFF 文件。如果你只做某个国家可以只下载覆盖那个国家的几个瓦片如果做全欧洲那得写脚本批量拉取手动点击不太现实。3. 从官网下载到上传 GEE我实测过的一条完整链路3.1 下载前必须先做的分块规划很多人第一步就栽在这直接挑感兴趣的瓦片下下了十几个 GeoTIFF然后发现相邻瓦片之间投影、分辨率、像素对齐都没问题但上传时 GEE 单资产有大小限制一块 2°×2° 的 10 米数据全欧洲范围内面积大点的地方一个瓦片就能到 1GB 以上单个资产上传容易失败或超限。我的建议是下载前先想清楚研究区在研究区矢量边界上叠加 JRC 的瓦片格网确定需要哪些瓦片下载后先用 GDAL 合并gdal_merge.py或gdalbuildvrt再按行政边界裁剪一次压缩体积如果合并后仍超过 GEE 单资产限制就按 1°×1° 或按国别切成多块分别上传。JRC 官网下载支持按瓦片选择也提供整个欧洲的完整 GeoTIFF 下载入口。我做某国项目时通常是下载覆盖该国及其周边缓冲区的约 20 到 30 个瓦片合并后裁剪大概 2GB 左右转成 Cloud Optimized GeoTIFF 后上传 GEE 就非常顺。3.2 用 GDAL 做合并、重投影和裁剪在本地处理时我常用的工具是 GDAL 命令行和 QGIS。核心命令如下。假设瓦片下载到tiles/目录# 用 VRT 合并速度快不产生中间文件 gdalbuildvrt eucropmap_merged.vrt tiles/*.tif # 裁剪到研究区范围用 GeoJSON 或 Shapefile gdalwarp -cutline study_area.geojson -crop_to_cutline \ -dstnodata 0 -overwrite \ eucropmap_merged.vrt eucropmap_cropped.tif # 转成 Cloud Optimized GeoTIFF方便 GEE 读取 gdal_translate -co TILEDYES -co COMPRESSDEFLATE -co PREDICTOR2 \ eucropmap_cropped.tif eucropmap_cropped_cog.tif注意几个细节原数据有空值区域合并时建议显式设置-dstnodata 0。原产品的背景值一般是 0但要确认一下你下载的版本里背景是不是0有的版本可能用255或65535这种标记搞错了后续面积统计会多出一大块“第 0 类”。不需要提前重投影到 EPSG:4326。GEE 上传时支持保留原始投影上传后 GEE 会自动按需求重投影提前转反而容易引入插值误差。如果你在 QGIS 里处理需要检查属性表是否保留了类别字段。EUCROPMAP 的单波段 GeoTIFF像素值就是类别编码没有额外属性表所以 GDAL 处理后通常就是一个 Int16/UInt8 单波段文件。3.3 GEE 上传参数这里踩过的坑比想象中多上传数据到 GEE 的入口是Assets → New → Image upload。很多人在这里手滑参数没填对几何位置错得离谱。规范的填法Asset ID建议用projects/你的项目/assets/eucropmap_2018_v1这种层次化命名方便后续管理多个版本Source files选择刚才生成的 COG 文件Coordinate reference system下拉框里如果找不到EPSG:3035选择EPSG:3035自定义输入或者直接留空让 GEE 从 GeoTIFF 内部读取投影信息。留空通常更靠谱因为 GDAL 写入的投影信息是完整的FiletypeGeoTIFF。上传后先在 GEE 里检查一下var cropMap ee.Image(projects/your-project/assets/eucropmap_2018_v1); print(cropMap.projection()); print(cropMap.bandNames()); Map.addLayer(cropMap, {min: 0, max: 21}, EUCROPMAP 2018);如果投影显示EPSG:3035波段名是b1或classification那就成功了一大半。假如这里发现几何位置偏移到海里去了基本是 GeoTIFF 内部坐标参考信息丢失重新用 GDAL 写一遍投影信息。4. GEE 里最容易集体翻车的地方类别映射与面积统计4.1 不要凭记忆写类别映射表这是我在帮某团队排查结果“整体不对”时最常见的病根。EUCROPMAP 的类别编号并不是按我在第 2 节列表那种顺序简单排列的而是按照 JRC 内部定义编码。具体表现是有人把分类结果按 1 到 21 的连续数值猜测了含义画出来的图里水域占满整个阿尔卑斯山草地变城市结论完全反了。正确做法到 JRC 数据下载页面找到该年份的类别说明文档通常是一个 Excel 或 PDF确认类别编号和名称的对应关系在 GEE 里把cropMap的直方图打出来统计 0 到 21 各个类别的像素数先排除背景值问题再写下映射代码。类别映射代码示例var classNames [ {value: 1, name: summer_cereals}, {value: 2, name: maize}, // 这里必须根据官方文档逐一填写不要照抄其他来源的编号 ]; var remap cropMap.remap( [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21] );这段代码看着什么都没做但实际作用是确认了类别取值范围和个数。如果下载的版本类别数不是 21或者某类缺失remap会直接报错比后面统计时发现莫名其妙多一类的排查成本低得多。4.2 面积统计别用像素数乘以 100 糊弄自己10 米分辨率每个像素面积是 100 平方米很多人直接数像素数乘 100觉得精度够了。这个做法在投影变形小的低纬度地区勉强说得过去在欧洲高纬度用 EPSG:3035 原始投影算误差不算大但如果数据被重投影到 Web MercatorEPSG:3857或直接以 4326 坐标系跑每个像素对应的地面面积在南北方向上差别很大。正确做法是结合ee.Image.pixelArea()它能返回每个像素的真实球面面积。统计某类总面积的标准写法var areaImage cropMap.eq(2).multiply(ee.Image.pixelArea()); var totalArea areaImage.reduceRegion({ reducer: ee.Reducer.sum(), maxPixels: 1e13, scale: 10, bestEffort: true, geometry: studyRegion }); print(总面积单位平方米, totalArea.get(classification));关键点reduceRegion里的scale参数填多少取决于你希望计算在什么分辨率下进行。如果源数据是 EPSG:3035 的 10 米这里填10没问题如果进行了reproject或reduceRegion未指定crsGEE 可能默认在 WGS84 下按scale取样导致面积统计偏差。稳妥做法是指定crs参数为原始投影var totalArea areaImage.reduceRegion({ reducer: ee.Reducer.sum(), maxPixels: 1e13, crs: cropMap.projection(), scale: 10, geometry: studyRegion });我测过一个中等国家的玉米面积用crs: cropMap.projection()的计算结果和官方提供的参考统计相差不到 2%而直接用默认投影计算误差能到 8% 以上。对于面积统计类任务这已经不是可以忽略的误差了。4.3 可视化样式让分类图不辣眼睛的设计小技巧EUCROPMAP 输出到地图上如果不设置 paletteGEE 默认的灰度渲染会让 21 类完全分不清。建议初始化一个可视化参数对象var visParams { min: 1, max: 21, palette: [ #ffff00, // 夏季谷物 #ff9900, // 玉米 #ccff33, // 冬季谷物 #99ff99, // 油菜 #ffcc00, // 向日葵 #996633, // 根茎类 #cccc99, // 苜蓿 #ccffcc, // 其他豆类 #cc9966, // 草地/牧场 #33cc00, // 果园 #993399, // 葡萄园 #3399ff, // 橄榄园 #cccccc, // 休耕地 #666600, // 其他多年生 #ffcccc, // 温室 #003300, // 林地 #0000ff, // 水域 #ff0000, // 城市 #808080, // 其他土地 #00ffff, // 湿地 #ffffcc // 其他作物 ] }; Map.addLayer(cropMap, visParams, EUCROPMAP 2018 Vis);配色没有统一标准但有序原则是作物类用黄绿暖色系非植被类用灰蓝冷色系城市用醒目的红色/深色水体用蓝色。这样图面第一眼就能看出农业区分布而不是一堆色块挤在一起。5. 上传后的实际应用从画图到出结论5.1 指定区域、指定类别一键统计最常用的需求是某国的某省2020 年玉米种植面积是多少。这需要 2018 年 EUCROPMAP 不能直接回答但如果你做的是同区域 2018 年的基准数据可以先跑通流程var country ee.FeatureCollection(FAO/GAUL/2015/level1) .filter(ee.Filter.eq(ADM1_NAME, 某省名字)); var cornArea cropMap.eq(2) .multiply(ee.Image.pixelArea()) .reduceRegion({ reducer: ee.Reducer.sum(), geometry: country.geometry(), crs: cropMap.projection(), scale: 10, bestEffort: true }); print(cornArea);顺便说一句GAUL 数据集在 GEE 里有时会被标记为 deprecated但 2015 版还能访问。如果图省事用它没问题如果做正式报告建议用你本地更准确的行政区边界上传为ee.FeatureCollection。5.2 把 EUCROPMAP 当作样本标签源来用很多人不知道EUCROPMAP 的价值不只是出图它还能当“免费的训练样本库”。做法是提取某一类别比如葡萄园的像素随机生成采样点把这些点和对应的 Sentinel-2 影像块配对作为训练数据集训练自己的分类模型因为 EUCROPMAP 本身有误差采样时最好加一个“纯度筛选”比如只保留类别置信度高的斑块——不过 2018 版本没有附带逐像素置信度波段一种替代方法是剔除小斑块连接组分分析后面积小于一定阈值的斑块不要。这个思路在我做作物精细分类时非常实用节省了大量野外采样时间。代价是模型有系统误差的风险因为标签本身继承了 EUCROPMAP 的错分噪声所以如果预算允许至少要用一部分独立实地验证点做精度评估。5.3 与 2019、2020 年份数据叠加做变化检测如果你手头有其他年份的 EUCROPMAP 版本可以直接做作物结构变化矩阵var map2019 ee.Image(projects/your-project/assets/eucropmap_2019_v1); var change cropMap.multiply(100).add(map2019); var changeCounts change.reduceRegion({ reducer: ee.Reducer.frequencyHistogram(), geometry: studyRegion, crs: cropMap.projection(), scale: 10, maxPixels: 1e13 }); print(changeCounts);变化矩阵里值由“2018 类别 × 100 2019 类别”构成。例如 2018 是 2玉米、2019 是 3冬季谷物变化值为 203。这个思路可以搬到任意两个年份上用来快速找出耕地“改种”的热点区域。实际跑的时候内存占用很大建议按区域分块统计或者用reduceRegion时指定tileScale参数比如tileScale: 4减少单线程任务量避免 GEE 内存超限。6. 结尾说几个我用下来的体会第一次跑 EUCROPMAP 全流程时我最大的感受是“地图产品永远比你想象的更需要较真”。分辨率、投影、类别编号、背景值任何一环错了结果都不对而且很多时候不是整体报错而是安静地错——你看着图觉得挺像那么回事直到量化统计才发现偏差。所以养成一个习惯拿到任何新数据第一件事不是急着分析而是打直方图、查投影、看边界、数类别个数把“数据体检”做扎实。再分享一个小技巧上传大文件的时候别一次把所有瓦片合成一个 GB 级大文件建议按瓦片原样先传 4 到 5 块测试确认 GEE 端读取没问题再批量传剩余的。这样万一某一步出问题排查成本低得多。最后EUCROPMAP 这类产品在欧洲以外区域没有覆盖如果你做的是其他大洲的同类分析思路可以照搬但数据源得换。常用替代品包括 FAO 的 WaPOR、IIASA 的耕地产品以及基于 GEE 上现有的 WorldCereal 数据集。核心方法论是一样的先摸清分类体系和坐标系再做重采样和统计分析。这套流程打通之后你会发现处理任何大区域土地分类数据本质上都是同一套打怪路径。

相关新闻

AirLLM 实战:消费级显卡上运行 70B 大模型的层间卸载方案

AirLLM 实战:消费级显卡上运行 70B 大模型的层间卸载方案

把 70B 权重文件完整拉下来之后,我盯着属性面板里那 140 多 GB 的数字沉默了很久。哪怕只按 FP16 精度加载参数,显存需求都接近 150GB,而我手头最好的消费级显卡只有 24GB 显存。换小模型?7B 和 70B 在复杂指令上的表现差距肉眼可…

2026/10/16 11:16:28 阅读更多 →
无GPU也能跑大模型:AirLLM分层推理实战解析

无GPU也能跑大模型:AirLLM分层推理实战解析

AI LLM 这个名字最近在圈子里转得很勤,比很多吹得天花乱坠的“国产替代”方案实在得多。它的核心卖点简单粗暴:没有显卡也能跑几十B参数的大模型,纯靠 CPU 和内存硬扛。我第一次看到项目标题的时候,第一反应是不太相信&#xff0c…

2026/10/16 11:16:28 阅读更多 →
轻薄本跑27B大模型:Qwen3.8-27B Q4量化部署实测与提速指南

轻薄本跑27B大模型:Qwen3.8-27B Q4量化部署实测与提速指南

准备把 Qwen3.8-27B-Q4 塞进 Ultra X7 358H 的时候,周围没几个人看好这个操作:270 亿参数的模型,量化之后还有 16GB 的权重文件,一台没有独立显卡的轻薄本,听起来确实像行为艺术。但最后它不仅跑起来了,还给…

2026/10/16 11:16:28 阅读更多 →

最新新闻

security-audit-skill:为编码智能体注入安全审计能力

security-audit-skill:为编码智能体注入安全审计能力

1. 从"security-audit-skill"这个名字说起:它到底在解决什么问题第一次看到security-audit-skill这个命名,我的直觉是:这大概率是一个面向编码智能体(coding-agent)的技能包,而不是一个独立的扫描…

2026/10/16 14:53:05 阅读更多 →
Codex桌面版实测:多智能体编排如何重塑AI编程工作流

Codex桌面版实测:多智能体编排如何重塑AI编程工作流

深夜一点多,一个同行给我丢来一张截图,我当时刚把手头那个定时任务脚本调完,准备关电脑。结果看了一眼截图就坐起来了——Codex 桌面版发布了。说实话,过去几个月我用 Codex 的方式还是那个老路子:在终端里敲命令&…

2026/10/16 14:53:05 阅读更多 →
PHP-FPM多进程模型详解:master与worker协作机制、参数配置及故障排查

PHP-FPM多进程模型详解:master与worker协作机制、参数配置及故障排查

1. 面试官到底在考察什么:先看问题的分层“PHP-FPM多进程模型”这道题,在PHP面试里属于必问经典。但这道题的考察深度可以拉得很开,面试官通常不是在等你背一个“master进程 worker进程”的结论,而是在区分三种人。第一种人&…

2026/10/16 14:53:05 阅读更多 →
Fabric 1.4.4联盟链手动搭建全流程:从证书到链码调用

Fabric 1.4.4联盟链手动搭建全流程:从证书到链码调用

Fabric 1.4.4 是我带过不少入门项目后,依然觉得最适合“从零讲清楚联盟链”的一个版本。它虽然是 2019 年的 LTS,但模块边界非常干净:身份怎么生成、排序服务怎么启动、通道怎么创建、链码怎么装上去,每一层都能单独拆开看。这篇文…

2026/10/16 14:53:05 阅读更多 →
STM32G474 HRTIM触发ADC中间时刻采样实战:避开PWM开关噪声

STM32G474 HRTIM触发ADC中间时刻采样实战:避开PWM开关噪声

简介:基于STM32G474的HRTIM触发多路ADC采样工程包,面向需要处理PWM开关噪声的嵌入式开发者。工程在NUCLEO-G474RE官方开发板上验证,使用CubeIDE完成配置与调试,实现HRTIM事件触发多路ADC、DMA自动搬运以及串口打印显示&#xff0c…

2026/10/16 14:53:05 阅读更多 →
EasyExcel百万级数据导出实战:从内存优化到异步架构

EasyExcel百万级数据导出实战:从内存优化到异步架构

做后端开发这些年,Excel导出算是我见过“翻车率”最高的功能之一。尤其是当数据量从几千行涨到几十万行时,很多系统就像被卡住喉咙一样,要么内存直接溢出,要么前端页面卡死,要么用户等了好几分钟最后下载下来一个损坏的…

2026/10/16 14:52:02 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →