资讯动态

Ultralytics DetectionPredictor 源码级解析:YOLO 目标检测推理的完整实现与后处理原理

发布时间:2026/9/8 17:18:18 来源:尧图企业网站定制
Ultralytics DetectionPredictor 源码级解析YOLO 目标检测推理的完整实现与后处理原理【免费下载链接】ultralyticsUltralytics YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking项目地址: https://gitcode.com/GitHub_Trending/ul/ultralytics导读本文以 docs/en/reference/models/yolo/detect/predict.md 定义的 API 为线索深度剖析 Ultralytics YOLO 检测任务推理器DetectionPredictor的实现从类定义、初始化、任务分发到前处理 / 推理 / 后处理全链路以及核心的 NMS非极大值抑制与目标框坐标还原逻辑。读完本文你将能理解model.predict()与 CLI 模式yolo modepredict在底层究竟发生了什么掌握DetectionPredictor各方法的职责、关键推理参数的真实作用并能基于源码自行扩展或调试检测推理流程。DetectionPredictor检测任务专属的推理器DetectionPredictor定义在 ultralytics/models/yolo/detect/predict.py继承自 ultralytics/engine/predictor.py 中的BasePredictor是目标检测任务对通用预测流程的任务专用定制层。它的定位正如其 docstring 所述将模型原始输出加工成包含边界框bounding box与类别预测的可理解检测结果。从类定义可以看到其核心构成Attributes属性args预测配置SimpleNamespace、model用于推理的检测模型、batch批图像及元数据等均由基类维护检测任务无需重复实现Methods方法postprocess将原始预测处理为检测结果、construct_results批量构建Results对象、construct_result由单张图像预测构造单个Result、get_obj_feats从特征图中抽取目标特征。这四个方法中postprocess是任务差异的核心入口其余三个是它的辅助分解。这种基类定流程、子类定后处理的设计让分类、分割、姿态、OBB 等任务各自只覆写自己的后处理逻辑是理解整个ultralytics/engine预测框架的关键。推理器在模型调用链中的位置日常使用中用户并不直接接触DetectionPredictor而是通过统一的YOLO(yolo26n.pt).predict(source...)或 CLI 调用。其装配链路如下ultralytics/engine/model.py 中的Model.predict()计算合并后的args默认conf0.25、batch1、modepredict、rectTrue并通过_smart_load(predictor)惰性创建推理器实例_smart_load依据任务类型查表。在 ultralytics/models/yolo/model.py 的task_map中detect任务映射的predictor正是DetectionPredictorpose、segment、obb 等任务则映射到各自的推理器子类推理器创建后调用setup_model(modelself.model, verboseis_cli)engine/predictor.py完成后端装配最终进入predict_cli()或__call__驱动的流式推理。# 直接使用 DetectionPredictor 的最小示例源自其类 docstring 的官方用法 from ultralytics.utils import ASSETS from ultralytics.models.yolo.detect import DetectionPredictor args dict(modelyolo26n.pt, sourceASSETS) predictor DetectionPredictor(overridesargs) predictor.predict_cli()其中DetectionPredictor已在 ultralytics/models/yolo/detect/init.py 中随DetectionTrainer、DetectionValidator一起导出因此可以from ultralytics.models.yolo.detect import DetectionPredictor直接导入。推理主循环preprocess → inference → postprocessDetectionPredictor本身并不包含流式主循环而是复用基类BasePredictor.stream_inference()ultralytics/engine/predictor.py定义的每批处理流程。理解这一流程是掌握后处理上下文的前提Setupsetup_source()解析输入源并计算imgsz必要时以self.model.warmup(imim)预热Preprocesspreprocess将输入的 BGRuint8图像np.stack后转置为BHWC→BCHW、执行BGR→RGB翻转、归一化到0.0–1.0并按模型fp16状态转为half/floatengine/predictor.py在此之前pre_transform会用LetterBox将不同尺寸的图缩放并填充到统一输入尺寸Inferenceinference调用self.model(im, augmentself.args.augment, embedself.args.embed)得到原始预测张量Postprocesspostprocess即本文件的核心——由DetectionPredictor覆写的后处理Profile 与产出基类用三个ops.Profile分别统计preprocess / inference / postprocess每张图的毫秒耗时写入self.results[i].speed字典并打印。这也是终端中Speed: x.xms preprocess, x.xms inference, x.xms postprocess per image一行日志的来源。基类BasePredictor.__call__engine/predictor.py还体现了两个重要语义streamFalse时返回打包为 list 的ResultsstreamTrue时返回生成器stream_inference后者对视频/长流输入必须开启否则推理结果会在 RAM 中持续累积基类STREAM_WARNING常量对此有明确警告。postprocess 深潜NMS 调用与参数透传DetectionPredictor.postprocess()ultralytics/models/yolo/detect/predict.py是检测推理最关键的环节它将模型输出的稠密预测张量训练时保留的 loss 输出等多余通道在 NMS 内部会被剔除过滤为稀疏的最终检测框。其签名接收三个输入preds模型原始输出img预处理后的输入张量形状(N,3,H,W)orig_imgs前处理前的原始图像可能是torch.Tensor或list[np.ndarray]。方法体第一步即调用nms.non_max_suppressionultralytics/utils/nms.py。值得注意其参数映射关系这正是 CLI/Python 中众多推理参数真正生效的位置postprocess 中传入取值来源含义与默认值见 ultralytics/cfg/default.yamlconf_thresself.args.conf置信度阈值预测默认0.25引擎层也会兜底设为 0.25iou_threskwargs.pop(iou, self.args.iou)NMS 的 IoU 阈值默认0.7允许调用方如 TrackTrack 的 loose-NMS 恢复逻辑临时覆盖classesself.args.classes按类别 ID 过滤如0或[0,2,3]默认不过滤agnosticself.args.agnostic_nms是否做类别无关 NMS默认Falsemax_detself.args.max_det每张图最多保留的检测数默认300nc0 if taskdetect else len(model.names)检测任务直接传0由 NMS 内部按张量结构推断类别数rotatedtask obb旋转框OBB开关从该分支可见 detect 推理器后处理同时服务旋转框场景end2endgetattr(self.model, end2end, False)是否为端到端免 NMS模型return_idxssave_feats是否需要返回被保留检测在特征图中的索引用于目标特征抽取紧接着的一行处理输入格式差异if not isinstance(orig_imgs, list): # input images are a torch.Tensor, not a list orig_imgs ops.convert_torch2numpy_batch(orig_imgs)[..., ::-1]即当输入为torch.Tensor时通过 ultralytics/utils/ops.py 的convert_torch2numpy_batch转回 numpy 批量数组并沿最后一维反转通道BGR↔RGB以匹配绘图约定。目标特征导出分支save_featspostprocess还承担了目标级特征导出的旁路能力predict.pysave_feats getattr(self, _feats, None) is not None当外部如某些可视化/检索需求设置了_feats时NMS 以return_idxsTrue返回保留检测的索引preds[1]随后调用get_obj_feats从特征图中抽取每个检测框对应的目标特征并把结果写回Results.featsif save_feats: for r, f in zip(results, obj_feats): r.feats f # add object features to resultsget_obj_featspredict.py的实现思路是从多层特征图中抽取通道维度最短的向量长度s将各层特征permutereshape后做mean(dim-1)统一向量长度再沿 channel 维拼接最后按 NMS 返回的索引取每个 batch 内检测框对应的特征。这为实例检索、特征比对类上层应用保留了通道但属可选能力默认推理路径并不触发。坐标还原与 Results 组装NMS 输出的框坐标处于预处理后图像的坐标系中LetterBox缩放填充后的 640×640 网格需要映射回原图坐标。construct_results与construct_result完成这一步def construct_result(self, pred, img, orig_img, img_path): pred[:, :4] ops.scale_boxes(img.shape[2:], pred[:, :4], orig_img.shape) return Results(orig_img, pathimg_path, namesself.model.names, boxespred[:, :6])ops.scale_boxesultralytics/utils/ops.py依据前处理输入尺寸img.shape[2:]与原始图像orig_img.shape的缩放/填充比例将(x1,y1,x2,y2)角点坐标还原到原图同时对越界坐标做裁剪还原后的前 6 列(x1, y1, x2, y2, conf, cls)与类别名self.model.names一起封装进ultralytics.engine.results.Results此对象即用户在 Python 端拿到的result其.boxes.xyxy、.boxes.conf、.boxes.cls等接口都源自这里construct_results则是按批将preds、预处理图、原图与self.batch[0]中的路径列表逐一对齐 zip批量构造结果列表。NMS 内部流程速览为便于排查检测数量、漏检、误检等问题这里概要展开non_max_suppressionultralytics/utils/nms.py的内部骨架未逐行展开的细节见源码输入形状为(bs, 4ncextra, anchors)时先转置为(bs, anchors, 4ncextra)将xywh中心格式通过xywh2xyxy转为xyxy角点格式旋转框场景跳过该步通过xc prediction[:, 4:mi].amax(1) conf_thres一次性筛出所有类上置信度超过conf_thres的候选锚点对每张图逐张做按类 NMSagnosticTrue时不按类分组期间自动在 torchvision NMS当推理设备非 XPU 且 torchvision 已加载与纯 torch 实现间切换依次应用classes类别过滤、max_det数量截断与max_wh/max_time_img等保护性限制最终每张图输出(N, 6extra)的检测矩阵。其中end2endTrue或输出末维恰为 6 的模型走免 NMS 快速通道仅做置信度过滤、类别过滤与max_det截断不执行任何框重叠抑制——这对应 RT-DETR 一类已内嵌 NMS 的端到端架构。DetectionPredictor正是通过getattr(self.model, end2end, False)感知这一差异从而保证同一套后处理入口兼容传统与端到端两类模型。与检测推理相关的核心参数在 CLI 或 Python 中传给predict的这些参数会最终流入上文postprocess的 NMS 调用默认值以 ultralytics/cfg/default.yaml 为基准参数默认作用confpredict 0.25 / val 0.001置信度阈值低于该值的目标被过滤范围 0.0–1.0iou0.7NMS 的 IoU 阈值越大保留的重叠框越多max_det300单图最多保留检测框数agnostic_nmsFalse为 True 时 NMS 不区分类别classesNone按类别 ID 列表过滤输出imgsz640推理输入尺寸predict 阶段支持[h, w]非方形rectpredict 时 True同尺寸批启用矩形推理减少填充浪费augmentFalse测试时增强TTA开关vid_stride1视频源每隔 N 帧读取一次stream_bufferFalse视频缓冲策略影响实时流延迟save/save_txt/save_crop按模式保存可视化结果 / txt 标签 / 裁剪目标showFalse弹窗显示依赖图形环境show_labels/show_conf/show_boxesTrue绘图是否绘制标签 / 置信度 / 框line_widthNone框线宽缺省随图像尺寸自动缩放device自动如0、cpu、mps等对应 CLI 用法模式与参数完全一致yolo modepredict modelyolo26n.pt sourcehttps://ultralytics.com/images/bus.jpg conf0.25 iou0.7 max_det300 yolo modepredict modelyolo11n.pt source./videos/ streamTrue saveTrue基于源码的扩展方向理解了DetectionPredictor的分层结构后常见的定制场景有清晰落点自定义后处理继承DetectionPredictor并覆写postprocess/construct_result再通过model.predict(..., predictorMyPredictor)注入该机制在 ultralytics/models/yolo/model.py 的视觉提示预测场景中已有运用逐阶段性能剖析Results.speed与终端日志中的三段耗时即由基类三个Profile产生可用作定位 preprocess / inference / postprocess 瓶颈的依据线程安全推理基类以self._lock包裹整个推理循环engine/predictor.py可在多线程环境下复用同一 predictor 实例。更多运行时参数与输入源类型图片、视频、目录、glob、Web 摄像头、RTSP 流、YouTube 等的说明可继续阅读 docs/en/modes/predict.md完整推理流程请结合 docs/en/reference/engine/predictor.md 中的BasePredictor参考页理解。【免费下载链接】ultralyticsUltralytics YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking项目地址: https://gitcode.com/GitHub_Trending/ul/ultralytics创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价