ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

MaixCam2部署Yolo11实现高速小球实时检测方案

MaixCam2部署Yolo11实现高速小球实时检测方案 做比赛视觉题最怕的不是模型精度不够而是“训练时一切正常一上板子就崩”。如果你正在准备类似的竞赛项目或者打算用嵌入式 AI 视觉板卡做实时检测这篇内容应该能帮你少踩很多坑。本文要讲的是一套已经在省级赛题中拿过一等奖、并且所有问题项均满分的方案用 MaixCam2 部署 Yolo11 模型实现高速小球的实时检测与输出。整套方案的核心不是某个玄学调参而是把“训练、导出、转换、部署、帧率优化”这条链路完整打通。先给结论在边缘端做目标检测真正拉开差距的并不是模型选得有多大、训练了多少轮而是你能不能把模型准确、稳定地跑进嵌入式设备里并且在现场光照、背景、运动模糊等干扰下依然不丢帧、不错检。下面我会按实际开发顺序把选型依据、数据集制作、模型训练、模型转换、板端部署、60 帧优化思路和竞赛现场经验完整拆开讲。1. 这类竞赛视觉题到底难在哪里如果你参加过类似的硬件视觉类赛题应该对这套流程不陌生题目要求摄像头识别场地中的小球把小球坐标、颜色或运动状态实时传给主控再由云台、小车或机械臂执行跟踪、抓取或避障动作。看起来只是“识别一个小球”但真正写起来会发现一堆问题小球在画面里目标很小容易受到地面纹理、光照反光影响现场光线不一定均匀同一个颜色在不同时间、不同角度下拍出来差异很大小球运动起来会产生拖影传统按帧处理很容易丢目标主控和视觉板之间还要通信视觉处理不能占用太多时间。不少人第一反应是用 OpenCV 做颜色阈值分割再加霍夫圆检测或轮廓筛选。这个方法在实验室固定光照下确实能跑但现场换一盏灯、换一块地面阈值就可能全部失效。更糟糕的是传统视觉很难处理“球被手短暂遮挡后继续出现”“两个球同时进入视野”“背景中有与球颜色接近的物体”这些情况。所以我们在方案里直接换了一条技术路线采用目标检测模型 Yolo11 做识别用一个带 NPU 的边缘视觉开发板 MaixCam2 做本地推理。模型负责“理解”什么是球、球在哪里硬件负责把推理耗时压到足够低最终才能在检测帧率上跑出理想效果。如果你只是想要一个能交差的比赛 Demo传统视觉也许够用但如果你希望方案在赛前调试、现场测试和最终展示中都比较稳基于 Yolo11 的深度学习检测方案是更值得投入的方向。2. 认识核心器件Yolo11 与 MaixCam22.1 Yolo11 是什么Yolo11 是 Ultralytics 在 YOLOv8 之后推出的目标检测系列模型。它不是一个单独的文件而是一整套包含模型定义、训练 pipeline、验证工具和部署导出工具的体系。Yolo11 支持目标检测、实例分割、姿态估计、旋转框检测和图像分类等任务因此你在很多新项目里会看到它被当作默认视觉基线。从网络结构上看Yolo11 延续了 YOLO 系列“CSPDarknet 风格主干 PAN-FPN 颈部 解耦头”的总体设计但在细节上做了轻量化改进。比如用 C3k2 这一类模块替代了部分旧模块在保持特征融合能力的同时减少了冗余计算同时针对注意力机制的使用位置也做了调整让模型在小目标检测与实时推理之间更容易取得平衡。对做竞赛和边缘部署的人来说Yolo11 更值得关注的是它提供了 n、s、m、l、x 多个规模。n 版本很小适合跑在内存和算力有限的开发板上s 版本属于精度和速度比较均衡的常用选择。比如我们最终部署时就要考虑模型体积和推理时间而不是一味追求 mAP。2.2 为什么说 Yolo11 比 YOLOv8 更适合这类小项目很多同学会问YOLOv8 已经很成熟了为什么还要换 Yolo11从官方数据来看Yolo11 在同精度档位下参数量和计算量通常比 YOLOv8 更低也就是说同样的设备上推理帧率可能更高更符合边缘端实时检测的需求。虽然实际帧率与输入分辨率、硬件优化程度、类别数量都有关系但在模型选择上Yolo11 的 nano 和 small 版本确实更适合放进嵌入式设备。此外Ultralytics 生态统一了训练、验证和导出体验。你可以在同一套 Python 环境里跑 YOLOv8 的老数据集也能直接切换到 Yolo11 重新训练代码改动很小。对项目周期紧张的竞赛场景来说这种迁移成本低的特点非常重要。不过要注意Yolo11 并不是“万能药”。如果检测目标特别小还是需要靠提高输入分辨率、增加训练数据里的目标尺寸占比来弥补。模型只是中间层数据质量和部署链路才是决定成败的关键。2.3 MaixCam2 是一块什么样的板子MaixCam2 是 Sipeed 推出的一体化 AI 视觉开发板延续了 MaixPy 开源生态。它把摄像头、屏幕、NPU 和 Linux 运行环境集成在一个小体积设备上适合做边缘 AI 视觉原型和竞赛方案验证。与传统单片机图像方案不同MaixCam2 上有较完整的 Linux 环境可以运行 Python 应用并通过官方 SDK 调用摄像头采集、屏幕显示、模型推理等功能。同时它的 NPU 可以加速神经网络运算使得在板端直接跑 Yolo11 这类轻量检测模型成为可能。对竞赛场景来说MaixCam2 带来的最大好处是开发效率高。你不需要自己写底层驱动不需要反复调试摄像头寄存器只需要关注上层视觉逻辑。同时它支持模型部署的完整转换流程可以把主机上训练好的 PyTorch 模型逐步转换为设备端可运行的格式。3. 整体系统方案与技术架构这个项目最终要实现的效果是MaixCam2 对着比赛场地以 60 帧的检测速率识别小球并把小球在画面中的坐标、可信度等信息及时送到执行端执行端根据坐标完成跟踪或者控制动作。从软件模块上划分整个系统包含四层图像采集层通过 MaixCam2 的摄像头采集画面模型推理层对画面中的小球执行 Yolo11 检测输出边界框坐标转换层把像素坐标按比例换算为执行机构需要的坐标通信控制层把结果通过串口、Wi-Fi 或 GPIO 输出给主控。这里有一个容易被新手忽略的关键点60 帧不是“摄像头能出 60 帧”而是“整条检测链路能达到 60 帧”。摄像头输出帧率高但模型推理耗时长就会产生帧堆积和延迟模型推理够快但画面读取不加缓冲也会因为阻塞导致掉帧。因此工程上需要同时关注采集缓冲、推理耗时、后处理和坐标转换的同步。在这个项目里我们把主要的视觉处理压力放在了 MaixCam2 上执行端只负责读取结果和执行动作。这种“视觉模块 执行模块”分离的架构可以有效降低主控的实时负担也让视觉部分可以独立调参。4. 环境准备与前置条件开始跑通一条完整链路之前建议先准备好以下环境。4.1 训练主机环境训练 Yolo11 需要一台带 NVIDIA 显卡的电脑或服务器使用 PyTorch 和 Ultralytics 作为主要框架。操作系统推荐 Windows 11 或 Ubuntu 20.04/22.04内存建议 16GB 以上显卡显存建议至少 4GB。如果显存较小可以把训练图片尺寸调低或者使用 Yolo11n 这种小模型训练显存占用会明显下降。Python 版本建议使用 3.8 到 3.11 之间的版本具体以 Ultralytics 当前官方说明为准。安装依赖时需要先安装对应 CUDA 版本的 PyTorch再安装 ultralytics。很多同学在这里容易踩坑直接pip install ultralytics但 PyTorch 是 CPU 版本导致训练速度极慢甚至无法使用 GPU。先在 Python 里执行一下import torch; print(torch.cuda.is_available())能输出 True 再开始训练。如果你使用的是 CUDA 12.4 环境安装 PyTorch 时要注意选择 cu124 对应的安装命令而不是默认的 cu118 或 cu121。判断有没有装错最简单的方式就是看启动训练时日志里是否显示使用 GPU如果没有说明 PyTorch 和 CUDA 版本不匹配。4.2 开发板环境MaixCam2 需要先烧录官方固件。烧录完成后板子开机进入 MaixPy 环境可以通过屏幕直接看到摄像头画面。开发调试时建议把板子通过 USB 连接到电脑在串口终端里运行 Python 脚本这样能看到 print 输出的调试信息也方便把本地代码推送到板端。如果板端部署需要先把模型转换成 MaixCam2 能加载的格式一般有两种方式一种是使用官方提供的模型转换工具链在本地 PC 完成转换另一种是使用 MaixHub 等官方在线转换服务。推荐把转换流程写在项目文档里这样赛前重新部署时不会手忙脚乱。5. 数据准备与 Yolo11 模型训练5.1 数据采集策略目标检测模型的效果上限很大程度由数据集决定。尤其是比赛场地里的小球如果你只在实验室的一个角度采集数据模型在正式场地上很容易失效。我们在采集数据时主要覆盖了几个维度不同距离近距离大球、远距离小球都有不同角度从低角度、平视、俯视各拍一些不同光照室内灯光、自然光、局部强光不同背景地面、桌面、比赛场地、有干扰物的环境运动状态静止小球、滚动小球、运动模糊状态。数据量不需要太大但对这个单一类别任务几百张高质量图片往往比几千张重复图片有用得多。标注工具可以使用 LabelImg也可以使用支持 YOLO 格式导出的标注平台。标注统一为 YOLO txt 格式每个 txt 文件与图片文件名一一对应里面记录“类别编号、目标中心 x、目标中心 y、目标宽度 w、目标高度 h”。完成后建议将数据按 8:1:1 划分为 train、val、test 三个文件夹。5.2 数据集目录结构推荐按下面的结构组织目录ball_dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yaml注意YOLO 训练时读取的是 yaml 里的路径如果你的数据集目录移动过位置记得同步修改 yaml 中的绝对路径或相对路径。data.yaml 内容类似这样path: D:/ball_dataset train: images/train val: images/val test: images/test nc: 1 names: 0: ball类别数量 nc 为 1因为我们只需要检测小球这一类目标。如果你需要同时检测红球、绿球、篮球等再把 names 改成多个类别。5.3 训练代码与参数选择编写训练脚本时可以用 Ultralytics 封装好的 API# 文件路径train_yolo11.py from ultralytics import YOLO model YOLO(yolo11s.pt) # 使用 Yolo11s 预训练权重作为起点 results model.train( databall_dataset/data.yaml, epochs150, imgsz640, batch16, device0, workers4, patience20, projectruns/ball_train, nameyolo11s_ball, exist_okTrue, )关键参数说明epochs训练轮数。数据量不大时150 轮足够了。如果连续多轮验证集损失不下降patience 参数会自动提前停止。imgsz输入图片尺寸。640 是训练精度与速度的平衡点。如果后续板端部署输入是 320也可以直接训练 320能更快收敛但需要人工确认小目标是否还清晰。batch根据显存调整。显存不足报 OOM 时可以降低 batch。device0 表示第一张显卡没有 GPU 可以写 cpu但训练会非常慢。5.4 训练结果验证训练结束后在runs/ball_train/yolo11s_ball/weights/目录下会生成best.pt和last.pt。best.pt 是验证集上表现最好的权重也是我们后续导出要用的文件。在验证阶段重点不是看 mAP 数字而是要在自己的测试图片上做推理观察漏检和误检是否集中在特定场景。比如我们曾发现模型对“只露出一半的小球”漏检率较高后来通过补充遮挡样本才明显改善了这个问题。6. 模型导出与设备端转换模型训练完成后不能直接把.pt文件放到 MaixCam2 上运行。Yolo11 默认是 PyTorch 模型嵌入式设备需要的是经过转换、量化和适配 NPU 的格式。6.1 导出 ONNX第一步是把 PyTorch 模型导出为 ONNX。使用 Ultralytics 自带命令yolo export modelruns/ball_train/yolo11s_ball/weights/best.pt formatonnx imgsz320 opset11这里把imgsz设为 320是为了和板端推理输入分辨率保持一致。很多同学习惯训练 640导出 640最后部署时性能不够如果板子算力有限更合理的做法是训练时就使用接近部署时的分辨率或者在导出时降为 320并重新验证效果。导出后生成best.onnx。可以用 Netron 打开查看模型结构确认输入输出节点。6.2 转换为 MaixCam2 可加载模型ONNX 模型还需要经过官方工具链转换为设备端模型格式。不同固件版本的转换方式可能略有差异常见做法是把模型上传到 MaixHub 的在线转换服务或使用官方本地转换工具按目标板卡选择 MaixCam2。转换时通常会有几个选项是否量化竞赛场景下如果板端推理帧率不够可以尝试 int8 量化但量化后精度会有一定损失。输入尺寸需要和导出 ONNX 时的 320 保持一致。输出格式后处理是否在板端完成建议保留原始输出然后在 Python 里自己写 NMS调试起来更直观。转换过程中最容易遇到的问题是模型里包含某些 NPU 不支持的算子。解决办法通常是把图像预处理操作尽量放到模型外面或者替换为更常见的算子避免使用过于新奇的模块。7. 板端部署代码实现当模型转换成功后可以在 MaixCam2 上编写部署脚本。如果你的固件版本支持 MaixPy 风格 API核心流程大致如下# 文件路径main.py在 MaixCam2 上运行 from maix import camera, display, image, nn, app detector nn.YOLO11(model/root/models/ball_kmodel.mud, dual_buffTrue) cam camera.Camera(detector.input_width(), detector.input_height(), detector.input_format()) disp display.Display() while not app.need_exit(): img cam.read() objs detector.detect(img) for obj in objs: x1, y1, x2, y2 obj.x, obj.y, obj.x obj.w, obj.y obj.h img.draw_rect(x1, y1, x2, y2, colorimage.COLOR_RED) img.draw_string(x1, y1 - 10, fball:{obj.score:.2f}, colorimage.COLOR_RED) disp.show(img)这里需要解释几个细节dual_buffTrue表示开启双缓冲能减少图像读取和推理之间的等待时间对提升帧率很有帮助。detector.input_width()和detector.input_height()会从模型文件信息里读取输入尺寸确保摄像头输出和模型输入一致。检测结果中的obj.x、obj.y、obj.w、obj.h是边界框在模型输出坐标系下的结果。如果你需要输给主控控制云台还需要把像素坐标换算成你约定的坐标。实际项目中我们通常会在检测基础上增加目标平滑避免输出坐标抖动。最简单的做法是滑动平均from collections import deque history deque(maxlen5) def smooth_point(cx, cy): history.append((cx, cy)) n len(history) avg_x sum(p[0] for p in history) / n avg_y sum(p[1] for p in history) / n return int(avg_x), int(avg_y)这段代码的意思是维护最近 5 帧的检测中心求平均值作为输出坐标。这样即使偶尔有一帧检测框轻微偏了输出也不会剧烈跳动。串口发送部分可以根据主控协议自行实现。例如每帧发送BALL_X123 Y89 CONF0.95主控收到后解析即可。如果使用串口建议在发送频率上和控制需求匹配不要每帧都全速发数据防止主控来不及处理。8. 项目中的帧率优化方法“60 帧检测小球”的核心在帧率调优。这里记录几条我们在实际工程中验证过有效的优化手段。8.1 降低输入分辨率Yolo11n 在 640 尺寸下的推理耗时会明显高于 320 尺寸。对于比赛场地里“小球”这个目标320 输入通常已经能够保证识别。如果目标实在太小可以把输入设置为 416这是一个折中方案。需要结合你现场摄像头的安装高度来评估小球在画面中占多少像素决定你最低能用多大分辨率。8.2 减少检测类别只检测“小球”这一类比同时检测“红球、蓝球、目标点、障碍物”等类别要快得多。因为类别越多最终后处理和分类计算量越大。如果题目要求区分颜色尽量在模型里做多分类或者用两个阶段的传统颜色判断而不是同时开启三个模型。8.3 开启双缓冲MaixCam2 的摄像头读取和模型推理是两个耗时点。开启双缓冲后系统可以在推理上一帧的同时采集当前帧排队时间被隐藏整体帧率提升非常明显。8.4 避免频繁打印和绘制在调试阶段打印每帧的目标坐标、在屏幕上绘制全部框非常有用但在正式运行时过多的 print 和画框会消耗 CPU 时间影响帧率。正式版本可以只保留关键帧的调试输出或者把可视化关闭。8.5 从后处理里省时间Yolo11 原始输出往往包含大量候选框如果在设备端做完整 NMS会占用不少时间。实际在单一目标场景下我们可以先按置信度对结果排序只保留最高置信度的前几个框再去做 NMS。这种“小 trick”能在不影响精度的前提下减少循环次数。9. 竞赛现场常见问题与排查思路竞赛现场和实验室环境差异很大。下面这几个问题是我们在准备和现场测试中比较常见的建议提前做预案。问题现象可能原因排查方式解决思路板端加载模型失败模型格式与固件不匹配确认转换时选择的板卡型号和固件版本使用与固件配套的转换工具或升级固件检测不到小球光照过暗或逆光查看摄像头原始画面是否清晰增加补光、调整摄像头曝光参数检测框乱跳背景中有相似颜色圆形物体导出训练数据中背景干扰样本采集更多负样本并标注背景类别增加干扰物帧率远低于 60输入分辨率过高用脚本打印模型推理耗时降低 imgsz、开启 dual_buff、关闭过多绘制小球运动模糊严重曝光时间过长检查摄像头设置调短曝光、提高帧率现场颜色与小样本不一致数据集过度单一多场景采集在赛前进行快速数据增强微调排查帧率问题时建议先在脚本里分别测量三段耗时读取摄像头耗时、模型推理耗时、后处理和显示耗时。不要笼统地说“板子卡”要定位到具体环节才知道该改分辨率还是改代码。9.1 启动失败先看三处如果板子运行脚本直接报错第一步不要猜按顺序检查模型路径是否正确很多同学把模型文件放到 U 盘但脚本里写的是绝对路径 /root/models/一开机没挂载就找不到文件。摄像头输入尺寸和模型输入尺寸是否一致如果不一致接口会自动缩放或报维度错误需要统一配置。当前固件是否支持示例中的 nn.YOLO11 接口不同版本 API 有差异建议查看随固件发布的示例代码。10. 从竞赛项目到工程落地还有哪些建议竞赛项目往往追求短周期内出效果但这套方案里有些思路同样适合真实的视觉检测项目。第一一定要固化全链路流程。训练、导出、转换、部署、验证这五个步骤任何一个环节手工操作都容易出错。建议在项目目录下保存一份 README记录训练命令、导出命令、转换时使用的参数、模型在板端的路径和测试结果。这样即使赛前一天换一块板子也能按文档快速恢复。第二保存多个版本模型。训练得到 best.pt 后不要急着删除 last.pt量化后的模型和未量化模型也分别保存。不同场景下量化模型可能精度不够但你未必有时间立刻重新训练保守起见保留多个备选权重很重要。第三准备好“兜底方案”。深度学习模型在极端环境下依然可能失效因此我们保留了基于 HSV 颜色过滤的快速检测作为备用逻辑。当 Yolo11 连续多帧检测不到目标时可以切换到传统视觉方式尝试找回目标再切回模型检测。这个降级策略在演示现场很管用。第四在主控通信层加上看门狗式和超时机制。如果视觉模块因为异常停下主控要能感知到而不是一直等数据。简单做法是每帧附带序号或时间戳主控若发现连续 1 秒没有收到新数据就提示视觉模块重启或者发出警告。工程化水平的提高往往不是体现在算法多先进而是体现在遇到问题时能不能快速定位、快速恢复。11. 总结基于 MaixCam2 和 Yolo11 做高速小球检测是一个典型的“模型轻量化 边缘部署 实时系统”问题。训练 Yolo11 只是其中一环更关键的是要把模型转换到设备端调整输入尺寸和后处理让整条检测链路的帧率达到项目要求。在这套方案中Yolo11 承担了鲁棒的视觉理解任务MaixCam2 提供了可落地的边缘算力和成熟的开发环境两者的组合让竞赛队伍把主要精力放到系统联调上而不是去纠结底层图像处理和模型部署格式。如果接下来你想继续深入有几个方向值得关注第一尝试用更多真实场景数据提升小目标检测能力第二在保证帧率的前提下做 int8 量化对比实验看精度损失多少第三把检测和控制闭环做成 PID 或串级控制让小球坐标直接驱动云台平滑跟踪。无论方向怎么选建议先把自己的部署脚本、转换流程和比赛现场日志整理成标准模板这样后续项目才能重复利用。
返回列表