电赛专题:用YOLO在K230上做高帧率目标检测到底应该怎么实现

Viewed 296

问题描述


这篇帖子记录一条可以直接照着完成的路线:

给 K230 烧录 CanMV 固件 → 用 test_capture.py 采集图片 → 用 X-AnyLabeling 标注 → 在电脑上用 CPU 训练 YOLOv5n → 导出 ONNX → 转换成 KModel → 上传 K230 → 运行 test_yolov5_sensor.py

本项目只有 100 多张图片,电脑使用 CPU 训练即可。模型固定选择 YOLOv5n,训练和部署输入分辨率固定为 224×224

把 AI 检测部分跑通后,就可以继续完成电赛作品中的控制、通信和其他功能了。


第一步:安装 Python 和 CPU 版 PyTorch

1. 安装 Python

从 Python 官网安装 Python 3.10:

Python 官方下载

安装时勾选:

Add Python to PATH

安装完成后打开 PowerShell:

python --version
python -m pip --version

能够正常显示版本号即可。

本文直接在当前 Python 环境中安装,不要求使用 Conda。如果电脑里还有其他 Python 项目,推荐使用 Conda 创建独立环境,但这不是本流程的必需步骤。

2. 安装 CPU 版 PyTorch

使用南京大学镜像源安装:

python -m pip install torch torchvision -i https://mirror.nju.edu.cn/pypi/web/simple

本项目只使用 CPU,不需要安装 CUDA。


第二步:下载 K230 固件和配套脚本

1. 下载 CanMV 固件

打开下面的固件下载页面:

K230 MicroPython Daily Build 固件下载

在页面中选择与自己手中开发板完全一致的型号,下载文件名以 CanMV-K230_micropython 开头的固件。

固件通常是 .gz 压缩包。下载完成后先解压,得到可以烧录的 .img 文件。

开发板型号一定要选对,不要把其他板型的镜像混刷到当前开发板。

2. 下载电赛配套脚本

打开下面的目录:

K230 电赛目标检测相关脚本

下载这三个文件:

test_capture.py
test_yolov5_sensor.py
xanylabeling_json_to_yolo.py

它们分别用于:

  • test_capture.py:调用 K230 摄像头采集训练图片。
  • test_yolov5_sensor.py:在 K230 上运行训练好的 YOLOv5 检测模型。

目录中的 gangqiu_det.kmodel 是示例模型,可以用来了解文件放置方式,但训练自己的目标时不使用它。


第三步:给 K230 烧录 CanMV 固件

按照官方教程下载并打开 K230BurningTool

CanMV K230 固件烧录教程

烧录步骤如下:

  1. 解压下载的 CanMV 固件,得到 .img 文件。
  2. 打开 K230BurningTool
  3. 在软件中选择刚刚解压出来的 .img 固件。
  4. 选择开发板实际使用的烧录介质。使用 TF 卡启动时通常选择 SDCARD
  5. 让开发板进入烧录模式。
  6. 点击“开始烧录”,等待进度完成。
  7. 烧录结束后重新启动开发板。

开发板正常启动后,电脑通常会识别出:

  • 一个名为 CanMV 的虚拟 U 盘;
  • 一个 MicroPython REPL 串口。

看到这两个设备,说明固件已经正常运行。


第四步:使用 VS Code 和 CanMV 扩展采集图片

1. 安装 CanMV 扩展

安装 Visual Studio Code,然后在扩展商店搜索并安装 CanMV 扩展。

使用方法参考:

CanMV Visual Studio Code 扩展教程

用 USB 连接 K230,在 VS Code 中通过 CanMV 扩展连接开发板。

2. 运行采集脚本

在 VS Code 中打开前面下载的:

test_capture.py

连接开发板后运行脚本。脚本会打开摄像头预览和采集界面,按界面提示完成下面的操作:

  1. 设置需要采集的图片分辨率。
  2. 启动摄像头预览。
  3. 调整目标的位置、距离和角度。
  4. 点击采集并确认保存。
  5. 不需要的图片直接丢弃。

test_capture.png

脚本默认把图片保存到:

/data/images

图片名称类似:

capture_000001_800x480.jpg
capture_000002_800x480.jpg
capture_000003_800x480.jpg

采集完成后,从 CanMV 虚拟 U 盘的 data/images 目录把图片复制到电脑。

3. 采集 100 多张有效图片

模型最终在 K230 摄像头画面上运行,所以训练数据也直接用 K230 采集。这样训练图片和实际运行画面的视角、颜色、噪声及镜头畸变更加一致。

采集时需要覆盖:

  • 目标出现在画面中央、边缘和角落;
  • 近距离、中距离和较远距离;
  • 正面、侧面和不同旋转角度;
  • 正常光照、偏暗、阴影和反光;
  • 简单背景和比赛现场的复杂背景;
  • 少量完全没有目标的背景图片。

不要连续保存大量几乎一样的画面。只有 100 多张数据时,每张图片都应该尽量提供不同的信息。

由于模型输入最终会缩放到 224×224,采集时不要让目标在画面中小到几乎看不清。


第五步:使用 X-AnyLabeling 标注

