
1. 先从用途倒推数据设计1.1 这七类树种到底从哪来做无人机树种检测这件事最难的不是飞不是标而是想清楚一个问题你花三个月做出来的数据集到底要喂给哪个具体业务。我这次的项目源自一个林区智慧巡检需求。客户要求用无人机完成重点区域的树种分布摸底点名要区分落叶松、云杉、华山松、白桦、川西云杉、兴安落叶松、樟子松。光看这份清单就知道这不是南方常见的阔叶林识别而是典型的北方混交林场景。针叶树占了一大半而且里面还有云杉和川西云杉这种亲缘关系很接近的双胞胎树种。我一开始也想过去找现成的开源遥感数据集。试了一圈发现公开数据大多是国外树种或者热带雨林放到国内的寒温带针叶林场景上迁移效果很差。更麻烦的是光学影像在不同季节、不同地形下树冠的光谱和纹理表现差异极大。比如白桦和落叶松七月份都是绿油油的但到了九月底落叶松变黄的速度和程度跟白桦并不一致这种季节变化最后都会成为模型误判的来源。所以最终决定放弃找数据集转向造数据集。整个项目其实可以拆成五件事林区树种清单确认、无人机影像采集、正射影像切片、标注规范制订、模型训练与回归验证。后面每一件事我都吃了一点亏也总结出了一些能直接抄的结论。1.2 为什么单株树冠是合适的标注粒度在数据集设计阶段我首先卡在标注粒度这个问题上。到底是按单株树冠标还是按林分区域标按林分区域标操作上最省事画个多边形把整片林子圈起来就行。但实际用下来问题很大混交林里往往几十米范围内就有两三种树混在一起边界完全不清晰圈出来的区域标签纯度非常差。模型学到的是这块绿有落叶松的特征而不是这个树冠是落叶松到单木尺度调查时就废掉了。按单株树冠标精度高但工作量翻倍。我观察了一下一张1000m乘800m的正射影像如果林分密度中等单株树冠数量可能在几千棵。这意味着标注量是以十万计的。最后我们的做法是混合策略先按单株树冠标一个核心区域保证每一类都有足够样本再用林分级别的粗标做预训练让模型先学会树冠检测和非树冠背景区分然后把预训练模型拿来给人工标注做辅助预标注人工只需要修正框的位置和类别。这里有个经验不要一开始就追求全量精细标注。先把数据分成AB两组A组标精细B组标粗糙然后用A组训模型用B组做测试集。如果B组上精度明显下降说明标注粒度不一致已经成了瓶颈再回头补标。我实测下来至少能省百分之三十的人工标注时间。1.3 一份好数据集的验收标准很多人以为数据集验收就是看总张数和总标注数这其实是个误区。无人机树种检测数据集最容易翻车的点是类间不均衡和场景单一。先说类间不均衡。云杉、樟子松、落叶松这类针叶树如果采集区域大面积连片会造成某类标注框特别多另一些类别只有零星几十个框。模型训练时少数类的AP会直线下降。我给自己定了一个参考标准每类至少保留800到1200个有效树冠样本少于500个的类别需要回补采集不然这个类别的存在价值约等于零。再说场景单一。如果所有影像都来自同一片林区、同一飞行高度、同一光照条件模型到了另一片地形就会表现得很差。我当时拿到第一版测试数据时模型在训练区mAP能到0.82换到相邻河谷马上跌到0.57。原因就是采集时只顾着数据量够大忽略了地形和光照多样性。基于这个教训我后来的验收标准里加了三条硬性条件一是必须有至少三个不同地形单元山地、河谷、丘陵的影像二是同一树种必须在阴坡和阳坡各有分布样本三是飞行高度不能只有一个档位至少要包含30米以下和80米以上两种分辨率采集。这三条看起来简单但直接影响模型能不能真正在巡检业务里跑起来。2. 七个树种的识别特征拆解2.1 树冠形态与光谱特征的差异树种检测模型学到的特征主要来自树冠的形状、颜色、纹理和阴影关系。这里先把我整理的七类树种俯视特征表列一下。树种树冠形态夏季俯视颜色冠层纹理特征最容易混淆的对象落叶松塔形冠顶钝尖黄绿或浅绿针叶簇生纹理细碎兴安落叶松、幼年樟子松云杉尖塔形冠幅较窄深绿至灰绿枝条密集颗粒感强川西云杉华山松广卵形冠幅大亮绿光泽感强针叶较长纹理偏粗高处拍摄的樟子松白桦卵形或近圆形亮绿透光感明显阔叶叶片密集边缘柔少数阔叶灌丛川西云杉窄塔形冠顶略平灰绿偏蓝鳞叶排列紧密颗粒感更强云杉兴安落叶松塔形冠基较大浅绿春季偏嫩黄针叶簇生树冠内部有明显空隙落叶松樟子松圆形或宽卵形深绿带黄针叶较长冠层不均匀有亮斑华山松、落叶松这张表不是我拍脑袋写的是拿了几百张影像和地面实测照片反复比对出来的。最核心的发现是单一的颜色均值特征完全靠不住真正稳定的是树冠边缘锐利度冠层纹理周期性的组合。云杉和川西云杉颜色接近但川西云杉的树冠边缘更平直有过明显的平台感而云杉更尖。这种细节在标注时很容易忽略却在训练时成为模型区分它们的关键线索。2.2 相似种之间的判别逻辑我在这个数据集上踩过最大的坑就是云杉和川西云杉的区分。两者的俯视影像相似度实在太高第一次标注时标注员甚至提出这两类是不是标错了。后来我仔细对比发现光学影像上真正能用的判别特征有三个。第一个是冠幅与树高的比例。云杉的冠幅相对更宽适合在中等郁闭度林分中生长俯视时树冠之间常出现重叠川西云杉的冠幅更窄树冠间距相对更大空隙更明显。这个特征在低分辨率影像上也能分辨。第二个是树冠边缘的光影表现。云杉枝条分层明显树冠边缘有比较自然的锯齿状阴影川西云杉的鳞叶排列更紧密树冠边缘看起来更光滑锯齿感很弱。晴天侧光拍摄时这个特征非常明显。第三个是阴影的方向和密度。由于树冠结构不同云杉下方的阴影更碎片化川西云杉下方的阴影更连续。后期我把影像按太阳高度角做了归一化处理后这个特征就更能体现出来了。对于落叶松和兴安落叶松单看俯视影像其实更难。两者的树冠形态几乎一样唯一的稳定区分点是冠幅大小和郁闭度下的分布格局。落叶松在混交林里更常见树冠偏小兴安落叶松更耐寒常形成纯林或优势林分树冠偏大。但这两个特征并不是绝对的所以数据集中一定要包含不同地域、不同生长阶段的样本不能只靠光学特征硬扛。2.3 从树种构成反推采集区域安排七类树种的构成其实已经决定了采集计划的大致范围。里面既有云杉、川西云杉这种偏湿润环境的树种也有樟子松、兴安落叶松这种耐旱耐寒的先锋树种还有白桦这种典型的次生林落叶阔叶树。这意味着采集区域必须覆盖多种生境单一林场搞不定。我最后选定的做法是三片区采集第一个片区以针叶纯林为主覆盖落叶松、兴安落叶松和樟子松第二个片区以针阔混交林为主覆盖云杉、川西云杉和白桦第三个片区选择林缘和疏林地带主要采集华山松同时补充其他树种的稀疏样本。这样安排的好处是每个树种都能在优势生境和劣势生境下分别出现模型学到的不是这一片都是云杉而是云杉在不同混交状态下的样子。第三片区采下来的数据量最少但因为特征变化最大训练时对AP的贡献反而最大。3. 影像采集与预处理实战3.1 飞行参数到底怎么定采集无人机树种检测数据飞行参数直接决定后续所有环节的成败。我最后定下来的参数体系如下供大家参考。飞行高度上我做了两档。第一档是100米高度主要获取大范围正射影像用于生成区域概览图和训练检测模型的远景样本。这个高度下地面分辨率大概在7到10厘米每像素单棵树冠由几十个像素组成对人眼来说勉强能分辨树种对模型来说已经足够学习树冠结构特征。第二档是35米高度获取高分辨率局部影像针对的是单株树冠的细节。这个高度下地面分辨率能到2到4厘米每像素树冠内部纹理、枝条结构都非常清晰。这部分数据我主要用于标注难度较高的相似种比如云杉和川西云杉。航线重叠率是另一个关键参数。航向重叠我设了80%旁向重叠70%。这个数值比普通测绘要求的60%到65%要高不少。原因是树冠是有高度的立体目标在正射拼接时会产生视差如果重叠率不够树冠边缘会出现明显的拼接锯齿和重影直接污染样本质量。飞行时间上我强烈建议避开正午。树冠阴影最小的时候不一定适合采集因为缺少立体感树冠边缘和背景的对比度反而下降。上午十点到十一点半以及下午两点半到四点这两个时间段侧光明显树冠轮廓清晰阴影还能辅助标注员判断冠层边界。有雾、大风、阴天我都不建议飞阴天平光条件下很多纹理特征会被压平模型学到的特征会很飘。3.2 正射拼接与切片策略采集回来的原始影像必须经过正射拼接才能得到完整的林区俯视图。这一步我踩过不小的坑第一次用默认参数拼接结果树冠边缘出现很多重影和拉花尤其是高一点的树拼出来像万花筒。问题出在数字表面模型的生成策略上。无人机树种检测数据集的正射拼接不能完全依赖标准地形模型树冠是有几十米高的立体结构如果只做平面正射校正树顶和树底的高差会带来明显的投影错位。我的解决办法是先用稀疏点云生成数字表面模型再做真正射校正让树冠顶部的影像站直然后再生成立体视图供后续使用。拼接完成后需要把大幅正射影像切割成训练切片。这里我试过两种切片尺寸1024像素和1536像素。1024在训练速度和显存占用上更友好但树冠尺度偏大时一棵树的风范可能占满整个切片上下文信息太少模型分不清这是整棵树冠还是树冠局部。1536效果更好但batch size必须降下来训练时间会拉长。切片时还有个容易忽视的细节相邻切片之间要有10%到20%的重叠。如果不重叠树冠正好被切在边界上时这个样本基本报废。重叠切片的做法是让同一棵树在相邻切片里各出现一次数据量虽然翻倍了但有效样本率大幅提高模型收敛也更快。3.3 哪些影像必须提前扔掉第一轮我采集了将近3万张原始影像真正进入训练集的只有不到一半。大量影像在预处理阶段就被我扔掉了这里说几条筛选红线。云层阴影下的影像必须扔。树林里云影移动造成的光照不均匀比单纯阴天更恐怖它会在同一张切片里制造两个亮度完全不同的区域。模型如果见过太多这种样本会试图用亮度来分类而不是用树冠特征。雾霾和薄霭也要扔。低空航拍时远处林区的山体常常笼罩在淡蓝色的大气散射里。这种影像上的树冠颜色整体偏灰蓝饱和度低如果混进训练集会让模型对颜色饱和度产生错误依赖。拼接后出现拉花和错位的区域宁可切掉也不能留。局部错位虽然看起来不大但在模型眼里就是一堆乱码式的边界纹理标注框一旦画在这些区域等于主动给训练集投毒。还有一类是飞行姿态剧烈变化导致的倾斜影像。无人机在大风天转弯时姿态角变化很大影像边缘的地物明显倾斜。正射校正后这些区域会被拉伸得很奇怪放进训练集只会增加无效样本。4. 标注规范与质量控制4.1 检测框还是分割掩码做单株树冠标注第一步就要决定用目标检测框还是实例分割掩码。我两个方案都试过说一点实际感受。如果项目目标是统计树种面积、生成分布图那么检测框就够用了。水平外接框虽然不能精确贴合树冠轮廓但在统计上误差是可以接受的只要框的中心位置准确面积估算误差能够控制在10%以内。检测框的标注效率也高得多一名标注员一天能标1200到1500个框如果是分割掩码大概只能画300到400个。如果目标是单木定位树冠面积精准测量那么必须用分割掩码。比如要做蓄积量估算、间伐作业设计一个框的精度远远不够树冠边界多画或少画几个像素面积误差会被放大。考虑到成本和客户需求我最后采用的是折中方案主标注用水平检测框类别标签和中心点严格把关另外对不容易判别的混交林区域追加掩码标注用来训练一个辅助分割模型。上线时主用检测模型辅助分割模型只做面积修正参考。4.2 边界情况怎么定规则树种检测标注最容易产生分歧的是一些边界情况。我在制定标注规范时明确了几条规则后来发现这几点直接决定了标注一致性。第一树冠被遮挡超过一半的不标。混交林里树冠互相挤压边缘经常会有树冠被其他树挡住。如果被遮挡面积超过50%模型学到的就是一个残缺的树冠形状容易造成特征错乱。如果遮挡在30%以下可以标但要在备注里标记partial。第二出于画面边缘的树冠不标。正射切片边缘经常有半个树冠露在外面这类样本在检测时会产生一个超出画幅的预测框后处理时很麻烦。我规定只有树冠主体完整出现在画面内才允许标注。第三幼树和灌木不标。没有进入主林层的幼树树冠太小与灌丛在影像上极难区分。我把树冠直径低于平均值的样本全部排除宁可少标一点也不能让模型把灌木当成樟子松。第四同一棵树在重叠切片里出现多次怎么办。我允许标注但规定同一个树冠ID必须通过备注字段关联。后续在做数据划分时保证同一个树冠ID的所有切片都出现在同一个数据集里避免切片级别的数据泄露。4.3 专家复核与一致性检查标注一致性是这类数据集的隐形天花板。两个标注员对同一棵树的判断不一致这个样本在训练时就会产生梯度冲突。我的做法是三轮质检。第一轮是系统自动检查用脚本统计每张切片的标注框数量、类别分布和框面积分布出现极端值就标记为可疑样本。比如一张切片里框了300棵落叶松但其他同类切片平均只有80棵这张图基本就是标错了区域。第二轮是专家抽检请有林学背景的人对5%到10%的切片进行复核。专家复检主要任务不是纠错而是确认类别定义有没有偏差。我当时发现标注员把很多受光不足、颜色偏深的华山松顺手标成了樟子松这个错误靠标注员自己交叉检查根本发现不了只有专家能看出端倪。第三轮是分类交叉检查每个类别随机抽20个框集中显示在屏幕上让不同标注员描述为什么觉得这个是落叶松。如果他们描述的特征各有侧重说明类内样本多样性足够如果所有人都说看着像那就要警惕这个类别的特征是否太单一可能需要补充采集。5. 模型训练与效果评估5.1 基线模型选择与训练配置数据集做完模型训练反而是最顺利的环节。我基于YOLO系列的检测框架做基线对比了不同backbone下的效果最终采用的配置如下。输入分辨率选1280乘1280。虽然训练变慢但对树冠这种中大型目标非常必要。我试过640分辨率检测框数量上去了但云杉和川西云杉的区分度明显下降说明细节纹理在降采样过程中被丢掉了。1280分辨率下模型能看见树冠内部的纹理颗粒这对相似种分类帮助极大。训练集、验证集、测试集的划分方式要特别小心。我强烈建议按采集区块划分而不是按切片随机划分。同一片林区相邻切片的内容高度相似如果随机划分验证集里会有大量与训练集来自同一次飞行的样本记忆代替了学习验证分数虚高。我前面提到同一树冠ID要关联正是为了在划分时做去重。训练超参数上我给了两个参考初始学习率设在0.01左右用余弦退火调度数据增强开启Mosaic和MixUp但概率只开到0.5。树冠俯视图不像通用目标检测数据集那么丰富过强的Mosaic会把不同树种的树冠纹理拼在一起反而产生错误的类间混合特征。5.2 评估指标别只看mAP训练完模型很多人习惯只看mAP50和mAP50-95这两个指标确实重要但树种检测项目里必须多看两个维度。第一个是各类别单独AP。七类树种如果整体mAP50在0.8以上看起来很漂亮但打开类别明细白桦可能高达0.92川西云杉只有0.61。巡检业务里客户关心的恰恰是那些难分的类别只看总体指标会掩盖严重偏科。第二个是混淆矩阵。我发现落叶松和兴安落叶松的混淆程度最高其次是云杉和川西云杉。这时候就要回去检查训练集里这两对的样本比例和拍摄环境多样性。我给自己的要求是每对易混淆类别的交叉错误率尽量控制在15%以下如果超过20%说明数据集里这对相似种的特征重叠太严重需要补特征或者采集更多专项样本。我第一版模型的实测数据如下供大家做个参照。类别AP50AP50-95主要错误类型落叶松0.840.6214%错分为兴安落叶松云杉0.880.689%错分为川西云杉华山松0.790.5711%错分为樟子松白桦0.910.724%错分为灌丛川西云杉0.740.5119%错分为云杉兴安落叶松0.810.5816%错分为落叶松樟子松0.770.5512%错分为华山松5.3 难例挖掘与针对性回补模型训练不是一次性的事情。第一版在川西云杉上只有0.74的AP50说明这个类别的特征学习明显不足。我做了一次针对性的难例挖掘。我把测试集里所有被分错的切片单独导出来用聚类做了一个可视化分析。结果显示被错分的川西云杉主要集中在两类场景里一是生长在阴坡的窄冠个体树冠形态明显收窄和普通云杉差异被拉开二是混交林里树冠受挤压的个体树冠呈现不规则多边形很难从俯视影像上捕捉典型特征。针对这些难例我做了三件事第一回补采集了阴坡窄冠川西云杉的专项数据第二在训练时对易混淆类别做了过采样让每个batch里云杉和川西云杉的出现频率接近第三增加了光学影像的对比度归一化预处理降低光照不均匀带来的干扰。经过这一轮迭代川西云杉的AP50提到了0.79虽然还是不理想但至少没有出现大规模的类间崩溃。这里多说一句不要为了追求指标好看而删掉不好做的样本。很多时候难样本恰恰代表真实业务场景删掉它们等于自欺欺人。宁可模型在测试集上分数低一点也要保证它见过足够多的困难地形。6. 实际巡检落地时的现实问题6.1 季节变化对模型泛化的冲击模型训练完不等于巡检就万事大吉。我第一版模型在六月份采集的数据上效果不错到了九月末帮客户做秋季巡检效果直接打折扣。白桦和落叶松在秋季快速变色树冠从绿色转为金黄模型之前学到的颜色分布特征全部失效大量白桦被漏检落叶松被错分成白桦。这个问题在树种检测里非常普遍。纯光学影像模型本质上学习的是某个季节下的树种外貌一旦季节变了外貌变化比不同树种的差距还大。我的解决办法是建立季节版本概念不指望一个模型扛一年而是按巡检时间分两季建模一个是生长旺季模型一个是秋季变色模型。多光谱数据能缓解一部分季节问题但不是所有巡检队都配得起多光谱相机所以对大多数团队来说季节版模型更现实。另一个折中思路是在训练数据里故意混入不同时期的少量样本。例如在生长季训练集中混入10%的去年秋季影像让模型不至于对颜色完全敏感。实测下来增加了大概3%到5%的鲁棒性虽然不大但在误检率上case减了不少。6.2 光照、阴影与树冠重叠巡检作业中绕不开的一个问题是航向与太阳角度的关系。如果无人机按固定航线飞行那么同一片林区前后两架的侧光方向可能完全相反。树冠阴面在模型眼里往往是暗色噪区如果训练数据里全是顺光影像逆光巡检时模型的表现会很挣扎。我的对策是两条。第一采集阶段刻意记录每张影像的航向角度并在切片时保留该信息用于数据清洗。第二训练阶段做光照翻转增强把影像左右翻转、上下翻转同时配合亮度扰动。这种增强方式能部分模拟太阳角度变化让模型学到与光照方向无关的树冠结构特征。树冠重叠的问题更难解。郁闭度高的纯林里成片树冠几乎连在一起水平检测框之间大量重叠。模型训练阶段如果密集重叠样本太多NMS阈值会很不好调阈值调高了容易漏检调低了会把一棵树重复框两三次。我最后用了一个相对保守的NMS参数置信度0.35IoU阈值0.45。同时在后处理阶段加了一个重叠框合并规则如果两个同类别框的重叠面积超过70%且置信度差在0.1以内就合并成一个树冠组后续统计时按面积归一化处理。6.3 从树冠检测到巡检报告的最后一公里模型输出的检测框距离客户能用的巡检报告还差好几步。我最后的处理管线是检测框先做地理配准把像素坐标转换到WGS84经纬度坐标系下再对树冠框进行面积估算按树种累加得到分布面积然后把结果聚合成小班尺度的树种比例表。这一步最容易出问题的是地理配准精度。如果正射影像拼接精度不够一个检测框的地理坐标偏差可能从五米到二十米不等。单独看一个树冠好像看不出问题汇总到小班面积时就会发现边界的树种分布完全对不上。我建议数据处理的最后关一定要加入地面控制点校验至少保证框中心平均误差在三米以内不然报告里的面积数据经不起推敲。另外巡检报告不能只给一张树种分布图。我后来在成果里加了一个树种组成变化预警模块把多期检测结果叠加自动比对同一位置的树种变化。比如某块小班去年是落叶松纯林今年突然出现大量白桦这可能是抚育或者自然更新导致的。客户对这个功能的反响比我预想的好很多也让我更确认了一点数据集和模型永远只是中间产物真正值钱的是能指导现场决策的结论。我的体会是这类智慧农业巡检项目最花时间的其实不是算法而是把数据的脏活累活做扎实。数据采集前先花一周把树种清单和地形图谱摸清楚后面所有环节都会受益。如果一上来就闷头飞、闷头标等到模型训完再发现数据有问题回填成本会是前期的好几倍。