尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
无人机河道浮木识别:语义分割数据集与训练全流程拆解
1. 为什么无人机拍河道浮木非要自己造一个数据集做水利巡检、河道治理或者防汛应急的朋友大概率都有过这样的经历拿着无人机沿着河道飞一圈回来导出的素材几十个G然后陷入漫长的逐帧看片环节。人工排查浮木、漂浮物、碍洪物眼睛看花不说漏判率还高得吓人。我最早接到这个需求是给某地的河道管理部门做一套无人机影像辅助分析系统。对方的要求很直接——能不能自动识别出水面上的浮木、树枝这类堵塞物最好顺便把面积和分布位置标出来。前期调研时我发现一个大问题市面上公开的遥感分割数据集大多针对陆地场景水体目标检测数据集也以船舶、垃圾漂浮物为主。专门针对无人机视角、河道场景、近岸浮木这种小目标的公开数据集基本处于空白状态。这意味着什么意味着如果我直接拿ImageNet预训练模型去跑河道影像几乎必死。浮木没有固定的颜色、纹理、形态在水面上又小又碎还会随着水流移动、翻转跟水里的倒影、岸边杂物、暗色水纹混在一起很难区分。通用模型在COCO上那套先验知识拿到这个场景里基本帮不上忙。所以自己做数据集不是“选择”而是“必须”。这次分享的这个数据集——无人机视角河道河岸浮木识别分割数据集一共1345张labelme格式单类别就是冲着这个问题来的。它解决的核心痛点就是给做河道视觉识别的团队提供一个可以直接用于训练分割模型的、场景聚焦的、标注格式成熟的数据基础。那这个数据集适合谁一类是做水利信息化、智慧河湖平台的技术人员需要把浮木识别能力集成到巡检系统里另一类是研究语义分割、弱监督学习的学生或工程师需要一个行业特色鲜明、规模又不算太大的数据集来跑实验、验证模型改进还有一类是刚入门分割任务想练手完整流程——数据标注、格式转换、模型训练、评估部署的开发者。后面我会把整条链路拆开讲清楚每个环节该怎么做、哪些地方容易踩坑都放到实操层面去说。老规矩先说一个反直觉的结论1345张图听起来不多但在无人机的垂视视角下完全够打一个基线模型。关键在于你怎么用它、怎么组织训练验证集、怎么处理单类别的类别不平衡问题。这个我后面详细展开。2. Labelme格式拆解别只看扩展名要理解JSON里的结构逻辑2.1 Labelme的JSON到底长什么样拿到数据集第一件事不是急着训练而是先搞清楚标注文件的内部结构。很多初学者喜欢把labelme格式当成一个“黑盒”——标注完导出转成coco或者voc就直接开训。但只要中间某个字段理解错了后期排查问题时会特别痛苦。Labelme的核心产物是JSON文件一个图像对应一个JSON。打开之后你会看到这些关键字段version标注工具版本号一般不用管。flags记录图像级别的布尔标签通常为空。shapes这是重头戏一个数组每个元素对应一个标注对象。每个对象里包含label类别名、points多边形顶点坐标列表、shape_type标注形状类型常见的是polygon也可以是rectangle、circle、group_id分组编号可为空。imagePath图像文件名。imageData通常是空字符串也可以Base64编码嵌入整张图。数据量大的时候建议清空否则文件会变得很臃肿。imageHeight、imageWidth图像的高和宽单位像素。对于浮木这个场景shape_type基本都是polygon也就是用手动多边形把目标轮廓框出来。这里有一个重要习惯浮木往往形状细长、边缘不规则标注的质量直接决定模型上限。2.2 单类别数据集的“类别隐忧”标题里写了“1类别”很多人觉得单类别简单啊模型只用做背景分割和目标分割二分类。其实恰恰相反单类别的难点在“边界”而不是“种类”。浮木这一类内部变化极大。一段枯木、一截树枝、一堆缠绕的水草杂物都可能被归为“浮木”。但如果标注风格不统一——有人说只标明显的树干有人把水草都标进去模型就会学得很困惑。我打开这个数据集检查的时候发现它的标注一致性做得还算不错主要集中在较完整的树干、枝杈、明显露出水面的木质漂浮物上。这一点在训练前一定要调研清楚否则你花大力气清洗数据的时间比标注还长。另外单类别意味着没有“负样本”的显式标注。岸边的石头、混凝土块、水面强烈反光区域模型都会天然当成候选区域去学习。所以训练时负样本的挖掘策略很关键后面我会专门讲到。2.3 从Labelme到分割训练三步走的转换流程绝大部分训练框架并不直接吃labelme的JSON你需要把它转换成模型可用的格式。这里我强烈建议转换成分段后的PNG掩码图mask或者标准COCO格式的JSON。具体流程三步第一步解析JSON中的shapes数组把每个points多边形通过OpenCV的fillPoly函数画到一张全零底图上目标区域填255。第二步把原始图像和掩码图重命名对齐例如IMG_0001.jpg对应IMG_0001_mask.png。注意掩码图只用灰度格式不要存成三通道彩色图否则后处理时还要去通道。第三步按照6:2:2或者7:2:1的比例把图像和掩码同步划分为训练集、验证集、测试集。划分时要特别注意同一段河道的连续帧图片不要拆开到不同集合里。如果你的图是飞行航线连续采集的相邻帧几乎同一个场景直接随机划分会导致验证集和训练集高度相似指标虚高。正确做法是先把航线分组按组划分。下面是一段我常用的转换脚本跑通之后能直接用import json import cv2 import numpy as np import os from tqdm import tqdm def labelme_to_mask(json_path, img_shape, mask_path): with open(json_path, r, encodingutf-8) as f: data json.load(f) mask np.zeros((img_shape[0], img_shape[1]), dtypenp.uint8) for shape in data[shapes]: points np.array(shape[points], dtypenp.int32) cv2.fillPoly(mask, [points], 255) cv2.imwrite(mask_path, mask) img_dir images json_dir jsons mask_dir masks os.makedirs(mask_dir, exist_okTrue) for json_name in tqdm(os.listdir(json_dir)): if not json_name.endswith(.json): continue json_path os.path.join(json_dir, json_name) img_name json_name.replace(.json, .jpg) # 根据实际情况调整后缀 img cv2.imread(os.path.join(img_dir, img_name)) if img is None: print(f图片读取失败: {img_name}) continue mask_path os.path.join(mask_dir, json_name.replace(.json, _mask.png)) labelme_to_mask(json_path, img.shape, mask_path) print(f已处理: {img_name})转换时还有一个小坑labelme的坐标原点在图像左上角单位是像素且是浮点数。直接用numpy数组做索引时要先转int32否则会报错。另一个清空imageData的操作能显著减小JSON体积1345个文件能差出几百MB。3. 1345张图怎么分配训练集设计的策略远比模型选型更重要3.1 数量不大但是场景覆盖广1345张图单独拿出来说确实不算大规模数据集。但无人机视角的河道影像有一个特点单张图内的信息密度高目标数量多场景结构相对类似。你不需要像ImageNet那样准备百万张只需要保证场景多样性和目标形态多样性到位就行。我在实际使用中核对过这个数据集的场景构成。它覆盖了几种典型的河道区段宽阔主河道的中央航拍、靠近河岸的侧视角、有植被覆盖的河漫滩区域、桥梁附近的水域这是浮木高发区因为水面收窄后漂浮物容易堆积、以及部分水面有强烈反光的时段。这些场景基本覆盖了实际巡检中会遇到的绝大多数情况。密集树影下的暗色浮木、与水面反光重叠的半浸没浮木这些难样本在数据集中有专门分布训练时务必保证这些样本进入训练集而不是全扔进验证集。大概算一笔比例账。假设1345张图中80%用于训练也就是1076张。每张图假设平均标注2到3个浮木实例训练集中就有大约2500个有效目标实例。这个量级对单类别的二分类分割来说已经足够让U-Net或DeepLabV3收敛到一个可用的水平。3.2 划分策略按航线分组而不是随机乱切刚才提过无人机采集的影像序列有很强的帧间相关性。如果同一段航线飞出200帧连续画面你把它随机拆到训练和验证集中模型很可能“作弊”——验证集里出现的浮木在训练集里有几乎一样的角度、光照和背景。最后的mIoU做出来90%以上你以为模型学好了一到实际部署就露馅。正确策略是把每一条飞行航拍记录视为一个完整单元在单元级别做划分。比如某次飞行覆盖了3公里河道产出了300张有效帧这300张要么全进训练集要么全进验证集。划分比例按航线段来算而不是按单帧来算。如果一个数据集已经被人为打乱了顺序没有航线信息那我建议你再看看文件名的EXIF拍摄时间或者GPS定位信息尽最大努力还原采集轨迹。实在还原不了至少做一次基于场景相似度的聚类再划分能做到多少算多少。这个细节直接决定你的验证集是“真验证”还是“自欺欺人”。3.3 验证集和测试集的角色分工我习惯把数据拆成三个部分组织。训练集用来学习验证集用来做模型选择——比如判断训练多少轮、是否早停、是否调学习率——而测试集只在最终模型定下来之后跑一次用于报告接近真实部署环境的指标。训练集约940张验证集约270张测试集约135张比例大致是70%、20%、10%。测试集一旦确定中途绝不动它。每改一次模型结构、每换一次损失函数都先在验证集上对比等全部调完再用测试集做最终评估。这是朴素但极其有效的防过拟合策略尤其是数据量只有1345张的时候测试集被“污染”的影响会被急剧放大。4. 河道浮木轻量分割的实操流程数据增强、模型选型到损失函数4.1 关键预处理畸变、裁剪与归一化无人机影像通常带有一定的镜头畸变和角度倾斜除非出厂前做过内参标定否则直接喂给模型会遇到一个麻烦模型会记住镜头畸变的分布规律而不是真正学会识别浮木。如果数据集中的图片尺寸很大比如4000×3000像素直接resize到512×512会丢失大量细节浮木这种目标本身可能只有几十个像素宽。我的建议是分两步走。第一步把原始大图做滑动窗口裁剪切成512×512或者640×640的切片。切的时候窗口要有重叠重叠率15%到20%比较合适防止浮木刚好落在窗口拼接线附近被截断。切出来的子图如果完全没有目标纯水面、纯岸地建议保留一部分作为负样本比例控制在总样本量的20%左右。第二步对于每个切片做归一化。具体是除以255后减去均值再除以标准差。均值标准差可以从整体数据上估算不需要特别精确一套通用统计值就够用。另外要注意labelme的JSON坐标是相对于原始大图的裁剪切片后必须同步更新标注坐标。这几乎是所有从高分辨率影像做分割的项目里最容易翻车的一步。我之前就见过某团队训练完了才发现掩码和图像错位了整整一个窗口大小模型指标接近随机水平。用transform的RandomCrop或者CenterCrop时要同时给图像和掩码传入同样的随机种子保证空间变换一致。4.2 模型选型别一上来就上Transformer现在分割模型五花八门很多同学一上手就祭出Swin Transformer、SegFormer、Mask2Former。不是说不行而是就1345张数据量、单类别分割任务来说这些高复杂度模型反而容易过拟合训练周期长调参成本高。我的习惯是先跑一个U-Net或者U-Net的baseline确认数据链路和损失函数没问题再逐步升级。具体到浮木场景我用下来最顺手的组合是ResNet34编码器加U-Net解码器。参数量适中显存占用友好在1080Ti级别以上的GPU上跑512×512输入batch size能开到16以上训练速度很快。DeepLabV3也是一个好选择尤其在浮木边缘细节上表现更锐利但推理速度略慢。如果你要部署到无人机地面站的便携设备上MobileNetV3U-Net的轻量组合可以放进备选清单精度掉一两个点但推理帧率能翻几倍。我在这个数据集上对比过几组常见配置简单列个参考不同硬件、不同划分下会有出入模型组合输入尺寸参数量训练耗时约验证mIoU约ResNet34 U-Net512×51244M2~3小时78%ResNet50 DeepLabV3512×51264M4~5小时81%MobileNetV3 U-Net512×51215M1.5小时72%SegFormer-B0512×5123.7M3小时74%注意这只是我本地的参考值你的划分方式、增强策略不同结果会有波动。重点是别只看精度要看精度和成本的平衡。4.3 数据增强组合围绕“水”这个场景定制通用增强——随机翻转、随机旋转、随机亮度对比度——都能用但浮木场景有它的特殊性。水面的光照变化极其剧烈同一个浮木在顺光、逆光、多云遮挡下拍出来的视觉特征差异巨大。所以我额外加了三类针对性增强第一是随机色彩扰动重点增强色相和饱和度的变化幅度。枯木的颜色可以从深褐到浅黄水面颜色可以从浑浊黄绿到深蓝灰保守的增强幅度不够大胆一点反而更贴合实际。第二是随机添加高斯噪声和轻微的模糊。很多浮木处在画面边缘或景深区域之外本身就有轻微失焦。给训练集注入噪声能提升模型的鲁棒性防止它对纹理细节过度敏感。第三是混合增强把两张训练图各自裁剪一半拼在一起标签也对应拼接。这能显著增加目标与背景的多样化组合让模型不至于只学会水面浮木这一种固定构图。实测下来混合增强能让验证集mIoU提升2个百分点左右在数据量有限的前提下性价比很高。然后是至关重要的一步在训练过程中对mask同步做增强。PyTorch里可以用torchvision.transforms配合Compose但一定要给图像和掩码用同一个随机变换实例。最常见的错误写法是分别创建两个Compose图像翻转了而掩码没翻转训练出来模型完全学不到东西损失函数还不下降。4.4 损失函数Focal Loss边界情况下的优势单类别分割的默认配置是交叉熵损失。但水上浮木这个场景背景水、岸、植被占比远高于目标区域。极端情况下一张图上浮木可能只占0.5%的像素交叉熵会把大量梯度集中在背景上模型倾向于全预测为背景准确率很高但mIoU惨不忍睹。针对类别不平衡我推荐用Focal Loss或者Dice Loss。Focal Loss通过调制系数降低易分类样本的权重让模型更关注那些难分的边界像素和细长浮木Dice Loss直接优化预测和真实掩码之间的重叠区域对小目标更为友好。实践中常见的做法是两者加权组合我记得有一组相对鲁棒的配置是0.5*Focal 0.5*Dice你可以按实际效果微调。浮木分割还有一个独特难点类别内部的“像素级不平衡”。粗壮的树干中间大片区域非常好分类难的是边界的细枝末节。这类像素恰好在Focal Loss中会被持续放大权重所以它对提升边界精度、召回率都有显著帮助。5. 踩坑记录无人机视角下的三大“视觉陷阱”与应对方案5.1 水面反光最容易被误判成木质结构的干扰项水面对阳光的镜面反射在航拍影像里经常形成亮白色或者暖黄色的条纹。这些条纹的走向有时恰好和浮木的细长形态相似模型很容易把反光区域判定成目标产生大量假阳性。我最初训练时精度不低但一看可视化结果一大片假阳性全标在水面的亮斑上。这个问题的根源在于训练数据里反光区域的特征没有充分“暴露”给模型。单靠模型自己学到“水面反光不是浮木”效率太低。我的解决方案有三层。第一层是在训练数据里多保留反光强烈的负样本切片让模型有机会学到反光区域的负例特征。第二层是后处理时用HSV空间的亮度通道加一个阈值浮木的边缘虽然有高光但整体平均亮度不会像水面反光那样接近纯白凡是掩码区域亮度均值超过某个阈值的直接清零。第三层是如果拍摄时间可选尽量选在上午9点到下午3点之间光线入射角相对垂直水面反光面积最小。5.2 岸际植被与枯草特征混淆的重灾区树影、岸边倒伏的枯草、被风吹动的落叶堆形态和颜色上跟浮木高度重叠。岸际植被属于陆地背景如果标注时不小心把它们圈进去模型就学歪了。我在这个数据集里特别检查过这部分——标注质量整体在线绝大多数目标确实是水中的木质漂浮物岸上的枯枝基本没标。这一点很重要不然训练阶段就会积累系统性偏差。真正麻烦的部署场景是浮木紧贴岸边、半截在岸上、半截在水里。这时候模型输出的掩码容易延伸到岸上植被区导致面积高估。我的经验是给最终掩码增加一个后处理规则结合岸线掩码如果模型预测区域延伸到了陆地将这些延伸部分裁掉。也就是说可以叠加一个水陆分割模型作为辅助约束。但这是进阶玩法基线阶段先不用加。5.3 目标尺度差异树枝是树枝树干也是树干无人机飞行高度变化导致同一类目标在图像上所占像素跨度极大。飞行高度50米一棵大树的浮木可能在图上占几百像素宽飞行高度150米同样一个目标只剩下几十像素的微小区域。一个在512×512输入下能明显识别的目标下采样到特征图后可能只剩一个点。为了减轻这个问题我一般会在标注阶段检查GT掩码中每个连通域的像素面积统计分布情况。如果发现小目标占比太高就增加多尺度输入训练比如同batch内混着输入384×384、512×512、640×640让模型适应不同尺度。推理阶段也可以做多尺度推理把多张不同尺度的预测结果做平均融合对小目标的漏检有明显改善。6. 从训练集到部署评估指标、可视化检查与模型压缩的一课6.1 别只盯mIoU还要看召回率和连通域数量分割任务最常见的主指标是mIoU、mPA平均像素精度但对浮木场景来说这些指标还不够。业务方关心的是“河道里究竟有没有大块浮木”“有多少块”“分布在哪”。这意味着你需要更贴近业务的指标召回率Recall漏检一个浮木可能意味着下游调度疏漏比误检更严重。连通域数量预测掩码中能够连成一个整体区域的数量直接对应“有几根浮木”。单体面积分布的误差预测出的单块目标面积与实际面积的偏差。我建议训练完成后对所有验证集预测结果做连通域分析统计预测连通域数量和GT连通域数量的接近程度。如果图像级mIoU不错但连通域数量偏差大说明模型虽然画得准但把一块目标切成了几段或者把几段连成一片。以业务为驱动的评估会让你避免一种常见尴尬——交了一份85%mIoU的报告对方却问“那河里的那根大木头为什么显示成三截”。6.2 可视化调参每20轮就翻一次预测图现代训练流程容易让人过度依赖终端打出的loss曲线。Loss降了不代表模型学到了浮木的结构特征。我固执地保持一个习惯每训练20个epoch就保存一批验证集预测图单独打开看哪里错、哪里漏。浮木分割有非常强的视觉可解释性你不看图根本无法发现模型在靠水面纹理“作弊”。具体看图时重点看三类情况第一类背景被标成目标的假阳性观察它们的共同特征——都是某种颜色或者特定位置第二类小目标被完全忽略说明模型对小目标关注不够需要加强多尺度或调整损失权重第三类低对比度浮木的轮廓被割裂说明边界细节还有问题可能需要在解码器端加一点深度监督。通过看图迭代比单纯调学习率快得多。6.3 模型压缩部署到无人机地面站前的一步模型训练完远不是结束。实际巡检场景你大概率不是在一台高配服务器上实时推理而是要在无人机地面站、便携电脑甚至嵌入式设备上跑。我从ResNet34U-Net的baseline出发做了两步压缩第一步做剪枝把编码器后几层冗余的通道剪掉一部分精度下降0.5%但参数量减少30%。第二步做INT8量化用验证集做校准数据量化和蒸馏结合最终模型体积缩小到原来的四分之一单帧推理时间从120ms降到40ms左右。如果你的设备内存更紧张还可以转ONNX再转TensorRT进一步榨取性能。这一步的实践顺序建议是先跑通未压缩的完整模型确认任务效果达标再做压缩。不要一上来就压缩到极限否则踩了坑还不知道是量化导致的精度下降还是模型本身就没训好。7. 这类项目后续还能怎么扩展说实话1345张图的数据集直接用来训练一个浮木分割模型绰绰有余但这个场景往深了做还有很多延伸空间。第一个方向是时序信息融合。河道浮木不是静止的会漂移、旋转、聚集成群。利用无人机视频的多帧信息做时序分割效果会比单帧明显更稳定。现在的数据集是单帧静态标注如果要扩展可以从同一航线的连续帧中抽取三到五帧标注同一目标的运动轨迹做成带跟踪标签的数据集。第二个方向是和水位、流速传感器融合。模型识别出浮木后结合当时的水文数据可以预测浮木下一段时间的漂移轨迹。这对于防汛决策有很高的实用价值。这部分的思路是把分割结果转换成目标中心点坐标序列再用卡尔曼滤波或者简单的线性外推做轨迹预测。第三个方向是域自适应。这个数据集主要覆盖晴好天气的河道场景到了雾天、雨天或者傍晚弱光环境模型性能可能崩盘。利用域自适应或测试时增强用少量目标域样本适应新环境是后续值得探索的方向。这次就先聊到这里。数据是拿来用的不是拿来供着的。开源数据集最大的价值不在于下载的一瞬间而在于你把它跑通、跑出结果、踩过该踩的坑之后那份能够迁移到相似场景的经验。希望这篇拆解能帮你少走一点弯路。
RELATED

