当前位置: 首页 > news >正文

【YOLO11-obb部署至RK3588】模型训练→转换RKNN→开发板部署

在这里插入图片描述
已在GitHub开源与本博客同步的YOLO11_RK3588_object_obb项目,
地址:YOLO11_RK3588_object_obb
详细使用教程,可参考README.md或参考本博客第七章 模型部署

注:本文是以瑞芯微RK3588 SoC进行示例,同时也可支持瑞芯微其他系列SoC:RK3562、RK3566、RK3568、RK3576、RK1126B、RK1808、RK399PRO等,部署流程也基本一致,如需帮助,可在Github README.md中联系。

文章目录

  • 一、项目回顾
  • 二、文件梳理
  • 三、YOLO11-obb数据集标注
    • 1. 在PC端安装roLabelImg
    • 2. roLabelImg生成文件转换txt
  • 四、YOLO11-obb模型训练
  • 五、PT转ONNX
  • 六、ONNX转RKNN
  • 七、模型部署

一、项目回顾

博主之前有写过YOLO11、YOLOv8目标检测&图像分割、YOLOv10、v5目标检测、MoblieNetv2、ResNet50图像分类的模型训练、转换、部署文章,感兴趣的小伙伴可以了解下:
【YOLO11部署至RK3588】模型训练→转换RKNN→开发板部署
【YOLOv10部署RK3588】模型训练→转换rknn→部署流程
【YOLOv8-obb部署至RK3588】模型训练→转换RKNN→开发板部署
【YOLOv8-pose部署至RK3588】模型训练→转换RKNN→开发板部署
【YOLOv8seg部署RK3588】模型训练→转换rknn→部署全流程
【YOLOv8部署至RK3588】模型训练→转换rknn→部署全流程
【YOLOv7部署至RK3588】模型训练→转换RKNN→开发板部署
【YOLOv6部署至RK3588】模型训练→转换RKNN→开发板部署
【YOLOv5部署至RK3588】模型训练→转换RKNN→开发板部署
【MobileNetv2图像分类部署至RK3588】模型训练→转换rknn→部署流程
【ResNet50图像分类部署至RK3588】模型训练→转换RKNN→开发板部署
YOLOv8n部署RK3588开发板全流程(pt→onnx→rknn模型转换、板端后处理检测)

最近做了一个YOLO11-obb的关键点检测项目,涉及数据集标注,模型训练、转ONNX、转RKNN量化以及RK3588开发板调试部署,查了下CSDN上暂未有关于YOLO11-obb在RK系列开发板的免费详细教程,遂开此文,相互学习。

二、文件梳理

YOLO11-obb的训练、转换、部署所需四个项目文件:
第一个:YOLO11-obb模型训练项目文件(链接在此),
第二个:瑞芯微仓库中YOLO11的pt转onnx项目文件(链接在此);
第三个:用于在虚拟机中进行onnx转rknn的虚拟环境配置项目文件(链接在此);
第四个:在开发板上做模型部署的项目文件(链接在此)。

注:
1.第四个项目文件中的内容很多,里面涉及到rknn模型转换以及模型部署的所有内容,所以该文件在模型转换中也要与第三个文件配合使用。
2.我上面的四个链接都是已经链接到项目的对应版本了,打开链接后直接git clone或者download zip即可。
这四个文件的版本如下:
第一个模型训练文件是v8.3.7之前的版本,最好严格按照我的要求来,如果你的版本过新,后续在转ONNX的时候会报错,所以最好选择v8.3.7,后续会解释原因。
第二个ONNX转换文件为默认main分支
第三个文件rknn-toolkit2为v2.3.2
第四个文件rknn_model_zoo也用v2.3.2(rknn-toolkit2尽量和rknn_model_zoo版本一致)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

三、YOLO11-obb数据集标注

大家比较熟悉的是常规的固定角度矩形框数据集标定,即YOLO11常规检测的格式,而obb是在此基础上的微调,在标签文件中加入更多参数让矩形框能够旋转一定的角度。YOLO11等数据集的标定工具一般是labelme或者是在线标定网站Make Sense,而obb格式的数据集的标定工具常规选用roLabelImg工具,具体使用方法如下:

