首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
基于YOLOv10的水下鱼类检测系统:数据集、训练与UI界面部署
📅 2026/10/21 4:07:53
✍️ 爱科研究院
👁 阅读 3,247
水下鱼类检测这个方向最近两三年热度涨得很快。我接触的很多需求方是搞海洋生态观测、水产养殖智能化和渔场巡检的朋友。他们缺的往往不是论文或者demo而是一个能直接在电脑上打开、点一下就能识别鱼种并数出数量的工具。这套基于YOLOv10的水下鱼类检测系统做的就是这件事用YOLOv10深度学习模型识别水下画面里的目标鱼配上完整的YOLO数据集训练流程再封装一个带UI界面的可视化工具把图片、视频、实时摄像头三类输入全部串起来。无论你是做毕业设计、工程落地还是想系统学习目标检测从训练到部署的完整链路这篇文章里的数据整理、训练参数和界面集成思路都能直接参考着用。1. 项目拆解这套系统到底在解决什么问题1.1 核心需求梳理从“看得见”到“认得准”水下场景做目标检测和普通路面场景有很大差别。水体对光线的吸收导致画面整体偏蓝绿色悬浮颗粒带来大量噪声鱼群密集游动时互相遮挡再加上一些鱼种本身颜色和背景高度相似直接用常规模型往往会出现漏检、误检。这个项目的核心需求其实有三层第一层是“看得见”也就是把鱼从浑浊的水下背景中分离出来第二层是“认得准”不仅要定位到鱼还要区分种类并给出置信度第三层是“用得上”模型训练完不能只是黑窗口里看指标得有直观的UI界面让非技术用户也能上传一张水下照片或者调起水下摄像头实时看到检测结果。我在拆这个项目时把整个系统分成了数据、模型、交互三块。数据决定模型能力的上限模型决定检测效果的基准界面决定工具是否真的能被用起来。三者缺一不可。很多人只盯着模型训练忽略数据集质量结果换一个水域、换一种光照模型立刻失效也有不少人把模型训练得很好但交付时没有界面需求方根本没法用。这套系统的价值在于把三块完整打通了尤其是UI部分让整个项目从“算法实验”变成了“可用工具”。1.2 技术路线为什么选YOLOv10和以往版本比强在哪YOLOv10这个版本发布后我第一时间就把项目里的检测基线从上一代换了过来。它最大的变化是去掉了NMS后处理。传统YOLO模型做完推理后还得跑一遍非极大值抑制去掉重复框这个步骤不仅多耗时间还经常因为阈值设置不当让密集目标被误删。水下鱼群往往挨得很近NMS阈值稍微调高一点两条相邻的鱼可能被合并成一个框这事我在老版本上踩过不止一次。YOLOv10采用无NMS的设计推理时直接输出最终结果管线干净了密集目标的漏检也明显改善。另外YOLOv10在主干部分引入了更高效的结构融合了大卷积核和部分自注意力机制。自注意力对全局信息比较敏感对水下这种光照不均衡、目标尺寸跨度大的场景是友好的。轻量化版本YOLOv10n可以在普通CPU上勉强跑实时而标准版YOLOv10s在显卡上能获得不错的精度和速度平衡。对于一个要交付的水下鱼类检测系统YOLOv10能直接导出标准权重用于部署生态也比很多自研网络成熟出了问题在社区里基本都能找到答案。1.3 系统整体架构数据训练、权重推理和界面交互怎么协作整个系统的运行链路大概是这样的先用整理好的水下鱼类YOLO数据集训练模型训练结束后保留精度最好的权重文件接着加载这个权重封装一个检测模块负责对图片、视频帧或摄像头画面做前处理、推理、后处理最后UI界面调用这个检测模块把帧画面、检测框、类别、置信度和统计数字一起呈现在窗口里。用户不需要关心模型在哪训练、权重怎么加载只需要点击按钮选择文件或者打开摄像头。这个架构里有一个容易被忽略的点模型推理和界面必须在不同线程里跑。摄像头画面是持续输入的如果推理阻塞了UI主线程窗口就会卡死鼠标拖不动、按钮没反应。正确做法是把检测循环放到后台工作线程界面线程只负责接收结果并刷新画面。这一点看起来简单但很多初学者做出来的工具卡顿严重就是没处理好线程关系。后面我会专门讲UI集成时的线程设计。2. 数据集准备决定模型上限的第一关2.1 水下鱼类数据整理来源筛选决定后面省不省心说到数据集我先泼一盆冷水别想着随便下个公开数据集就直接开训。水下鱼类数据有几个典型问题一是类别分布极度不均衡常见鱼种可能上千张稀有鱼种可能只有几十张二是很多公开数据是人工挑过的“干净图”水色、光照和真实水下设备拍到的画面差异很大三是不同公开数据集的标注风格不一样有的把整群鱼标成一个框有的把每条鱼单独标出来直接混用会让模型学得很乱。我在整理这个项目的数据时主要做了三件事。第一按类目统计数量把低于阈值的类别做筛选太少的目标干脆先砍掉或者用数据增强补样本第二做帧级去重水下视频连续帧高度相似如果直接把视频抽帧全扔进去训练集和验证集里会有大量几乎相同的图片验证指标虚高换个视频立刻打回原形第三把数据按来源视频分组划分训练集和验证集时保证同一个视频的帧不会同时出现在两边这样才能验证模型的泛化能力而不是背题能力。2.2 标注规范与YOLO格式转换坐标归一化别搞错YOLO系列使用的标注格式是txt文件每张图片对应一个同名txt文件里的每一行代表一个目标类别编号、中心点x坐标、中心点y坐标、目标宽度、目标高度后四个值都以图片宽度和高度做归一化取值在0到1之间。很多常见标注工具导出的是VOC的XML格式或者COCO的JSON格式转成YOLO格式时经常会出两类错误一是忘了做归一化把绝对像素坐标直接写进去模型训练时梯度直接爆炸二是目标越界标注框有一部分超出图片边界归一化后出现大于1的值训练虽然能跑但边界框学习得很奇怪。我习惯在转换脚本里加一个防御逻辑如果计算出的中心坐标或宽高超过0到1范围就钳制到合法区间并打印一行警告。用labelme或类似工具标注的时候尽量贴着鱼的身体边缘画框不要太贪心把鳍和尾巴全框进去也不要太紧凑导致鱼类身体被截掉一半。水下画面模糊边缘看不清的情况非常多我的原则是宁可稍微保守一点确认不了的区域宁可不标也不要标一个带着大量背景的框否则模型会把背景纹理一起学进去。2.3 数据增强策略让模型适应低光、浑水和密集遮挡水下鱼类检测的增强策略和常规检测不太一样重点要模拟水体光学特性。常规增强里的随机翻转、缩放、平移、马赛克都可以用但颜色增强的幅度要格外注意。水下环境本身偏蓝绿色如果你把HSV色相扰动开得很大模型可能会被教得“觉得什么颜色都有可能”反而丢失了物种颜色的判别信息。我更倾向于做定向增强降低亮度模拟深水区加一点高斯噪声模拟悬浮颗粒偶尔用运动模糊模拟相机抖动适当提高对比度模拟清澈水质的边缘锐利画面。马赛克增强对水下密集目标很有效它把四张图拼成一张能强迫模型在一个较小的感受野里看到更多目标提高密集鱼群的检测能力。但马赛克也会改变目标尺寸分布训练后期可以关闭它让模型在接近真实尺度的分布上微调。我在这个项目里大约留了30%的原始样本不做任何增强保证模型见过真实分布。增强只是辅助不要喧宾夺主。3. YOLOv10模型训练从环境搭建到权重出炉3.1 环境配置与依赖安装踩坑最集中的环节训练环境建议直接用Python 3.10或3.11PyTorch 2.xCUDA能装多新就装多新但前提是显卡驱动跟得上。如果你想省事直接安装ultralytics这个包YOLOv10的官方训练命令已经被集成进去了。这里有一个老生常谈但必须强调的坑PyTorch的CUDA版本和系统驱动不匹配会导致模型训练时直接报错说没有可用的GPU。安装前先确认本机显卡驱动支持哪个CUDA版本再选择对应版本的PyTorch安装命令顺序不能反。数据集配置文件要写成YAML格式写上训练图片路径、验证图片路径和类别名称列表。类别名称的顺序非常关键YOLO会根据txt标注里的数字索引去对应这个列表如果你把类别顺序搞乱了训练出来的模型预测结果标签就会张冠李戴。我建议在训练前先写一个小脚本随机挑几个txt文件把标注内容和原图画出来人工核对一遍确认编号和类别名对得上再开训练。3.2 训练参数设置这些关键参数直接影响最终效果我训练这个水下鱼类项目时基础命令是这样的yolo detect train datafish.yaml modelyolov10s.pt epochs300 imgsz640 batch16 device0几个核心参数给新手拆解一下。epochs不要只看绝对数值要结合早停机制来看我习惯设一个偏大的值比如300然后打开早停验证集指标连续20个epoch没提升就自动停止省时间也防止过拟合。imgsz默认640如果你的显卡显存够鱼群中小目标又多可以尝试加到1024甚至1280小目标召回率往往能明显改善但显存占用会成倍增加这个需要按硬件条件取舍。batch的选择主要受显存限制跑不起来就减半不要硬扛。预训练权重的选择也很有讲究。yolov10n适合显存小、追求速度的机器毕竟是先跑通流程yolov10s是我在这个项目里的主力选择精度速度平衡如果场景特别复杂且显卡没问题用yolov10m或更大。加载预训练权重可以显著降低训练收敛时间特别是在鱼类数据集和训练数据不多的情况下直接凭空训练非常容易过拟合。损失曲线如果训练到后期还在高位震荡优先检查的是学习率默认的0.01对大多数情况没问题但小数据集上可以适当降低。3.3 训练过程监控与效果评估不能只看loss值训练期间我习惯盯三个东西loss曲线、PR曲线和验证集上的batch预测图。loss只反映一个整体的收敛趋势它降不代表每个类别都学好了。PR曲线能直观看到每个类别的查准率和查全率权衡如果某个鱼类类别的曲线面积明显低于其他类说明这个类别的训练样本可能不足或者标注质量有问题。还有一张典型的错误分析图能按类别展示漏检、误检和定位误差的比例这套图经常能帮我快速定位模型到底卡在哪。训练结束后验证集上我最看重的两个指标是mAP50和mAP50-95。mAP50看的是粗略定位的识别能力mAP50-95则对框的定位精度要求更高更适合评估水下密集目标场景。保存权重时ultralytics默认同时输出best.pt和last.pt千万别拿last.pt去部署它只是最后一个epoch的快照不一定代表最优状态。我用最终模型在真正没参与训练的水下视频上做了一轮盲测原图和检测框叠加播放确认效果符合预期这一步比任何指标都更有说服力。4. UI界面集成把模型包装成正式工具4.1 界面框架选型为什么我用PySide6给模型配界面可选方案不少但我还是推荐PySide6这个Qt for Python的绑定库。原因有三个第一它自带成熟的窗口、按钮、文件选择、表格、画布组件不需要自己造轮子第二Python直接调用和推理代码天然融合不需要额外开服务再搞一套前后端通信第三跨平台Windows上打包成exe也很成熟对交付友好。相比纯命令行或者临时画个网页界面PySide6做本地检测工具是最稳妥的选择。UI布局我按“中间大画面、两侧辅助信息”的思路来设计。主区域是图像显示区实时显示原画面和检测框叠加结果。左侧放文件选择、模式切换按钮包括选择图片、选择视频、打开摄像头右侧显示当前帧的检测结果表格包含类别、置信度、坐标下面是全局统计信息比如总鱼数、各类别计数。界面的默认背景用深色检测框用亮色对比水下画面普遍偏暗深色界面不会抢视觉注意力。4.2 三种输入模式图片、视频、摄像头的实现要点图片检测最简单调用文件对话框选图读取后缩放至模型输入尺寸推理后把检测框画回原图再在界面上显示。需要注意的一点是OpenCV读取的图片默认是BGR通道而UI组件显示图像时通常要求RGB中间少一步颜色转换检测结果倒是没问题但显示出来的图颜色会偏蓝绿。这个细节在带水下数据的界面里特别容易弄混因为水下画面本身偏色颜色不对往往看不出来。视频检测和摄像头检测本质上是一个逻辑都是循环读帧、推理、显示。关键差别在于摄像头需要处理设备索引和帧率问题。OpenCV的VideoCapture如果打不开首先要检查索引号是否正确USB摄像头很多时候不是0号设备其次摄像头初始化后要等一两秒让自动曝光稳定下来否则前几帧画面一片漆黑或过曝。后台工作线程里跑推理时一次性不要把所有帧都塞进模型要控制处理频率比如每秒最多处理10帧其余帧直接跳过留给界面刷新。否则模型推理速度跟不上视频帧率队列越积越多画面延迟会越来越大。4.3 检测结果展示与导出让用户能查到明细和统计检测框画出来只是第一步真正让这个系统“有用”的是结果可追溯。我在界面上放了一个QTableWidget的表格每一行显示检测到的鱼类别、置信度、中心坐标、宽高。置信度可以加一个滑块实时调节低于阈值的检测框即时消失这个功能非常实用因为不同水域的模型置信度分布差异很大固定阈值往往顾此失彼。类别过滤用下拉多选框用户只想看某两种鱼的时候把其他类别隐藏掉就行。导出功能我做了两个一个是把当前帧带检测框的结果图保存成图片另一个是把整段视频的检测结果追加写入CSV文件包含时间戳、类别、置信度和坐标。对水产养殖场景来说按时间统计鱼群数量的变化曲线很有价值。这个项目里我先做到CSV导出后面如果要做长期趋势分析再基于这些数据进行二次开发整个系统的数据链路是留好的。5. 常见问题与调试实录这些坑我替你踩过了5.1 训练阶段高频报错与解决方案训练时最常见的报错就是“CUDA out of memory”。遇到这个不要只想着换显卡先检查batch尺寸减半再试。如果batch已经很小还是爆显存把imgsz从640降到480虽然精度会有些牺牲但至少能把流程跑通。另一种经常让人摸不着头脑的情况是loss出现nan我遇到过几次基本都出在数据集上要么是标注文件里出现了空文件导致图片没有目标要么是归一化坐标算出了负数要么是类别编号越界。遇到nan就优先检查数据而不是去调学习率方向搞错了会浪费大量时间。还有一个是训练开始后不到几十个epoch就提前停止而且指标很低。这种情况大概率是验证集图片里根本没有几个目标或者验证集和训练集分布完全不一致。水下数据如果按文件名随机切分同一个视频的相邻帧可能同时出现在训练集和验证集里指标虚高后会提前早停而如果切分时不小心把某个类别的样本全部切到了验证集里那训练集没有该类样本验证时又全是该类样本效果自然崩。所以我前面反复强调切分数据时一定要按视频来源分组这是经验之谈。5.2 推理端性能排查界面卡顿和速度慢怎么办界面卡顿十有八九是线程问题把推理放到QThread后台线程里是最直接的解法。如果线程分离了还卡那就要看是不是推理线程和界面线程共享了同一个OpenCV窗口对象导致资源冲突。正确的做法是推理线程只输出结果帧和检测数据界面线程统一负责绘制。另一个常见的慢源是模型在CPU上跑YOLOv10n在CPU上勉强能到实时但yolov10s在CPU上会掉到每秒几帧视频检测看着就像幻灯片。我的建议是部署机至少有个普通显卡推理时开启半精度速度能提升不少。如果还想更快可以把权重先导出成ONNX格式再推理。ONNX经过图优化后在某些机器上比直接烧PyTorch权重快不少。导出命令大概是yolo export modelbest.pt formatonnx opset12 halfTrue导出后写一个ONNX Runtime的推理脚本记得把输入图像的预处理保持一致缩放方式、归一化系数、通道顺序都不能变否则输出结果会莫名其妙地偏差。ONNX推理不仅速度快也能把项目和生产环境解耦后续换TensorRT也能顺理成章。5.3 精度不够时的调优方向从数据、模型、后处理三个层面下手如果模型跑下来对某一类鱼的漏检率很高我先不会急着换更大的模型而是去数一数这个类别在训练集里的样本数量。样本少于100张先想办法补充或者用增强模拟更多姿态样本充足但依然漏检我再看标注框是不是画得太大把太多背景包进去了。很多时候精度瓶颈根本不在模型结构而在数据质量的死角。当数据已经比较干净就可以考虑把imgsz提高到1024或1280。水下小目标在半米范围内看得很小640输入对它们来说只有几十个像素放大输入尺寸是最直接的提升方式。如果显存扛不住大输入可以试试使用更大体量的模型或者对目标区域做类别间重采样让稀有类别在训练时的参与比例更高一些。最后还可以在后处理上做文章不同类别单独设置置信度阈值比如优势鱼种阈值调高一点减少误报稀有鱼种阈值调低一点提高召回这个在UI里用一个配置文件维护就行。我这个项目做到最后个人体会最深的是检测系统的复杂度不在于某个单一技术点而在于把数据、模型、界面、部署这些环节串成一个整体。水下场景又比一般场景更考验工程经验偏色、遮挡、小目标这些坑挨个踩一遍之后你再去碰其他视觉检测项目会顺手很多。每次交付这种带界面的检测工具我都会反复确认一件事不熟悉算法的人拿到手能不能在不看文档的情况下五分钟内完成第一次检测。能做到这一点系统才算真正做完了。
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/21 4:07:53
实时音频引擎rea核心链路与延迟优化实战解析
2026/10/21 4:02:53
开源PDF417解码器:从图像预处理到Reed-Solomon纠错的完整管线解析
2026/10/21 4:02:53
STM32裸机LWIP移植LAN8720A:PING通调优与避坑指南
2026/10/21 5:13:00
从rea极简命名拆解事件驱动架构:读取-求值-动作循环的设计与实现
2026/10/21 5:13:00
CPR 1.3.0:现代C++ HTTP客户端库实战指南
2026/10/21 5:13:00
CTF入门指南:赛制、五大赛道与以赛促学的实战路径
2026/10/21 5:13:00
打印机驱动搜索下载工具:自动识别与手动搜索实战指南
2026/10/21 5:13:00
litellm 统一大模型调用中间层:从 SDK 到生产级代理的完整实践
2026/10/21 5:08:00
YOLOv8-seg轮胎缺陷分割实战:数据集构建、模型改进与部署全流程
2026/10/21 0:01:44
ClickHouse实战:从列式存储到亿级数据秒级查询
2026/10/21 0:01:44
高效筛选arXiv机器学习论文:四步法实战指南
2026/10/21 0:01:44
Python爬取百度迁徙数据:接口签名、反爬与SQLite存储实战
2026/10/20 16:07:12
OpenResearch实战:Claude Code、Codex、OpenCode、Cursor 工作流搭建与故障排查
2026/10/20 7:57:25
知识管理核弹:用Obsidian构建第二大脑的工程化方案(TaoToken 统一 Key 接入版)
2026/10/20 16:49:38
金融AI落地指南:从调研报告到技术选型与工程实践
2026/10/20 2:24:03
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/20 2:23:57
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/20 2:23:53
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)