相关推荐

Windows与Linux平台CUDA环境部署完整踩坑指南

Windows与Linux平台CUDA环境部署完整踩坑指南

上周帮一位同事在Windows工作站上部署CUDA环境,前后折腾了两个小时,最后的根因出乎意料——他先装了最新的CUDA Toolkit 12.2,但显卡驱动还停留在几年前的版本,两者直接对不上。这其实是在CUDA Windows与Linux系统安装过程中最容易…

📅 2026/10/21 21:30:00
基于SpringBoot+Vue的白酒销售系统与协同过滤推荐算法实战

基于SpringBoot+Vue的白酒销售系统与协同过滤推荐算法实战

每到毕业季,总会有大量同学被同一个问题反复折磨:到底选一个什么样的毕设题目,才能既体现工作量,又兼顾技术含量,答辩时还能有故事可讲?如果是计算机相关专业的同学,我通常建议往前后端分离和推…

📅 2026/10/21 21:30:00
OPNET网络仿真环境搭建与编译避坑实战指南

OPNET网络仿真环境搭建与编译避坑实战指南

1. 为什么OPNET至今仍值得花时间折腾 搞网络仿真的朋友大概率都听过OPNET这个名字。它是商业网络仿真领域的老牌工具,全称Optimized Network Engineering Tool,后来被某大型通信公司收购后改名为Riverbed Modeler。虽然官方早已停止更新,但在…