1. 在PC端安装roLabelImg

先在PC端安装好anaconda和Anaconda prompt,然后创建若任一conda环境,以我之前使用的labelme环境为例,激活环境后,进行如下操作打开标定工具:

git clone https://github.com/cgvict/roLabelImg
cd roLabelImg
pip install pyqt5 lxml
pyrcc5 -o resources.py resources.qrc  # 编译资源文件
python roLabelImg.py  # 启动

标定工具如下所示:点击左侧的“Create RotatedRBox”,创建矩形框,如下图所示:
在这里插入图片描述

然后通过zxcv四个键调整旋转框角度:
在这里插入图片描述

2. roLabelImg生成文件转换txt

标定生成的是xml文件,结构如下所示:

<object><type>robndbox</type><name>car</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><robndbox><cx>1970.4288</cx><cy>1428.5181</cy><w>154.8035</w><h>331.4003</h><angle>0.29</angle></robndbox></object>

然而,YOLO11-obb的数据集要求的是txt文档为如下格式:
在这里插入图片描述
即“目标类别ID, x1, y1, x2, y2, x3, y3, x4, y4”
因此需要将roLabelImg标定生成的xml文件转换成符合要求的txt文件,可通过以下rotlabellmgxml2yolov8obbtxt.py脚本批量化自动转换,只需要修改xml_dir 和output_dir 参数即可:

rotlabellmgxml2yolov8obbtxt.py:

import os
import xml.etree.ElementTree as ET
import math
import numpy as npdef convert_rotated_rect(cx, cy, w, h, angle):"""将旋转矩形(cx,cy,w,h,angle)转换为四个角点坐标"""# 计算旋转矩阵cos_a = math.cos(angle)sin_a = math.sin(angle)# 计算未旋转前的四个角点(相对于中心)half_w = w / 2half_h = h / 2corners = np.array([[-half_w, -half_h],[ half_w, -half_h],[ half_w,  half_h],[-half_w,  half_h]])# 应用旋转rot_matrix = np.array([[cos_a, -sin_a], [sin_a, cos_a]])rotated_corners = np.dot(corners, rot_matrix.T)# 加上中心坐标,得到绝对坐标abs_corners = rotated_corners + np.array([cx, cy])# 将四个角点展平为一维数组 [x1,y1,x2,y2,x3,y3,x4,y4]return abs_corners.flatten().tolist()# 设置路径
xml_dir = "/xxx/Others/xml"  # 替换为你的XML文件夹路径
output_dir = "/xxx/Others/txt"  # 替换为输出文件夹路径# 确保输出目录存在
os.makedirs(output_dir, exist_ok=True)# 遍历所有XML文件
for xml_file in os.listdir(xml_dir):if not xml_file.endswith(".xml"):continuexml_path = os.path.join(xml_dir, xml_file)try:tree = ET.parse(xml_path)root = tree.getroot()# 获取图像尺寸size = root.find("size")img_w = float(size.find("width").text)img_h = float(size.find("height").text)# 准备输出TXT文件txt_filename = os.path.splitext(xml_file)[0] + ".txt"txt_path = os.path.join(output_dir, txt_filename)with open(txt_path, "w") as f:# 遍历所有objectfor obj in root.findall("object"):robndbox = obj.find("robndbox")cx = float(robndbox.find("cx").text)cy = float(robndbox.find("cy").text)w = float(robndbox.find("w").text)h = float(robndbox.find("h").text)angle = float(robndbox.find("angle").text)# 转换旋转矩形为四个角点corners = convert_rotated_rect(cx, cy, w, h, angle)# 归一化坐标 (除以图像宽高)并确保在0-1范围内normalized_corners = []for i in range(0, len(corners), 2):x = max(0.0, min(1.0, corners[i] / img_w))  # 限制在0-1之间y = max(0.0, min(1.0, corners[i+1] / img_h))  # 限制在0-1之间normalized_corners.extend([x, y])# 格式化为字符串: class_index x1 y1 x2 y2 x3 y3 x4 y4# 类别索引为0 (只有pipeline一类)# 先写整数类别索引,然后写浮点数坐标line_str = "0 " + " ".join([f"{x:.6f}" for x in normalized_corners])f.write(line_str + "\n")print(f"已处理: {xml_file} -> {txt_filename}")except Exception as e:print(f"处理 {xml_file} 时出错: {str(e)}")print(f"转换完成! 共处理 {len(os.listdir(xml_dir))} 个XML文件。")