本项目统一使用 X-AnyLabeling,不再选择其他标注软件。

从官方仓库下载并安装:

X-AnyLabeling 下载链接

打开软件后按下面的步骤操作:

  1. 打开从 K230 复制到电脑的图片目录。
  2. 创建本项目需要检测的类别。
  3. 使用矩形框把每个目标完整框住。
  4. 给矩形框选择正确的类别。
  5. 检查图片中是否存在漏标目标。
  6. 保存全部标注。

label_img.jpg

label_after.jpg

X-AnyLabeling 默认保存的是与图片同名的 .json 文件。JSON 是 X-AnyLabeling 的工程标注格式,方便后续重新打开和修改,但 YOLOv5 不能直接使用这些 JSON 训练,必须转换为 YOLO TXT。

部分 X-AnyLabeling 版本的界面中没有 YOLO 导出选项。为了避免受软件版本影响,本项目统一使用配套的 Python 脚本进行转换。

使用脚本将 JSON 转换为 YOLO TXT

从前面打开的 K230 电赛目标检测脚本目录 下载:

xanylabeling_json_to_yolo.py

也可以直接点击:

下载 xanylabeling_json_to_yolo.py

将脚本保存到电脑上的项目目录。

假设 K230 图片和 X-AnyLabeling 生成的 JSON 都位于:

D:/K230_Project/annotations

其中的文件类似:

capture_000001_800x480.jpg
capture_000001_800x480.json
capture_000002_800x480.jpg
capture_000002_800x480.json

打开 PowerShell,运行下面的命令:

python xanylabeling_json_to_yolo.py --input-dir D:/K230_Project/annotations --output-dir D:/K230_Project/labels --classes red

--classes 后面的类别顺序就是类别编号。上面的单类别命令表示:

0: red

如果项目有两个类别,命令写成:

python xanylabeling_json_to_yolo.py --input-dir D:/K230_Project/annotations --output-dir D:/K230_Project/labels --classes class_a class_b

对应关系为:

0: class_a
1: class_b

这个顺序必须与后面 data.yaml 中的 names 顺序完全一致。

转换完成后,D:/K230_Project/labels 中会生成:

capture_000001_800x480.txt
capture_000002_800x480.txt

脚本只接受矩形框标注。如果误用了多边形等其他标注类型,脚本会直接报错并指出对应 JSON 文件,需要回到 X-AnyLabeling 改成矩形框。

生成的 .txt 才是后续 YOLOv5 训练需要的标签。原来的 .json 可以保留,方便以后继续修改标注,但不要放进 YOLOv5 的 labels/trainlabels/val 目录。

YOLO TXT 中每一行的格式为:

class_id x_center y_center width height

例如:

0 0.512500 0.436111 0.225000 0.338889

其中:

  • class_id0 开始;
  • 后四个数是目标框中心坐标和宽高;
  • 坐标已经归一化到 0~1
  • 每张图片对应一个同名 .txt 标签文件。

例如:

capture_000001_800x480.jpg
capture_000001_800x480.txt

标注时,矩形框尽量贴近目标边缘。图片中出现的目标都要标出来,漏标会直接影响训练效果。

转换后随机打开几个 .txt 文件检查:包含目标的文件中,每一行应有 5 个数字,并且第一个数字是类别编号。完成这一步后,再把图片和 TXT 按下一节的目录结构划分为训练集和验证集。


第六步:整理成 YOLOv5 数据集

将全部数据按约 8:2 分成训练集和验证集。100 多张图片可以把约 80% 放入训练集,剩余约 20% 放入验证集。

整理后的目录如下:

my_dataset/
├── images/
│   ├── train/
│   │   ├── capture_1.jpg
│   │   └── ...
│   └── val/
│       ├── capture_101.jpg
│       └── ...
└── labels/
    ├── train/
    │   ├── capture_1.txt
    │   └── ...
    └── val/
        ├── capture_101.txt
        └── ...

图片和标签必须同名,并分别放入对应的 imageslabels 目录。

my_dataset 目录中新建 data.yaml。下面以检测“钢球”为例:

path: D:/K230_Project/my_dataset
train: images/train
val: images/val

nc: 1
names:
  0: red

path 改成自己电脑上 my_dataset 的实际绝对路径。Windows 路径使用 /,不要使用 \

如果项目有多个类别,就按顺序继续添加:

nc: 2
names:
  0: class_a
  1: class_b

后面部署时,test_yolov5_sensor.py 中的标签顺序必须和这里完全一致。


第七步:下载 YOLOv5 并安装依赖

打开 PowerShell,执行:

git clone https://github.com/ultralytics/yolov5.git
cd yolov5
python -m pip install -r requirements.txt -i https://mirror.nju.edu.cn/pypi/web/simple

如果没有安装 Git,可以从 YOLOv5 官方仓库 下载 ZIP,解压后在 PowerShell 中进入该目录。


第八步:使用 CPU 训练 YOLOv5n

本项目确定使用:

模型:YOLOv5n
设备:CPU
输入分辨率:224×224
训练轮数:100

将数据集的 data.yaml 路径替换到下面的命令中,然后在 YOLOv5 根目录执行:

