ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

简单的yolo识别训练并移植到ROS1

简单的yolo识别训练并移植到ROS1 第一步本地环境检测与创建核心训练模型对显卡GPU有硬性要求。在本地 Dell 电脑上我们需要建立一个支持 CUDA 加速的 PyTorch 环境。1.1 硬件与驱动检查在 Dell 电脑上打开普通的命令提示符cmd或终端运行以下命令nvidia-smi检查目的确认你的 Dell 电脑是否有 NVIDIA 显卡如 RTX 3060/4060 等并记录下右上角显示的CUDA Version例如CUDA Version: 12.x或11.x。这决定了你后续能安装的 PyTorch 版本。1.2 创建隔离的 Anaconda 虚拟环境为了不污染你电脑上的其他 Python 项目建议在本地也创建一个名为yolov5_train的独立虚拟环境。在 Anaconda Prompt或终端中依次输入# 1. 创建 Python 3.8 的虚拟环境 conda create -n yolov5_train python3.8 -y # 2. 激活该虚拟环境 conda activate yolov5_train检测当前环境请把下面这行测试脚本直接复制到你当前的终端确保处于(yolov5_train)环境下并回车运行python3 -c try: import torch print(✅ PyTorch 已安装版本:, torch.__version__) print( GPU 加速CUDA状态:, torch.cuda.is_available()) if torch.cuda.is_available(): print( 显卡型号:, torch.cuda.get_device_name(0)) except ImportError: print(❌ 未检测到 PyTorch) try: import torchvision print(✅ Torchvision 已安装版本:, torchvision.__version__) except ImportError: print(❌ 未检测到 Torchvision) 1.3 安装带 CUDA 加速的 PyTorch根据你 1.1 步骤中查到的 CUDA 版本去 PyTorch 官网挑选对应的安装命令。如果是 CUDA 11.x通用安装命令通常为pip install torch1.12.1cu113 torchvision0.13.1cu113 --extra-index-url https://download.pytorch.org/whl/cu1131.4 环境验证测试关键环境装好后必须运行以下脚本验证 GPU 是否真正被 PyTorch 识别。在激活的虚拟环境中输入python进入交互模式import torch print(PyTorch版本:, torch.__version__) print(CUDA是否可用:, torch.cuda.is_available()) if torch.cuda.is_available(): print(当前显卡名称:, torch.cuda.get_device_name(0))通关标准必须输出CUDA是否可用: True并且正确打印出你的 NVIDIA 显卡型号。如果输出为False说明安装成了 CPU 版本无法用来加速训练。输入exit()退出 Python。1.5 安装 YOLOv5 依赖源码包将你小车上的yolov5-pytorch源码整体复制到这台 Dell 电脑上在终端中cd进入该目录利用国内源快速安装剩下的工具包cd path/to/yolov5-pytorch pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple第二步数据标注工具安装以及数据标注2.1 标注工具LabelImg需要在本地电脑上安装一个图片标注软件用来框选你的数字。pip install labelimg # 在终端直接输入 labelimg 即可打开可视化界面2.2 采集“数字标牌”数据集核心资产拍照采集用手机或小车摄像头拍摄比赛/课设中使用的数字标牌1、2、3、4。场景多样性每个数字至少在不同的光照、不同的距离、不同的侧倾角度下拍摄50 ~ 100 张照片。整个数据集建议在 300 张照片以上。摆放结构在yolov5-pytorch根目录下按照说明书创建VOCdevkit/VOC2007/JPEGImages放图片和VOCdevkit/VOC2007/Annotations放后面生成的 xml 标注。2.3 配置文件修改类别文件在model_data/下新建num_classes.txt里面写上1 2 3 4修改路径修改voc_annotation.py中的classes_path指向这个num_classes.txt运行它来自动切分出训练集和验证集的索引文件2007_train.txt。2.4 预训练权重垫底yolov5_s.pth训练不能从零瞎猜需要“站在巨人的肩膀上”。确保你的model_data/目录下有你之前看到的yolov5_s.pth文件。train.py会读取它作为基础特征骨干网络在此基础上收敛出你的数字特征。2.5 启动 LabelImg 标注工具在终端输入labelimg(如果弹出界面但终端疯狂报错提示缺少pyqt等请运行pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple后重试)2.6 进行黄金三配置最重要防止格式出错打开 LabelImg 的图形化界面后请立即完成这 3 点设置这是数据成功的关键确定格式点击界面左侧工具栏的那个大大的按钮它默认可能是 YOLO 或 CreateML多点几次直到它显示为PascalVOC。 原因你的小车代码包默认配置的是 VOC 数据格式如果我们选错了格式后面训练时会报错找不到标签。设置图片目录 (Open Dir)点击界面左侧的Open Dir按钮。选择目录~/yolo5/yolov5-pytorch/VOCdevkit/VOC2007/JPEGImages。此时你就能在界面上看到你的第一张数字图片了。设置保存目录 (Change Save Dir)点击界面左侧的Change Save Dir按钮。选择目录~/yolo5/yolov5-pytorch/VOCdevkit/VOC2007/Annotations。 原因这能确保每一个框选操作生成的.xml标签文件都被精准地存在它该去的地方。2.7 开始纯鼠标流标注步骤配置好后开始给这 173 张图片“点石成金”启用框选在键盘上按下W键Create\RectBox此时你的鼠标会变成一个十字光标。画框用鼠标十字瞄准图片里你要识别的数字标牌左键按住不放拖动拉出一个大小适中、刚好把数字标牌完全包裹住的框。输入标签名松开鼠标左键会弹出一个输入框。请直接输入你要训练的真实数字如果是数字 1就输入1。如果是数字 2就输入2。依此类推不要写复杂的名字如“num_1”只写纯数字标签。点击 OK。保存按下键盘Ctrl SSave保存这行标注。此时隔壁的 Annotations 文件夹里会多出一个对应的 xml 文件切换下一张按下键盘D键Next ImageLabelImg 会自动加载第 2 张图片。重复重复W(框选) - 输入数字 -CtrlS(保存) -D(下一张) 的循环。# 1. 下载 labelImg 的官方纯源码包 git clone https://github.com/HumanSignal/labelImg.git # 2. cd 进入刚刚下载的源码目录 cd labelImg # 3. 编译出 Linux 系统需要的界面资源文件 pyrcc5 -o libs/resources.py resources.qrc # 4. 直接用 Python 启动源码 python3 labelImg.py第三步生成训练索引与启动模型训练3.1 生成数据索引文件 (2007_train.txt)训练代码需要通过文本索引文件找到对应图片的标注路径。在终端中确保处于(yolov5_train)虚拟环境下执行# 确保在项目根目录 cd ~/yolo5/yolov5-pytorch # 生成数据集索引文件 python3 voc_annotation.py检查输出运行完毕后项目根目录下会自动生成2007_train.txt和2007_val.txt。可以通过ls -l确认文件已建立。3.2 启动训练在你的源码架构基于 bubbliiiing 版本 yolov5-pytorch中核心配置默认已在train.py文件内设置只需确认代码中classes_path已指向model_data/num_classes.txt。1. 直接运行默认训练命令最简指令python3 train.py2. 自定义参数启动命令推荐如果你需要通过命令行动态覆盖参数如调整 Batch Size、训练轮数等直接复制并运行以下指令python3 train.py \ --model_path model_data/yolov5_s.pth \ --classes_path model_data/num_classes.txt \ --input_shape 640 640 \ --Epoch 50 \ --batch_size 8 \ --num_workers 4 \ --cuda True Ubuntu 训练常见问题与调试建议显存溢出 (CUDA Out of Memory)如果显卡显存较小导致报错将--batch_size调小例如改成4或2python3 train.py --batch_size 4DataLoader 多进程报错若提示 multiprocessing 错误可将--num_workers设为0python3 train.py --num_workers 0后台挂载训练防止终端中断nohup python3 train.py train.log 21 tail -f train.log # 实时查看后台输出训练结果与部署训练启动后模型权重与日志会自动保存到logs/目录中best_epoch_weights.pth准确率最高的模型权重训练完成后将此文件拷贝到小车端/树莓派端部署使用。last_epoch_weights.pth最后一轮训练结束后的权重。完整全流程从录制视频 → 抽帧 → LabelImg标注 → 更新ImageSets → 生成训练索引 → 训练 → 导出OAK模型 → ROS部署适配你的项目工件实物颜色固定光照会变化工件运动距离可变bubbliiiing‑yolov5‑pytorchPascal‑VOC(xml)标签格式。 重点标注什么时候、用什么命令更新ImageSets/Main下面的txt文件。0.前期准备工作目录~/yolo5oak录制视频输出~/yolo5/workpiece_video/xxx.mp4OAK录制的工件视频yolov5‑pytorch项目路径~/yolo5/yolov5‑pytorchlabelImg路径~/yolo5/labelImgVOC目录结构标准yolov5‑pytorch/VOCdevkit/VOC2007/ ├─JPEGImages/ #存放所有抽帧jpg图片 ├─Annotations/ #存放对应xml标签图片和xml同名一一对应 └─ImageSets/Main/ #trainval.txt / train.txt / val.txt / test.txt**由voc_annotation.py自动生成不要手动编辑**步骤1OAK录制工件视频固定OAK相机支架工件在实际工作运动区间运动覆盖现场全部实际工作距离近‑远包含现场典型光照正常灯光、轻微阴影、明暗变化⚠️只录制【实物标准大小、标准本体颜色】工件不要录制变色、异形、别的物体。运行oak_record_video.py录制视频保存到~/yolo5/workpiece_video/例如work_01.mp4。步骤2视频抽帧把图片放进JPEGImages运行video_to_frames.py抽帧间隔不要太密避免大量重复图片。cd ~/yolo5 python3 video_to_frames.py输出图片命名格式num_target_0000.jpg、num_target_0001.jpg …将抽帧得到的全部.jpg复制到VOC的JPEGImages文件夹cp workpiece_images/*.jpg ~/yolo5/yolov5-pytorch/VOCdevkit/VOC2007/JPEGImages/校验ls ~/yolo5/yolov5-pytorch/VOCdevkit/VOC2007/JPEGImages确认图片全部存在。步骤3LabelImg标注PascalVOCcd ~/yolo5/labelImg pyrcc5 -o libs/resources.py resources.qrc python3 labelImg.py界面设置左上角格式切换为PascalVOC生成xml不是YOLO txtOpen Dir→ 选择~/yolo5/yolov5‑pytorch/VOCdevkit/VOC2007/JPEGImagesChange Save Dir→ 选择~/yolo5/yolov5‑pytorch/VOCdevkit/VOC2007/Annotations标注操作规则W画框框住标准工件弹出类别输入框填写target_workpiece无论图片里面有没有工件必须按 CtrlS 保存生成同名xml再按D下一张没有工件也要保存空xml否则后续脚本报xml找不到。 图片名num_target_xxxx.jpg↔ 标签num_target_xxxx.xml名字必须完全一模一样。标注完成校验jpg数量 xml数量cd ~/yolo5/yolov5-pytorch/VOCdevkit/VOC2007 ls JPEGImages/*.jpg | wc -l ls Annotations/*.xml | wc -l两个数字必须相等。步骤4更新 ImageSets/Main 的全部txt文件【重点】⚠️不要手动编辑trainval.txt不要自己手写文件名进去bubbliiiing的voc_annotation.py当annotation_mode 0时 脚本会自动扫描Annotations文件夹下面所有真实存在的xml文件自动生成 ImageSets/Main下面trainval.txt、train.txt、val.txt、test.txt。 新增/删除图片‑xml之后只需要重新运行voc_annotation.pyImageSets内容自动刷新。确认voc_annotation.py头部配置annotation_mode 0 classes_path model_data/work_classes.txt trainval_percent 0.9 train_percent 0.9 VOCdevkit_path VOCdevkitannotation_mode0①扫描Annotations的xml重写ImageSets下面全部txt②再生成根目录的2007_train.txt、2007_val.txt训练索引。annotation_mode1仅生成ImageSets下面txt不生成2007_train/val.txtannotation_mode2只读取已有的ImageSets/train.txt、val.txt不会刷新ImageSets新增图片时绝对不要用mode2确认类别文件model_data/work_classes.txtcd ~/yolo5/yolov5-pytorch cat model_data/work_classes.txt内容只有一行无多余空格换行target_workpiece运行脚本自动刷新ImageSetspython3 voc_annotation.py输出示例Generate txt in ImageSets. train and val size XX train size XX Generate txt in ImageSets done. Generate 2007_train.txt and 2007_val.txt for train done. | target_workpiece | XX |✔此时VOCdevkit/VOC2007/ImageSets/Main/trainval.txt已经自动更新为当前Annotations内所有xml对应的id。 脚本内部逻辑读取Annotations下全部.xml去掉后缀得到图片id随机划分train/val/test写入ImageSets下各个txt。查看ImageSets/Main/trainval.txt确认内容cat VOCdevkit/VOC2007/ImageSets/Main/trainval.txt同时项目根目录生成训练用索引文件2007_train.txt、2007_val.txt这两个是给train.py读取的。⚠️重要规则以后新增图片牢记每次新增一批图片xml把jpg复制进JPEGImageslabelImg全部标注生成对应xml修改voc_annotation.py确保annotation_mode 0执行python3 voc_annotation.py自动刷新ImageSets全部内容自动生成2007_train/val.txt。❌不要手动修改ImageSets里面任何txt手动改会出现id和实际xml不一致报FileNotFound。步骤5修改训练相关配置文件5‑1 train.py 修改classes_path model_data/work_classes.txt input_shape [640, 640] mosaic False model_path model_data/yolov5_s.pth Freeze_Train False UnFreeze_Epoch 100 Unfreeze_batch_size 8 #显存不足改为4/2 num_workers 0 eval_flag True5‑2 utils/dataloader.py 修改数据增强适配你的光照变化需求打开utils/dataloader.pyget_random_data函数头部参数def get_random_data(self, annotation_line, input_shape, jitter.3, hue0.0, sat0.25, val0.30, randomTrue):get_random_data_with_Mosaic函数头部参数def get_random_data_with_Mosaic(self, annotation_line, input_shape, jitter0.3, hue0.0, sat0.25, val0.30):hue0.0关闭色相偏移拒绝识别别的颜色物体sat、val小扰动模拟现场明暗光照变化保留随机scale缩放适配工件远近运动成像大小变化工件非对称注释掉flip翻转代码。train.py设置mosaicFalsemosaic增强不会执行。步骤6开始训练模型cd ~/yolo5/yolov5-pytorch #前台运行 python3 train.py #或者后台运行 nohup python3 train.py train_log.txt 21 tail -f train_log.txt注意样本数量过少会触发ZeroDivisionError此时需要扩充数据集临时调试可以eval_flagFalse并修改utils_fit.py跳过验证loss计算仅用于跑通流程不用于实际项目。训练完成最优权重logs/best_epoch_weights.pth步骤7导出ONNX再转OAK的OpenVINO IR模型⚠️必须用bubbliiiing自带export_onnx.py不能用ultralytics的exportpython export_onnx.py --weights logs/best_epoch_weights.pth --input_shape 640,640 ov-convert model.onnx --output_model workpiece得到workpiece.xml、workpiece.bin步骤8复制模型、标签到ROS2 oak_arm_detector包cp workpiece.xml ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/model/workpiece_model/ cp workpiece.bin ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/model/workpiece_model/ echo target_workpiece ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/labels_work.txt步骤9编译ROS2包启动空间检测节点SpatialDetectionNetwork深度计算真实物理尺寸过滤节点逻辑不用像素面积过滤依靠OAK双目深度计算工件真实mm物理长宽做过滤同时识别机械臂两者同时满足才输出匹配信号。cd ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86 colcon build --packages-select oak_arm_detector source install/setup.bash ros2 launch oak_arm_detector oak_detector.launch.py新开终端观察话题输出ros2 topic echo /oak/arm_work_match ros2 topic echo /oak/workpiece_xyz_mm ros2 topic echo /oak/workpiece_real_wh_mm附录常见故障点ImageSets相关坑❌手动修改ImageSets/Main/trainval.txt新增图片之后脚本读取旧id报xml找不到。 ✅正确annotation_mode0运行voc_annotation.py自动扫描Annotations刷新全部ImageSets内容。❌annotation_mode2运行voc_annotation.py不会刷新ImageSets只会读取旧的train.txt/val.txt新增图片不会加入训练集。❌标注图片图内无工件直接D下一张不CtrlS缺少xmlvoc_annotation.py直接FileNotFound。 ✅正确每张图片必须CtrlS保存生成同名xml空目标也是空xml。图片删除操作删除JPEGImages里面的jpg删除Annotations里面对应的xml执行python3 voc_annotation.pyannotation_mode0ImageSets自动剔除该id。极简记忆版新增一批数据只做这几步视频抽帧 → jpg复制进JPEGImageslabelImg全部标注每张CtrlS生成xmlvoc_annotation.py保持annotation_mode0运行python3 voc_annotation.py自动更新ImageSets/Main全部txt自动生成2007_train.txt、2007_val.txt执行训练。ONNX → OpenVINO IR(xml/bin)完整转换操作步骤环境状态已经成功安装openvino‑devmo命令可用已经导出model.onnx422K ⚠️新版本mo参数没有--output_model改用--output_dir和--model_name步骤1切换到onnx所在项目目录cd ~/yolo5/yolov5-pytorch确认model.onnx存在ls -lh model.onnx输出示例-rw‑rw‑r-- 1 a a 422K 10月 8 17:21 model.onnx步骤2执行mo模型转换命令mo --input_model model.onnx --output_dir ./ --model_name workpiece参数说明--input_model model.onnx输入的ONNX模型文件--output_dir ./输出到当前工作目录--model_name workpiece生成模型文件前缀输出workpiece.xml、workpiece.bin如果出现算子/opset兼容报错使用带opset参数版本mo --input_model model.onnx --output_dir ./ --model_name workpiece --opset 17日志提示MO command line tool is considered as the legacy conversion API属于版本警告直接忽略不影响使用。步骤3校验转换输出产物ls -lh workpiece.xml workpiece.bin正常会看到两个不为0字节的文件workpiece.xml网络拓扑描述文件workpiece.bin模型权重二进制文件步骤4复制xml/bin到ROS2 oak_arm_detector模型目录cp workpiece.xml ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/model/workpiece_model/ cp workpiece.bin ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/model/workpiece_model/步骤5生成类别标签文件labels_work.txtecho target_workpiece ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/labels_work.txt步骤6进入ROS工作空间编译包并source环境cd ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86 colcon build --packages-select oak_arm_detector source install/setup.bash步骤7启动OAK识别launch文件ros2 launch oak_arm_detector oak_detector.launch.py步骤8新开终端监听业务话题观察输出ros2 topic echo /oak/arm_work_match ros2 topic echo /oak/workpiece_xyz_mm ros2 topic echo /oak/workpiece_real_wh_mm部署前必须修改否则深度尺寸过滤会全部拦截工件打开oak_arm_detector/main_double_model.py填入你的工件真实物理毫米尺寸合理公差self.real_w_min xxx self.real_w_max xxx self.real_h_min xxx self.real_h_max xxx硬性对齐约束训练图像尺寸640×640 → 导出onnx 640×640 → OAK节点内部推理输入也必须是640×640。常见问题mo未找到命令执行export PATH$PATH:~/.local/bin把用户本地脚本目录加入PATH转换警告legacy conversion API忽略numpy版本冲突警告ml‑dtypes requires numpy2.0.0推理场景可以忽略当前numpy1.26.4适配YOLO训练。完整一键复制整组命令直接粘贴执行cd ~/yolo5/yolov5-pytorch mo --input_model model.onnx --output_dir ./ --model_name workpiece ls -lh workpiece.xml workpiece.bin cp workpiece.xml ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/model/workpiece_model/ cp workpiece.bin ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/model/workpiece_model/ echo target_workpiece ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/labels_work.txt cd ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86 colcon build --packages-select oak_arm_detector source install/setup.bash ros2 launch oak_arm_detector oak_detector.launch.py
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进