在转换完成后,即可开始PyTorch的YOLO11-obb模型训练。
注:博主的模型只有car一个检测类别

四、YOLO11-obb模型训练

YOLO11-obb的模型训练和此前的YOLOv8obb、YOLOv10等基本一致。
先从训练环境搭建开始,YOLO11-obb的环境搭建非常简单,不需要再pip install -r requirements.txt和pip install -e .了。

步骤如下:

conda create -n YOLO11 python=3.8
conda activate YOLO11
pip install ultralytics

配置好环境后,把另外一些必要的四个文件准备好:
在这里插入图片描述
自己创建一个train-obb.py脚本,放在和ultralytics文件夹同级位置,然后把ultralytics文件夹中的yolov11-obb.yaml文件复制出来,再把yolo11n.pt放进来,因为训练开始前会用预训练权重进行Automatic Mixed Precision(AMP自动混合精度)check,如果你没放预训练权重,终端会自己下载,但是速度较慢,所以先提前放置过来。各配置文件内容如下所示:

carobb.yaml:

train: /xxx/Dataset/previous_dataset/car_100_obb/images/train
val: /xxx/Dataset/previous_dataset/car_100_obb/images/val
# number of classes
nc: 1
# class names
names: ['car']

train-obb.py:

from ultralytics import YOLO# 加载模型
model = YOLO("yolo11-obb.yaml")  # 从头开始构建新模型
#model = YOLO("yolov11n.pt")  # 加载预训练模型(推荐用于训练)# Use the model
results = model.train(data="carobb.yaml", epochs=300, batch=32)  # 训练模型

yolo11-obb.yaml:

# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLO11 Oriented Bounding Boxes (OBB) model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/obb# Parameters
nc: 1 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolo11n-obb.yaml' will call yolo11-obb.yaml with scale 'n'# [depth, width, max_channels]n: [0.50, 0.25, 1024] # summary: 344 layers, 2695747 parameters, 2695731 gradients, 6.9 GFLOPss: [0.50, 0.50, 1024] # summary: 344 layers, 9744931 parameters, 9744915 gradients, 22.7 GFLOPsm: [0.50, 1.00, 512] # summary: 434 layers, 20963523 parameters, 20963507 gradients, 72.2 GFLOPsl: [1.00, 1.00, 512] # summary: 656 layers, 26220995 parameters, 26220979 gradients, 91.3 GFLOPsx: [1.00, 1.50, 512] # summary: 656 layers, 58875331 parameters, 58875315 gradients, 204.3 GFLOPs# YOLO11n backbone
backbone:# [from, repeats, module, args]- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4- [-1, 2, C3k2, [256, False, 0.25]]- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8- [-1, 2, C3k2, [512, False, 0.25]]- [-1, 1, Conv, [512, 3, 2]] # 5-P4/16- [-1, 2, C3k2, [512, True]]- [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32- [-1, 2, C3k2, [1024, True]]- [-1, 1, SPPF, [1024, 5]] # 9- [-1, 2, C2PSA, [1024]] # 10# YOLO11n head
head:- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 6], 1, Concat, [1]] # cat backbone P4- [-1, 2, C3k2, [512, False]] # 13- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 4], 1, Concat, [1]] # cat backbone P3- [-1, 2, C3k2, [256, False]] # 16 (P3/8-small)- [-1, 1, Conv, [256, 3, 2]]- [[-1, 13], 1, Concat, [1]] # cat head P4- [-1, 2, C3k2, [512, False]] # 19 (P4/16-medium)- [-1, 1, Conv, [512, 3, 2]]- [[-1, 10], 1, Concat, [1]] # cat head P5- [-1, 2, C3k2, [1024, True]] # 22 (P5/32-large)- [[16, 19, 22], 1, OBB, [nc, 1]] # Detect(P3, P4, P5)