python train.py --weights yolov5n.pt --cfg models/yolov5n.yaml --data D:/K230_Project/my_dataset/data.yaml --epochs 100 --batch-size 8 --imgsz 224 --workers 0 --device cpu --name k230_yolov5n

100 多张图片、YOLOv5n224×224 输入都比较轻量,普通电脑使用 CPU 即可完成训练。

训练结束后,最好的模型位于:

runs/train/k230_yolov5n/weights/best.pt

后续只使用这个 best.pt


第九步:导出 ONNX

在 YOLOv5 根目录执行:

python export.py --weights runs/train/k230_yolov5n/weights/best.pt --imgsz 224 --batch-size 1 --include onnx --device cpu

导出完成后得到:

runs/train/k230_yolov5n/weights/best.onnx

训练、ONNX 导出和 K230 部署全部保持 224×224 输入。


第十步:把 ONNX 转换成 KModel

K230 的 KPU 不能直接运行 ONNX,需要先把模型转换为 .kmodel。本项目不安装命令行转换环境,直接使用 Windows 可视化转换软件。

1. 下载可视化转换软件

下载下面的免安装压缩包:

YOLO-KModel-Converter-Portable-Slim-Win.zip

下载完成后完整解压,不要直接在压缩包中运行程序。进入解压目录,双击其中的 YOLO KModel Converter 可执行程序。

2. 准备量化校准图片

在电脑上新建一个 calibration_data 文件夹,从训练集中复制约 20 张有代表性的原始图片进去。

calibration_data/
├── capture_000001_800x480.jpg.jpg
├── capture_000006_800x480.jpg.jpg
├── capture_000009_800x480.jpg.jpg
└── ...

图片要覆盖不同距离、角度、光照和背景。这里放原始图片即可,不需要标签文件。

3. 在软件中设置转换参数

打开转换软件后,按下面的固定参数设置:

  • 模型任务:YOLOv5 Detect
  • 输入模型:选择 runs/train/k230_yolov5n/weights/best.onnx
  • 校准数据集:选择刚刚创建的 calibration_data 文件夹
  • 输入宽度:224
  • 输入高度:224
  • 量化选项:0
  • 输出文件:设置为 best.kmodel

确认所有参数后,点击界面中的转换按钮,等待转换完成。

转换成功后得到:

best.kmodel

这个文件就是稍后上传到 K230 的模型。转换时输入宽度和高度必须都是 224,与训练及 ONNX 导出保持一致。


第十一步:上传模型并运行 K230 检测脚本

1. 上传模型

将下面两个文件复制到 CanMV 虚拟 U 盘的 data 目录:

best.kmodel
test_yolov5_sensor.py

最终路径为:

/data/best.kmodel

2. 修改脚本参数

在 VS Code 中打开 test_yolov5_sensor.py,修改开头的模型参数:

kmodel_path = "/data/best.kmodel"
labels = ["red"]
model_input_size = [224, 224]
rgb888p_size = [224, 224]

confidence_threshold = 0.5
nms_threshold = 0.45

需要确认:

  • kmodel_path 与上传的模型路径一致;
  • labelsdata.yaml 中的类别名称和顺序完全一致;
  • model_input_size 固定为 [224, 224]
  • rgb888p_size 设置为 [224, 224]
  • 如果开发板摄像头编号不同,再修改脚本中的 Sensor(id=2)

3. 运行模型

在 VS Code 中通过 CanMV 扩展连接 K230,然后运行:

test_yolov5_sensor.py

脚本会:

  1. 打开 K230 摄像头;
  2. 读取 /data/best.kmodel
  3. 对实时画面执行 YOLOv5 目标检测;
  4. 在屏幕上绘制检测框和类别;
  5. 在终端打印实时 FPS。

使用 YOLOv5n224×224 模型输入和 224×224 RGB 推理通道时,K230 在合适配置下帧率可以达到 50 FPS 以上。实际速度还会受到摄像头、显示方式、固件版本和绘图开销影响。


最后总结

整套流程就是:

  1. 下载并烧录 CanMV K230 固件;
  2. 用 VS Code 的 CanMV 扩展运行 test_capture.py
  3. 使用 K230 摄像头采集 100 多张图片;
  4. 使用 X-AnyLabeling 画矩形框并导出 YOLO 标签;
  5. 整理 imageslabelsdata.yaml
  6. 安装 Python、CPU 版 PyTorch 和 YOLOv5 依赖;
  7. 使用 CPU 训练 YOLOv5n,输入分辨率为 224×224
  8. best.pt 导出为 best.onnx
  9. 使用 YOLO KModel Converter 可视化工具将 ONNX 转成 best.kmodel
  10. 把模型上传到 K230,修改并运行 test_yolov5_sensor.py

到这里,电赛项目中的 AI 目标检测部分就完成了。接下来可以把检测结果接入串口、运动控制、机械结构或其他业务逻辑,继续完成整套作品。


参考资料

复现步骤


硬件板卡


K230

软件版本


https://download.kendryte.com/developer/releases/canmv_k230_micropython/daily_build/

其他信息


1 Answers