预测实战)
YOLO 定向目标检测推理全解析OBBPredictor 源码剖析与旋转框OBB预测实战【免费下载链接】yolov10YOLOv10: Real-Time End-to-End Object Detection [NeurIPS 2024]项目地址: https://gitcode.com/GitHub_Trending/yo/yolov10本文以 YOLOv10 仓库中ultralytics/models/yolo/obb/predict.py的OBBPredictor类为线索系统讲解定向边界框Oriented Bounding Box, OBB推理的完整链路从类继承关系、postprocess逐行实现到旋转框 NMS、坐标格式规整、结果对象读取再到 Python API 与 CLI 实战。读完本文你将能够理解旋转框预测输出中xywhr七维向量的来龙去脉并直接上手运行 OBB 模型完成对遥感、航拍、文字检测等密集场景中的旋转目标检测。一、OBBPredictor 是什么从水平框到旋转框的推理进阶普通目标检测输出的是轴对齐的水平边界框HBB对于飞机、舰船、车辆、文本等长宽比悬殊或任意朝向的目标水平框会引入大量背景噪声且多个密集目标互相重叠时难以通过常规 NMS 正确抑制。定向目标检测在水平框四参数(x_center, y_center, width, height)基础上额外引入一个旋转角度r输出xywhr五参数旋转框从而精确贴合目标本体。在 YOLOv10 仓库中OBB 推理由 ultralytics/models/yolo/obb/predict.py 中的OBBPredictor类承担。它专门负责输入任意来源图像 → 调用 OBB 模型前向推理 → 旋转框后处理 → 输出Results对象这一条链路是与DetectionPredictor水平框、SegmentationPredictor分割、PosePredictor姿态并列的预测器实现之一。二、类结构与继承关系三个层次的职责分工从源码结构看OBBPredictor采用三级继承设计职责层层递进engine/predictor.py 的BasePredictor提供推理基础设施包括数据源加载setup_source、预处理preprocess/pre_transform内部使用LetterBox做等比例缩放填充、模型加载setup_model通过AutoBackend支持 PyTorch/ONNX/TensorRT 等多种后端、流式推理主循环stream_inference、结果保存与可视化write_results、save_predicted_images、show、线程安全锁等。ultralytics/models/yolo/detect/predict.py 的DetectionPredictor实现水平框检测的postprocess执行常规 NMS 并把坐标缩放到原图尺寸。ultralytics/models/yolo/obb/predict.py 的OBBPredictor仅通过覆盖__init__与postprocess两个方法就把通用检测推理旋转框化这是 OBB 推理与普通检测推理的全部差异所在。OBBPredictor的完整定义如下见 predict.pyclass OBBPredictor(DetectionPredictor): A class extending the DetectionPredictor class for prediction based on an Oriented Bounding Box (OBB) model. def __init__(self, cfgDEFAULT_CFG, overridesNone, _callbacksNone): super().__init__(cfg, overrides, _callbacks) self.args.task obb def postprocess(self, preds, img, orig_imgs): preds ops.non_max_suppression( preds, self.args.conf, self.args.iou, agnosticself.args.agnostic_nms, max_detself.args.max_det, nclen(self.model.names), classesself.args.classes, rotatedTrue, ) if not isinstance(orig_imgs, list): orig_imgs ops.convert_torch2numpy_batch(orig_imgs) results [] for pred, orig_img, img_path in zip(preds, orig_imgs, self.batch[0]): rboxes ops.regularize_rboxes(torch.cat([pred[:, :4], pred[:, -1:]], dim-1)) rboxes[:, :4] ops.scale_boxes(img.shape[2:], rboxes[:, :4], orig_img.shape, xywhTrue) obb torch.cat([rboxes, pred[:, 4:6]], dim-1) # xywh, r, conf, cls results.append(Results(orig_img, pathimg_path, namesself.model.names, obbobb)) return results关键点__init__中self.args.task obb标记任务类型后续数据加载、预处理、结果渲染都会据此走 OBB 分支而postprocess则是旋转框推理的算法核心下面逐行拆解。三、postprocess 逐行拆解旋转框推理的四个关键步骤3.1 旋转框 NMSrotatedTrue打开旋转抑制preds ops.non_max_suppression( preds, self.args.conf, self.args.iou, agnosticself.args.agnostic_nms, max_detself.args.max_det, nclen(self.model.names), classesself.args.classes, rotatedTrue, )与水平检测的 NMS 唯一区别在于rotatedTrue。它告诉ops.non_max_suppression预测张量的最后一维携带旋转角度参与 IoU 计算的框是xywhr旋转框而非xyxy水平框。此阶段使用的关键参数均来自推理配置conf置信度阈值低于该值的预测直接丢弃预测模式默认0.25见 default.yaml 注释conf未显式指定时 predictor 内部会补默认值iouNMS 的 IoU 阈值默认0.7agnostic_nms是否做类别无关 NMS默认Falsemax_det单张图像最大保留检测数默认300classes按类别 ID 过滤如classes0或classes[0,2,3]nc从self.model.names取类别总数保证 NMS 按类别维度正确分组。3.2 规整旋转角度regularize_rboxesrboxes ops.regularize_rboxes(torch.cat([pred[:, :4], pred[:, -1:]], dim-1))NMS 输出中每个旋转框由(x, y, w, h, conf, cls, r)构成前四列是中心点与宽高xywh最后一列是旋转角r中间两列是置信度与类别。这里先把xywh与末列角度r重新拼接成五参数旋转框再调用ops.regularize_rboxes把角度规整到标准定义域如[-π/2, π/2)确保后续坐标缩放与可视化阶段角度语义一致。这是旋转框推理区别于水平框推理的独特一步。3.3 坐标缩放回原图scale_boxes(..., xywhTrue)rboxes[:, :4] ops.scale_boxes(img.shape[2:], rboxes[:, :4], orig_img.shape, xywhTrue)模型在预处理后的 letterbox 尺寸img.shape[2:]即(H, W)上输出预测而orig_img.shape是原始输入尺寸。scale_boxes结合预处理时记录的缩放比例与填充偏移把xywh坐标逆变换回原图坐标系xywhTrue指明输入输出均为xywh格式而非xyxy。同时当输入是torch.Tensor批张量时先通过convert_torch2numpy_batch转回 numpy 图像列表以便与每个预测一一对应。3.4 组装最终结果xywh, r, conf, cls七维张量obb torch.cat([rboxes, pred[:, 4:6]], dim-1) # xywh, r, conf, cls results.append(Results(orig_img, pathimg_path, namesself.model.names, obbobb))最终每个目标的输出是形状为[N, 7]的张量列含义依次为列索引含义说明0, 1x_center,y_center旋转框中心点坐标原图尺度2, 3width,height旋转框宽高原图尺度4r旋转角弧度已规整5conf置信度分数6cls类别索引该张量被封装进Results对象obb关键字参数并携带原图、图像路径与类别名表self.model.names一起返回供上层stream_inference循环统一进行保存、可视化与日志输出。四、从 Results 读取旋转框OBB 结果对象与坐标属性推理返回的每个Results对象都带有一个obb属性其类型为 ultralytics/engine/results.py 中定义的OBB类继承自BaseTensor。OBB构造时断言张量末维为 7 或 87 对应(xywh, r, conf, cls)8 则在中间多出一列跟踪 IDis_trackTrue用于旋转框跟踪场景。读取结果的标准姿势from ultralytics import YOLO model YOLO(yolov8n-obb.pt) # 加载预训练 OBB 模型 results model(aerial.jpg) # 对单张图片推理 r results[0] obb r.obb # OBB 对象data 形状 [N, 7] 或 [N, 8] xywhr obb.xywhr # [N, 5](x, y, w, h, angle) 旋转框原始表示 xyxyxyxy obb.xyxyxyxy # [N, 8]四角点坐标原图尺度 xyxyxyxyn obb.xyxyxyxyn # [N, 8]四角点坐标归一化 conf obb.conf # [N]置信度 cls obb.cls # [N]类别索引OBB类还提供cpu()、numpy()、cuda()、to()等张量迁移方法方便接入后续的自定义后处理或业务逻辑。这种原始xywhr与展开xyxyxyxy双视图的设计既方便几何计算也方便直接绘制与导出。五、快速上手直接使用 OBBPredictor 类除了高层YOLO接口源码 docstring 给出了直接实例化OBBPredictor的底层用法见 predict.py适合需要定制回调或细粒度控制推理流程的场景from ultralytics.utils import ASSETS from ultralytics.models.yolo.obb import OBBPredictor args dict(modelyolov8n-obb.pt, sourceASSETS) predictor OBBPredictor(overridesargs) predictor.predict_cli()其中overrides是一个参数字典会被合并进全局默认配置见 default.yamlpredict_cli()以 CLI 同等的语义运行推理逐批消费结果而不在内存中累积。六、推理参数速查控制 OBB 预测行为的核心配置OBBPredictor的所有行为均由 ultralytics/cfg/default.yaml 中 Predict settings / Visualize settings 一节驱动OBB 推理最常用的参数如下参数默认值作用source无推理数据源图片、视频、目录、glob、URL、摄像头0等imgsz640推理输入尺寸OBB 官方权重通常建议1024conf0.25predict置信度阈值iou0.7NMS 的 IoU 阈值max_det300每图最大检测数agnostic_nmsFalse类别无关 NMSclasses无仅保留指定类别device无cpu/0/0,1halfFalseFP16 半精度推理dnnFalseONNX 使用 OpenCV DNN 后端vid_stride1视频抽帧步长augmentFalse推理时 TTA 增强save/save_txtFalse保存标注图 / 保存 txt 标签save_confFalsetxt 中附带置信度show/show_labels/show_conf/show_boxesFalse/True/True/True可视化相关line_width无画框线宽为空则按图缩放七、CLI 实战一条命令完成旋转框预测以yolov8n-obb.pt预训练模型为例该权重基于 DOTAv1 类数据预训练任务文档见 docs/en/tasks/obb.mdCLI 用法如下# 对单张图片推理并保存标注结果 yolo obb predict modelyolov8n-obb.pt sourceaerial.jpg saveTrue # 对整个目录推理1024 输入尺寸同时导出 txt 标签与置信度 yolo obb predict modelyolov8n-obb.pt source./dataset/images imgsz1024 save_txtTrue save_confTrue # 从摄像头实时推理 yolo obb predict modelyolov8n-obb.pt source0等价的高层 Python 接口from ultralytics import YOLO model YOLO(yolov8n-obb.pt) # 或自定义权重 path/to/best.pt results model.predict( sourceaerial.jpg, conf0.25, iou0.7, max_det300, saveTrue, save_txtTrue, save_confTrue, )八、测试验证仓库如何保障 OBB 推理正确性仓库测试 tests/test_python.py 的test_predict_img对 OBB 推理做了端到端验证加载yolov8n-obb.pt权重后对torch.Tensor形式的批量输入执行推理并断言返回的results数量与输入 batch 大小一致obb_model YOLO(WEIGHTS_DIR / yolov8n-obb.pt) ... results obb_model(t, imgsz32) assert len(results) t.shape[0]这意味着OBBPredictor不仅要正确处理图片、视频等常规来源也必须兼容张量输入路径——这正是postprocess中convert_torch2numpy_batch分支存在的原因可以作为你在业务中复用该组件的可靠性参考。九、延伸阅读与 OBB 训练验证生态的衔接OBBPredictor并非孤立模块它与 OBB 任务闭环中的另外两个组件配套使用三者统一从 ultralytics/models/yolo/obb/init.py 导出OBBTrainerOBB 训练器对应 train.py负责模型训练OBBValidatorOBB 验证器见 ultralytics/models/yolo/obb/val.py。它的postprocess同样以rotatedTrue调用 NMS并采用batch_probiou概率式旋转 IoU计算mAP且能输出 DOTA 评测所需的predictions_txt/predictions_merged_txt结果文件。验证器中的pred_to_json通过xywhr2xyxyxyxy把旋转框转为 8 点多边形与推理侧OBB.xyxyxyxy属性形成对照模型结构定义位于 ultralytics/cfg/models/v8/yolov8-obb.yaml配套的小规模数据配置为 ultralytics/cfg/datasets/dota8.yaml适合快速跑通训练 → 验证 → 预测全流程。十、总结OBBPredictor是 YOLO 定向目标检测推理的标准入口其核心价值在于用最小改动仅覆盖__init__与postprocess复用了整套推理基础设施同时通过rotatedTrue的旋转框 NMS、regularize_rboxes的角度规整与scale_boxes(..., xywhTrue)的坐标逆变换把通用检测输出转换为(xywh, r, conf, cls)七维旋转框表示。理解这条后处理链路你就能在遥感影像、航拍图像、文档版面分析等高密度旋转目标场景中快速部署、调参与二次开发 OBB 推理能力。【免费下载链接】yolov10YOLOv10: Real-Time End-to-End Object Detection [NeurIPS 2024]项目地址: https://gitcode.com/GitHub_Trending/yo/yolov10创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考