📅 2026/10/21 21:30:00
MORE NEWS

更多资讯

📰

Agentic AI生产落地指南:从状态机编排到可观测性部署

做了几个月的Agentic AI落地项目,最大的感受是:让大模型说话容易,让它干活难;让Agent在demo里跑通容易,让它每天稳定处理上千个真实任务、出错了还能自己恢复,难上加难。很多Agentic AI教程停在"构建&…

📰

lingbot-map:多传感器融合的语义建图系统实战解析

1. 这个项目要解决什么问题第一次看到lingbot-map这个名字,我第一反应是:这八成又是一个机器人建图相关的模块。跟几位做移动机器人的朋友聊完,再结合我自己在室内外巡检、仓储搬运这些小项目里折腾过的经历,基本可以确认&#xf…

📰

基于YOLOv8的鱼病害检测系统:从数据集到UI部署全解析

搞水产养殖的朋友应该都懂,鱼病这东西最怕拖。一晚没巡塘,第二天水面就可能漂着几条,再查就是整池感染。以前全靠老师傅打着手电捞鱼、翻鳃、看体表,费时间,也特别吃经验。现在有了基于YOLOv8深度学习的鱼病害检测系统…

📰

Agent长期运行实战:从“聊几句”到“跑几小时”的异步任务化改造

把Agent从“聊几句就返回结果”变成“在后台跑几小时甚至几天再交结果”,这个转变让很多团队翻了大车。我见过一个项目,Agent需要爬取上百个数据源、逐个清洗、做交叉验证,最后生成一份分析报告。单次任务运行时间超过6小时,结果进…

📰

Dify+DeepSeek搭建私有化AI知识库:从部署到问答的实战全流程

上个月给某企业做内部知识管理调研的时候,我发现一个特别普遍的现象:网盘买了、Wiki搭了、文档中台上了一堆,但新人入职想找一份制度文件还是要问三个人,项目复盘的经验永远躺在聊天记录的翻不到底的地方。说白了,企业…

📰

知识工作插件体系设计:边界划分、上下文传递与可扩展性实践

1. 从"知识工作插件"这个命名说起:它到底想解决什么问题第一次看到"knowledge-work-plugins"这个命名,我的直觉是:这大概率不是一个具体的产品,而是一类面向知识工作者的可插拔能力集合。所谓"知识工作&…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