YOLO11 旋转目标检测 | 数据标注 | 自定义数据集 | 模型训练 | 模型推理
在本文中,我们将详细介绍如何使用YOLO11模型实现旋转目标检测。
本文内容包括数据标注、自定义数据集的准备、模型训练和推理等关键步骤,帮助大家快速搭建一个完整的旋转目标检测流程。
此外,还将展示如何将模型导出为ONNX格式,以便在多种平台上部署。
目录
1、旋转目标—数据标注工具X-AnyLabeling
2、json转为YOLO11的旋转框txt标签
3、配置YOLO11代码工程
4、数据集yaml配置文件
5、YOLO11模型结构配置文件
6、编写训练代码
7、开始训练
8、模型推理
9、生成ONNX模型
1、旋转目标—数据标注工具X-AnyLabeling
旋转目标框标注中,过去通常使用roLabelImg,但作者太久没维护了,功能单一陈旧;
本文使用X-AnyLabeling标注工具,进行旋转目标框标注
开源地址:https://github.com/CVHub520/X-AnyLabeling
安装方式参考:https://github.com/CVHub520/X-AnyLabeling/blob/main/docs/en/get_started.md
安装好后,使用下面命令打开标注工具
python anylabeling/app.py
然后点击左上角的“Open Dir”打开需要标注的图片路径
右键选择“Create Rotation”进行旋转框标注
快捷键 | 描述 |
---|---|
z | 逆时针旋转大角度 |
x | 逆时针旋转一个小角度 |
c | 顺时针旋转一个小角度 |
v | 顺时针旋转大角度 |
要显示旋转角度,我们可以单击顶部菜单栏中的 'View',然后选中 'Show Degrees' 以实时显示估计的旋转角度。
同时支持设置为中文的,很方便~
标注完成后,会自动保存,生成与图片同名的json标注文件;
2、json转为YOLO11的旋转框txt标签
YOLO11中旋转框格式,通过其四个角点指定边界框,坐标在 0 和 1 之间标准化。
它的数据格式,如下所示:
class_index x1 y1 x2 y2 x3 y3 x4 y4
看一下标签文件示例,如下所示:
0 0.780811 0.743961 0.782371 0.74686 0.777691 0.752174 0.776131 0.749758
需要注意四个角点的顺序,右上 -> 右下 -> 左下 -> 左上
下面编写代码,将文件夹中的所有JSON标注文件,转换为YOLO11的旋转框格式的TXT标注文件。
核心函数是:order_points
-
计算中心点:首先计算四个点的中心点
(center_x, center_y)
,通过所有点的坐标平均值来获得。 -
计算角度并排序:定义了一个内部函数
angle_from_center
来计算每个点相对于中心点的角度。使用math.atan2
计算角度,以便按逆时针顺序排序。 -
按顺序排列顶点:按逆时针顺序排列后,将点排序为
右上 -> 右下 -> 左下 -> 左上
的顺序,这样就可以确保点的顺序与YOLO11的OBB任务要求一致。
def order_points(points):
# 1. 计算中心点
center_x = sum([p[0] for p in points]) / 4
center_y = sum([p[1] for p in points]) / 4
# 2. 计算每个点相对于中心点的角度,并排序
def angle_from_center(point):
return math.atan2(point[1] - center_y, point[0] - center_x)
# 按角度逆时针排序
points = sorted(points, key=angle_from_center, reverse=True)
# 3. 按"右上、右下、左下、左上"的顺序排列
ordered_points = [points[0], points[1], points[2], points[3]]
return ordered_points
下面是完整代码
import math, os, json
# 定义类别映射字典,键为类别名称,值为类别索引
category_mapping = {"class1": 0, "class2": 1, "class3": 2}
def order_points(points):
# 计算四个顶点的中心点坐标
center_x = sum([p[0] for p in points]) / 4
center_y = sum([p[1] for p in points]) / 4
# 计算每个点相对于中心点的角度,按逆时针方向排序,确保点的顺序一致
points = sorted(points, key=lambda p: math.atan2(p[1] - center_y, p[0] - center_x), reverse=True)
# 返回按顺序排列的四个点,顺序为“右上、右下、左下、左上”
return [points[0], points[1], points[2], points[3]]
def convert_json_to_yolo11(json_folder, output_folder, category_mapping):
os.makedirs(output_folder, exist_ok=True) # 确保输出文件夹存在,如果不存在则创建
for filename in os.listdir(json_folder): # 遍历JSON文件夹中的每个文件
if filename.endswith('.json'): # 只处理.json结尾的文件
json_path = os.path.join(json_folder, filename)
try:
with open(json_path, 'r') as f:
data = json.load(f) # 读取JSON文件内容
except (FileNotFoundError, json.JSONDecodeError) as e:
print(f"文件读取错误或格式无效:{filename},错误信息:{e}") # 如果读取出错,输出错误信息并跳过
continue
# 获取图像的宽度和高度
image_width = data.get("imageWidth")
image_height = data.get("imageHeight")
if not image_width or not image_height: # 如果图像尺寸信息缺失,输出警告并跳过该文件
print(f"图像尺寸信息缺失:{filename}")
continue
yolo_lines = [] # 初始化YOLO格式的标注行
for shape in data.get("shapes", []): # 遍历JSON中的每个标注对象
label = shape.get("label") # 获取标注的类别名称
if label in category_mapping: # 检查类别名称是否在类别映射字典中
class_index = category_mapping[label] # 获取对应的类别索引
else:
print(f"未识别的类别标签:{label},跳过该标注") # 如果类别标签未定义,输出警告并跳过该标注
continue
points = shape.get("points") # 获取标注的四个顶点坐标
if len(points) == 4: # 确保标注包含四个顶点,符合OBB要求
ordered_points = order_points(points) # 使用order_points函数对顶点进行顺序排列
# 将顶点坐标归一化到0-1之间,并保留六位有效数字
normalized_points = [[round(x / image_width, 6), round(y / image_height, 6)] for x, y in ordered_points]
# 构造YOLO格式的标注行,包含类别索引和四个归一化顶点坐标
yolo_line = [class_index] + [coord for point in normalized_points for coord in point]
yolo_lines.append(" ".join(map(str, yolo_line))) # 将标注行添加到YOLO行列表中
if yolo_lines: # 如果存在标注数据,则写入到对应的TXT文件中
txt_filename = os.path.splitext(filename)[0] + ".txt" # 生成输出TXT文件名
output_path = os.path.join(output_folder, txt_filename)
with open(output_path, 'w') as out_file:
out_file.write("\n".join(yolo_lines)) # 将所有标注行写入TXT文件
print(f"转换完成: {output_path}") # 输出转换完成信息
# 使用示例
json_folder = "json_path" # JSON文件夹路径,需要修改
output_folder = "txt_path" # 输出TXT文件夹路径,需要修改
convert_json_to_yolo11(json_folder, output_folder, category_mapping)
运行代码前,需要设置类别映射字典,比如定义三个类别,和对应的顺序
category_mapping = {"car": 0, "pedestrians": 1, "bicycle": 2}
同时,设置输入和输出文件夹路径
json_folder
:修改json_folder
变量为包含JSON文件的文件夹路径。output_folder
:修改output_folder
变量为您希望输出TXT文件的文件夹路径。
3、配置YOLO11代码工程
首先到YOLO11代码地址,下载源代码:https://github.com/ultralytics/ultralytics
- 在 GitHub 仓库页面上,用户点击绿色的 "Code" 按钮后,会弹出一个选项框。
- 选择通过 HTTPS 或 GitHub CLI 克隆仓库,也可以点击框中的 "Download ZIP" 按钮,将整个仓库下载为 ZIP 压缩包到本地。
解压ultralytics-main.zip文件,在ultralytics同级目录中,
- 新建文件:训练代码(train.py)、推理代码(infer.py)
- 以及测试数据的文件夹:datasets,权重文件目录:weights
ultralytics-main/
.github/
datasets/
docker/
docs/
examples/
runs/
tests/
ultralytics/
weights/
.gitignore
CITATION.cff
CONTRIBUTING.md
LICENSE
mkdocs.yml
print_dir.py
pyproject.toml
README.md
README.zh-CN.md
train.py
infer.py
weights目录可以存放不同任务的权重,比如:yolo11m-cls.pt、yolo11m-obb.pt、yolo11m-pose.pt、yolo11m-seg.pt、yolo11m.pt、yolo11n.pt等。
train.py文件是和ultralytics文件夹同一级目录的
后面可以直接调用ultralytics源代码中的函数、类和依赖库等,如果有需要直接修改ultralytics中的代码,比较方便。
4、数据集yaml配置文件
在ultralytics/cfg/datasets/目录下,新建一个yaml文件,比如:autoparts_obb.yaml
# Ultralytics YOLO 🚀, AGPL-3.0 license
path: ./datasets/obb_car_20241108# dataset root dir
train: train/images # train images
val: val/images # val images
# Classes
names:
0: car
1: pedestrians
2: bicycle
同级目录下还存在许多数据集配置文件
比如:coco128.yaml、coco.yaml、DOTAv1.5.yaml、VOC.yaml、Objects365.yaml、Argoverse.yaml等等
yaml文件中的path,需要根据实际数据路径进行修改,指定数据集的路径
5、YOLO11模型结构配置文件
YOLO11旋转模型结构的配置文件,比如yolo11-obb.yaml,它所在位置是
ultralytics/cfg/models/11/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: 80 # 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 GFLOPs
s: [0.50, 0.50, 1024] # summary: 344 layers, 9744931 parameters, 9744915 gradients, 22.7 GFLOPs
m: [0.50, 1.00, 512] # summary: 434 layers, 20963523 parameters, 20963507 gradients, 72.2 GFLOPs
l: [1.00, 1.00, 512] # summary: 656 layers, 26220995 parameters, 26220979 gradients, 91.3 GFLOPs
x: [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)
如果需要修改模型结构,可以在这个文件进行修改。
6、编写训练代码
前面准备好了:数据集配置文件(autoparts_obb.yaml)、模型结构配置文件(yolo11-obb.yaml)
- 这里需要注意结构配置文件,虽然文件名是yolo11-obb.yaml,但是需要再后面指定模型尺寸(n, s, m, l, x)
- 比如需要m规模的模型,在加载模型时用YOLO("yolo11m-obb.yaml");如果不指定,默认是n的,感觉怪怪的
下面编写训练代码,可以参考一下:
from ultralytics import YOLO
# 加载预训练的模型
# model = YOLO("yolo11m-obb.yaml").load("weights/yolo11m-obb.pt")
model = YOLO("weights/yolo11s-obb.pt")
# 定义训练参数,添加默认值、范围和中文注释
train_params = {
'data': "autoparts_obb.yaml", # 数据集配置文件路径,需要自定义修改 xx.yaml, coco8.yaml, dota8.yaml
'epochs': 100, # 总训练轮次,默认值 100,范围 >= 1
'imgsz': 640, # 输入图像大小,常规默认值 640,在OBB任务中默认1024, 范围 >= 32
'batch': 8, # 批次大小,默认值 16,范围 >= 1
'save': True, # 是否保存训练结果和模型,默认值 True
'save_period': -1, # 模型保存频率,默认值 -1,表示只保存最终结果
'cache': False, # 是否缓存数据集,默认值 False
'device': "0", # 训练设备,默认值 None,支持 "cpu", "gpu"(device=0,1), "mps"
'workers': 8, # 数据加载线程数,默认值 8,影响数据预处理速度
'project': None, # 项目名称,保存训练结果的目录,默认值 None
'name': None, # 训练运行的名称,用于创建子目录保存结果,默认值 None
'exist_ok': False, # 是否覆盖已有项目/名称目录,默认值 False
'pretrained': True,
'optimizer': 'auto', # 优化器,默认值 'auto',支持 'SGD', 'Adam', 'AdamW'
'verbose': True, # 是否启用详细日志输出,默认值 False
'seed': 0, # 随机种子,确保结果的可重复性,默认值 0
'deterministic': True, # 是否强制使用确定性算法,默认值 True
'single_cls': False, # 是否将多类别数据集视为单一类别,默认值 False
'rect': False, # 是否启用矩形训练(优化批次图像大小),默认值 False
'cos_lr': False, # 是否使用余弦学习率调度器,默认值 False
'close_mosaic': 10, # 在最后 N 轮次中禁用 Mosaic 数据增强,默认值 10
'resume': False, # 是否从上次保存的检查点继续训练,默认值 False
'amp': True, # 是否启用自动混合精度(AMP)训练,默认值 True
'fraction': 1.0, # 使用数据集的比例,默认值 1.0
'profile': False, # 是否启用 ONNX 或 TensorRT 模型优化分析,默认值 False
'freeze': None, # 冻结模型的前 N 层,默认值 None
'lr0': 0.01, # 初始学习率,默认值 0.01,范围 >= 0
'lrf': 0.01, # 最终学习率与初始学习率的比值,默认值 0.01
'momentum': 0.937, # SGD 或 Adam 的动量因子,默认值 0.937,范围 [0, 1]
'weight_decay': 0.0005, # 权重衰减,防止过拟合,默认值 0.0005
'warmup_epochs': 3.0, # 预热学习率的轮次,默认值 3.0
'warmup_momentum': 0.8, # 预热阶段的初始动量,默认值 0.8
'warmup_bias_lr': 0.1, # 预热阶段的偏置学习率,默认值 0.1
'box': 7.5, # 边框损失的权重,默认值 7.5
'cls': 0.5, # 分类损失的权重,默认值 0.5
'dfl': 1.5, # 分布焦点损失的权重,默认值 1.5
'pose': 12.0, # 姿态损失的权重,默认值 12.0
'kobj': 1.0, # 关键点目标损失的权重,默认值 1.0
'label_smoothing': 0.0, # 标签平滑处理,默认值 0.0
'nbs': 64, # 归一化批次大小,默认值 64
'overlap_mask': True, # 是否在训练期间启用掩码重叠,默认值 True
'mask_ratio': 4, # 掩码下采样比例,默认值 4
'dropout': 0.0, # 随机失活率,用于防止过拟合,默认值 0.0
'val': True, # 是否在训练期间启用验证,默认值 True
'plots': True, # 是否生成训练曲线和验证指标图,默认值 True
# 数据增强相关参数
'hsv_h': 0.1, # 色相变化范围 (0.0 - 1.0),默认值 0.015
'hsv_s': 0.7, # 饱和度变化范围 (0.0 - 1.0),默认值 0.7
'hsv_v': 0.4, # 亮度变化范围 (0.0 - 1.0),默认值 0.4
'degrees': 0.0, # 旋转角度范围 (-180 - 180),默认值 0.0
'translate': 0.1, # 平移范围 (0.0 - 1.0),默认值 0.1
'scale': 0.5, # 缩放比例范围 (>= 0.0),默认值 0.5
'shear': 0.0, # 剪切角度范围 (-180 - 180),默认值 0.0
'perspective': 0.0, # 透视变化范围 (0.0 - 0.001),默认值 0.0
'flipud': 0.0, # 上下翻转概率 (0.0 - 1.0),默认值 0.0
'fliplr': 0.5, # 左右翻转概率 (0.0 - 1.0),默认值 0.5
'bgr': 0.0, # BGR 色彩顺序调整概率 (0.0 - 1.0),默认值 0.0
'mosaic': 0.5, # Mosaic 数据增强 (0.0 - 1.0),默认值 1.0
'mixup': 0.0, # Mixup 数据增强 (0.0 - 1.0),默认值 0.0
'copy_paste': 0.0, # Copy-Paste 数据增强 (0.0 - 1.0),默认值 0.0
'copy_paste_mode': 'flip', # Copy-Paste 增强模式 ('flip' 或 'mixup'),默认值 'flip'
'auto_augment': 'randaugment', # 自动增强策略 ('randaugment', 'autoaugment', 'augmix'),默认值 'randaugment'
'erasing': 0.4, # 随机擦除增强比例 (0.0 - 0.9),默认值 0.4
'crop_fraction': 1.0, # 裁剪比例 (0.1 - 1.0),默认值 1.0
}
# 进行训练
results = model.train(**train_params)
YOLO11模型训练,思路流程:
- 加载模型:使用 YOLO 类指定模型的配置文件,并加载预训练权重
yolo11m-obb.pt
。 - 定义训练参数:通过字典
train_params
定义了一系列训练参数,涵盖了训练过程中可能涉及的配置项,如数据集路径、训练轮数、图像大小、优化器、数据增强等。 - 执行训练:使用
model.train(**train_params)
将定义的训练参数传入模型,开始训练。 - 保存训练结果:训练完成后,结果保存在
results
中,包含损失和精度等信息。
在ultralytics工程中,没有了超参数文件了,需要从model.train( )函数参数设置,所以才会有上面的示例代码。
7、开始训练
直接运行train.py,就开始训练啦
Ultralytics 8.3.7 🚀 Python-3.12.4 torch-2.2.1+cu121 CUDA:0 (NVIDIA A30, 24062MiB)
Starting training for 100 epochs...
Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size
1/100 2.69G 2.705 6.069 1.437 9 640: 100%|██████████| 138/138 [00:14<00:00, 9.36it/s]
Class Images Instances Box(P R mAP50 mAP50-95): 100%|██████████| 138/138 [00:07<00:00, 17.30it/s]
all 1100 2100 0.81 0.486 0.584 0.266
.......
Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size
100/100 2.69G 0.8774 0.5173 1.043 11 640: 100%|██████████| 138/138 [00:13<00:00, 10.54it/s]
Class Images Instances Box(P R mAP50 mAP50-95): 100%|██████████| 138/138 [00:07<00:00, 17.50it/s]
all 1100 2100 0.932 0.924 0.96 0.637
100 epochs completed in 0.614 hours.
Optimizer stripped from runs/obb/train39/weights/last.pt, 19.8MB
Optimizer stripped from runs/obb/train39/weights/best.pt, 19.8MB
训练完成后,可以在runs/obb/train39路径,可以看到保存的权重、训练记录表格和标签信息等
8、模型推理
使用刚才训练好的模型权重,进行模型推理,看看旋转目标检测效果
示例代码,如下所示:
from ultralytics import YOLO
# 加载预训练的YOLOv11n模型
model = YOLO(r"runs/obb/train39/weights/best.pt") # weights/yolo11m-obb.pt
# 对指定的图像文件夹进行推理,并设置各种参数
results = model.predict(
source="/mnt/datasets/OBB_point_offer_Mix_num55/images", # 数据来源,可以是文件夹、图片路径、视频、URL,或设备ID(如摄像头)
conf=0.3, # 置信度阈值
iou=0.4, # IoU 阈值
imgsz=640, # 图像大小
half=False, # 使用半精度推理
device=None, # 使用设备,None 表示自动选择,比如'cpu','0'
max_det=1000, # 最大检测数量
vid_stride=1, # 视频帧跳跃设置
stream_buffer=False, # 视频流缓冲
visualize=False, # 可视化模型特征
augment=False, # 启用推理时增强
agnostic_nms=False, # 启用类无关的NMS
classes=None, # 指定要检测的类别
retina_masks=False, # 使用高分辨率分割掩码
embed=None, # 提取特征向量层
show=False, # 是否显示推理图像
save=True, # 保存推理结果
save_frames=False, # 保存视频的帧作为图像
save_txt=True, # 保存检测结果到文本文件
save_conf=False, # 保存置信度到文本文件
save_crop=False, # 保存裁剪的检测对象图像
show_labels=True, # 显示检测的标签
show_conf=True, # 显示检测置信度
show_boxes=True, # 显示检测框
line_width=1 # 设置边界框的线条宽度,比如2,4
)
9、生成ONNX模型
再YOLO11中,从xxx.pt权重文件转为.onnx文件,然后使用.onnx文件,进行旋转目标检测任务的模型推理。
用ONNX模型推理,便于算法到开发板或芯片的部署。
首先我们训练好的模型,生成xxx.pt权重文件;
然后用下面代码,导出ONNX模型(简洁版)
from ultralytics import YOLO
# 加载一个模型,路径为 YOLO 模型的 .pt 文件
model = YOLO("runs/obb/train39/weights/best.pt")
# 导出模型,格式为 ONNX
model.export(format="onnx")
运行代码后,会在上面路径中生成best.onnx文件的
- 比如,填写的路径是:"runs/obb/train39/weights/best.pt"
- 那么在runs/obb/train39/weights/目录中,会生成与best.pt同名的onnx文件,即best.onnx
上面代码示例是简单版,如果需要更专业设置ONNX,用下面版本的
YOLO11导出ONNX模型(专业版)
from ultralytics import YOLO
# 加载一个模型,路径为 YOLO 模型的 .pt 文件
model = YOLO(r"runs/obb/train39/weights/best.pt")
# 导出模型,设置多种参数
model.export(
format="onnx", # 导出格式为 ONNX
imgsz=(640, 640), # 设置图像大小,常规默认值 640,在OBB任务中默认1024
keras=False, # 不导出为 Keras 格式
optimize=False, # 不进行优化 False, 移动设备优化的参数,用于在导出为TorchScript 格式时进行模型优化
half=False, # 不启用 FP16 量化
int8=False, # 不启用 INT8 量化
dynamic=False, # 不启用动态输入尺寸
simplify=True, # 简化 ONNX 模型
opset=None, # 使用最新的 opset 版本
workspace=4.0, # 为 TensorRT 优化设置最大工作区大小(GiB)
nms=False, # 不添加 NMS(非极大值抑制)
batch=1, # 指定批处理大小
device="cpu" # 指定导出设备为CPU或GPU,对应参数为"cpu" , "0"
)
对于model.export( )函数中,各种参数说明:
format="onnx"
:指定导出模型的格式为 onnx。imgsz=(640, 640)
:输入图像的尺寸设为 640x640。如果需要其他尺寸可以修改这个值,比如1024x1024。keras=False
:不导出为 Keras 格式的模型。optimize=False
:不应用 TorchScript 移动设备优化。half=False
:不启用 FP16(半精度)量化。int8=False
:不启用 INT8 量化。dynamic=False
:不启用动态输入尺寸。simplify=True
:简化模型以提升 ONNX 模型的性能。opset=None
:使用默认的 ONNX opset 版本,如果需要可以手动指定。workspace=4.0
:为 TensorRT 优化指定最大工作空间大小为 4 GiB。nms=False
:不为 CoreML 导出添加非极大值抑制(NMS)。batch=1
:设置批处理大小为 1。- device="cpu", 指定导出设备为CPU或GPU,对应参数为"cpu" , "0"
YOLO11相关文章推荐:
一篇文章快速认识YOLO11 | 关键改进点 | 安装使用 | 模型训练和推理-CSDN博客
一篇文章快速认识 YOLO11 | 实例分割 | 模型训练 | 自定义数据集-CSDN博客
一篇文章快速认识YOLO11 | 旋转目标检测 | 原理分析 | 模型训练 | 模型推理_yolov11 obb-CSDN博客
YOLO11模型推理 | 目标检测与跟踪 | 实例分割 | 关键点估计 | OBB旋转目标检测-CSDN博客
YOLO11模型训练 | 目标检测与跟踪 | 实例分割 | 关键点姿态估计-CSDN博客
YOLO11 实例分割 | 自动标注 | 预标注 | 标签格式转换 | 手动校正标签-CSDN博客
YOLO11 实例分割 | 导出ONNX模型 | ONNX模型推理-CSDN博客
YOLO11 目标检测 | 导出ONNX模型 | ONNX模型推理-CSDN博客
YOLO11 目标检测 | 自动标注 | 预标注 | 标签格式转换 | 手动校正标签_yolo11 标注平台-CSDN博客
YOLO11 图像缩放 | 图像填充 | 自适应不同尺寸的图片_yolov11 中图像预处理-CSDN博客
分享完成,欢迎大家多多点赞和收藏,谢谢~