以上就是几个核心文件的内容,准备好文件后,激活YOLO11环境,在 YOLO11/ultralytics-8.3.7 的路径下开始训练:

python train-obb.py 

这里说一下为什么有人是用脚本训练,有人是用yolo task=detect mode=train…训练,二者区别如下:

两种训练命令的区别机制

  1. ​​python train.py(问题方式)​​
    ​​执行路径​​:显式调用当前目录的脚本
    ​​模块加载​​:触发Python的本地模块导入机制,优先加载同目录下的ultralytics
    ​​典型表现​​:修改conv.py等文件立即生效,验证了本地代码被调用
  2. ​​yolo task=detect mode=train …(正确方式)​​
    ​​执行路径​​:通过环境中的​​入口点脚本​​调用
    安装ultralytics包时自动生成yolo命令行工具
    存储路径示例:YOLO11/bin/yolo
    ​​模块加载​​:直接调用环境安装的包,完全隔离本地目录干扰
    ​​验证方法​​:执行 which yolo 将返回环境路径(如/root/anaconda3/envs/YOLO11/bin/yolo
    整理如下:
    在这里插入图片描述
    因为博主需要频繁修改ultralytics的源码,因此选择使用脚本训练,如果读者喜欢标准训练/部署,可用yolo命令行训练,但还是建议脚本训练更加有可操作性。

在训练完成后,终端如下所示:
在这里插入图片描述

五、PT转ONNX

我将训练得到的best模型重命名为deploy_yolo11n_obb_best.pt,然后将其复制到第二个文件中,并且将第二个文件项目重命名为ultralytics_yolo11(pt2onnx),如下所示:
在这里插入图片描述
调整 ./ultralytics/cfg/default.yaml 中 model 文件路径,默认为 yolov1n.pt,若自己训练模型,请调接至对应的路径。支持检测、分割、姿态、旋转框检测模型。我修改的结果如下:
在这里插入图片描述

修改完default.yaml后,在终端(linux系统终端)输入:

export PYTHONPATH=./
python ./ultralytics/engine/exporter.py

结果如下所示:
在这里插入图片描述
会在当前路径下生成相同名称的ONNX模型,用netron打开该模型,如下所示:

在这里插入图片描述
如果转出的onnx模型和上述模型的输出通道数量不一致,则模型有问题,不用再去转rknn了,一定会有问题。


这里要说一下,上文提到的训练时的ultralytics版本不能过新的原因,是因为ultralytics版本更新很频繁,如果使用较新版本训练模型,会有部分模块与瑞芯微ultralytics_yolo11项目冲突,因为瑞芯微ultralytics_yolo11项目fork的是8.3.9版本的:
在这里插入图片描述
所以建议大家训练的时候尽量保持版本一致或者是8.3.0-8.3.9之间的版本,如果使用较新版本训练,转换时会出现类似如下错误:
在这里插入图片描述

六、ONNX转RKNN

在进行这一步的时候,如果你是在云服务器上运行,请先确保你租的卡能支持RKNN的转换运行。博主是在自己的虚拟机中进行转换。
先安装转换环境
这里我们先conda create -n rknn232 python=3.8创建环境,创建完成后激活该环境,打开第三个文件:rknn_toolkit2-2.3.2,在图示路径下找到这两个文件:
在这里插入图片描述
在终端激活环境,在终端输入

pip install -r requirements_cp38-2.3.2.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

然后再输入

pip install rknn_toolkit2-2.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

然后,我们的转rknn环境就配置完成了。

现在开始转换RKNN模型:
先进入rknn_model_zoo-2.3.2\examples\yolov8_obb文件夹(注意是yolov8_obb\python),将刚才得到的ONNX模型复制进来:
在这里插入图片描述

打开python/convert.py,进行适配参数修改:
在这里插入图片描述

然后执行在python文件夹路径下激活环境后执行命令:

python convert.py ../model/deploy_yolo11n_obb_best.onnx rk3588

结果如下所示:
在这里插入图片描述

此时在model下已生成同名的RKNN模型:
在这里插入图片描述

然后把rknn模型复制到win下,用netron模型打开,看模型结构是否符合要求:
在这里插入图片描述

七、模型部署

如果前面流程都已实现,模型的结构也没问题的话,则可以进行最后一步:模型端侧部署。
我已经帮大家做好了所有的环境适配工作,科学上网后访问博主GitHub仓库:YOLO11_RK3588_object_obb

在这里插入图片描述
git clone后把项目复制到开发板上,按如下流程操作:
①:cd build,删除所有build文件夹下的内容
②:cd src 修改main.cc,修改main函数中的如下三个内容,将这三个参数改成自己的绝对路径:

在这里插入图片描述

在这里插入图片描述

解释一下,这个标签路径中的内容如下所示:

在这里插入图片描述

其实就是你在训练yolo11时在yaml配置文件中的类别名

④修改include/postprocess.h 中的宏 OBJ_CLASS_NUM:
在这里插入图片描述

⑤:把你之前训练好并已转成RKNN格式的模型放到YOLO11_RK3588_object_obb/model文件夹下,然后把你要检测的所有图片都放到YOLO11_RK3588_object_obb/inputimage下。
在运行程序后,生成的结果图片在YOLO11_RK3588_object_obb/outputimage下

⑥:进入build文件夹进行编译

cd build
cmake ..
make

在build下生成可执行文件文件:rknn_yolo11obb_demo
在build路径下输入

./rknn_yolo11obb_demo

运行结果如下所示:
在这里插入图片描述
注:我已经在GIthub的仓库中按照路径放置好了本博客所使用到的所有文件,包括rknn模型、输入图片、输出图片以及txt文档,只需修改cpp中的文件路径即可,或者可参考main.cc中的main函数,按照如下命令亦可:

./rknn_yolo11obb_demo 模型路径 输入图片文件夹路径 输出图片文件夹图片

原inputimage文件夹下的图片:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在修改完main.cc中main函数的路径参数后执行完./rknn_yolo11obb_demo后在outputimage下的输出结果图片:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

根据输出结果,可以看到检测效果还是可以的。

上述即博主此次更新的YOLO11obb部署RK3588,包含PT转ONNX转RKNN的全流程步骤,欢迎交流!

http://www.dtcms.com/a/517011.html

相关文章:

  • 怎么建立公司网站平台南通微信网站开发
  • nodejs可以做企业网站吗wordpress xcache
  • AI Agent结合机器学习与深度学习在全球气候变化驱动因素预测中的应用
  • 基于 GEE 使用 OTSU 算法赋能遥感水体自动化提取:从自动阈值计算到高效分割的水体自动分割方案
  • 网站开发的项目总结汕头网站建设方案开发
  • 网站做好了怎么做后台wordpress设置弹窗
  • jsp租房网站开发门户网站系统建设项目招标书
  • PL2303TA不支援WINDOWS 11及后续版本,请洽询购买厂商[已解决]
  • Flink 的 checkpoint 对 key state 是怎么样存储的?
  • 辛集市住房和城乡建设厅网站焦作网站建设设计公司
  • 电子商务网站建设有什么意义重庆网站建设途锦科技
  • 【回眸】英语自我介绍(头马俱乐部版)
  • Python技巧:负数的16进制补码
  • 昆山建设局网站首页网站培训公司
  • 南充做网站建网站 网站内容怎么做
  • 力扣热题100道之189轮转数组
  • AutoGen框架入门:5个核心概念搭建智能体协作系统
  • MySQL 慢查询诊断与 SQL 优化实战指南(适配 MySQL 8.4 LTS)
  • wordpress 上传svg南通seo网站推广费用
  • 蓝桥杯-16955 岁月流转
  • 每日一个网络知识点:应用层WWW与HTTP
  • 个人网站建设实验心得投资公司取名字大全
  • 欧美网站建设公司东莞专业的网站制作有哪些
  • xtuoj Candy
  • 襄阳大摩网站建设网站开发者所有权归属
  • 一条龙网站建设价格编程应用
  • StarsNote 1.1.0测试版
  • Java--网络原理
  • 2025-10-21 XiaoQuQu 的 2025 CSP-S 第二轮模拟 ROUND2 补题
  • react中的受控组件与非受控组件