【YOLO 入门到精通 08】推理预测完全指南:多数据源、流式推理与性能优化

【YOLO 入门到精通 08】推理预测完全指南:多数据源、流式推理与性能优化

标签 :YOLO推理 流式推理 predict 性能优化 Results对象

难度 :⭐⭐⭐ | 阅读时长 :约 60 分钟 | 系列 :第 08/12 集

前置 :07 验证评估 | 下一集 :09 目标跟踪


写在前面

训练评估之后,模型要真正「干活」------处理图片、视频、摄像头、RTSP 流。本集是 推理的工程实战手册 :不只教 model(img),更教你怎么在生产环境稳定、高效地跑推理。


本集学习目标

  • 掌握全部推理数据源及用法
  • 使用 stream 模式处理长视频
  • 调优 conf/imgsz/batch 等参数
  • 集成到 Flask 等应用

文章目录

  • [【YOLO 入门到精通 08】推理预测完全指南:多数据源、流式推理与性能优化](#【YOLO 入门到精通 08】推理预测完全指南:多数据源、流式推理与性能优化)
    • 写在前面
    • 本集学习目标
    • [8.1 推理模式概览](#8.1 推理模式概览)
    • [8.2 推理数据源大全](#8.2 推理数据源大全)
    • [8.3 流式推理](#8.3 流式推理)
    • [8.4 推理参数详解](#8.4 推理参数详解)
    • [8.5 Results 对象深入](#8.5 Results 对象深入)
    • [8.6 性能优化](#8.6 性能优化)
    • [8.7 应用集成示例](#8.7 应用集成示例)
    • [8.8 踩坑指南](#8.8 踩坑指南)
    • [8.9 常见问题 FAQ](#8.9 常见问题 FAQ)
    • [8.10 本集小结](#8.10 本集小结)

8.1 推理模式概览

#mermaid-svg-w7DLzIkEA1ESpUdV{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-w7DLzIkEA1ESpUdV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-w7DLzIkEA1ESpUdV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-w7DLzIkEA1ESpUdV .error-icon{fill:#552222;}#mermaid-svg-w7DLzIkEA1ESpUdV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-w7DLzIkEA1ESpUdV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-w7DLzIkEA1ESpUdV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-w7DLzIkEA1ESpUdV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-w7DLzIkEA1ESpUdV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-w7DLzIkEA1ESpUdV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-w7DLzIkEA1ESpUdV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-w7DLzIkEA1ESpUdV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-w7DLzIkEA1ESpUdV .marker.cross{stroke:#333333;}#mermaid-svg-w7DLzIkEA1ESpUdV svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-w7DLzIkEA1ESpUdV p{margin:0;}#mermaid-svg-w7DLzIkEA1ESpUdV .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-w7DLzIkEA1ESpUdV .cluster-label text{fill:#333;}#mermaid-svg-w7DLzIkEA1ESpUdV .cluster-label span{color:#333;}#mermaid-svg-w7DLzIkEA1ESpUdV .cluster-label span p{background-color:transparent;}#mermaid-svg-w7DLzIkEA1ESpUdV .label text,#mermaid-svg-w7DLzIkEA1ESpUdV span{fill:#333;color:#333;}#mermaid-svg-w7DLzIkEA1ESpUdV .node rect,#mermaid-svg-w7DLzIkEA1ESpUdV .node circle,#mermaid-svg-w7DLzIkEA1ESpUdV .node ellipse,#mermaid-svg-w7DLzIkEA1ESpUdV .node polygon,#mermaid-svg-w7DLzIkEA1ESpUdV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-w7DLzIkEA1ESpUdV .rough-node .label text,#mermaid-svg-w7DLzIkEA1ESpUdV .node .label text,#mermaid-svg-w7DLzIkEA1ESpUdV .image-shape .label,#mermaid-svg-w7DLzIkEA1ESpUdV .icon-shape .label{text-anchor:middle;}#mermaid-svg-w7DLzIkEA1ESpUdV .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-w7DLzIkEA1ESpUdV .rough-node .label,#mermaid-svg-w7DLzIkEA1ESpUdV .node .label,#mermaid-svg-w7DLzIkEA1ESpUdV .image-shape .label,#mermaid-svg-w7DLzIkEA1ESpUdV .icon-shape .label{text-align:center;}#mermaid-svg-w7DLzIkEA1ESpUdV .node.clickable{cursor:pointer;}#mermaid-svg-w7DLzIkEA1ESpUdV .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-w7DLzIkEA1ESpUdV .arrowheadPath{fill:#333333;}#mermaid-svg-w7DLzIkEA1ESpUdV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-w7DLzIkEA1ESpUdV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-w7DLzIkEA1ESpUdV .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-w7DLzIkEA1ESpUdV .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-w7DLzIkEA1ESpUdV .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-w7DLzIkEA1ESpUdV .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-w7DLzIkEA1ESpUdV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-w7DLzIkEA1ESpUdV .cluster text{fill:#333;}#mermaid-svg-w7DLzIkEA1ESpUdV .cluster span{color:#333;}#mermaid-svg-w7DLzIkEA1ESpUdV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-w7DLzIkEA1ESpUdV .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-w7DLzIkEA1ESpUdV rect.text{fill:none;stroke-width:0;}#mermaid-svg-w7DLzIkEA1ESpUdV .icon-shape,#mermaid-svg-w7DLzIkEA1ESpUdV .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-w7DLzIkEA1ESpUdV .icon-shape p,#mermaid-svg-w7DLzIkEA1ESpUdV .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-w7DLzIkEA1ESpUdV .icon-shape .label rect,#mermaid-svg-w7DLzIkEA1ESpUdV .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-w7DLzIkEA1ESpUdV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-w7DLzIkEA1ESpUdV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-w7DLzIkEA1ESpUdV :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 输入源
预处理
模型推理
后处理
Results
可视化/保存/API

特点 说明
多源 图/视频/摄像头/URL/流
流式 stream=True 省内存
批量 batch=N 提吞吐
可定制 conf/iou/imgsz/classes

8.2 推理数据源大全

来源 示例 stream 说明
图片 'img.jpg' ❌ 单张
目录 'images/' ✅ 批量
视频 'v.mp4' ✅ MP4/AVI
URL 'https://...' ❌ 网络图
摄像头 0 ✅ 设备索引
PIL Image.open() ❌ RGB
OpenCV cv2.imread() ❌ BGR ndarray
RTSP 'rtsp://...' ✅ 监控流
YouTube 'https://youtu.be/...' ✅ 在线视频
Glob '*.jpg' ✅ 通配符
python 复制代码
from ultralytics import YOLO
model = YOLO("yolo26n.pt")

model("img.jpg")           # 路径
model("images/")           # 目录
model("video.mp4")         # 视频
model(source=0)            # 摄像头
model("rtsp://ip/stream")  # RTSP

8.3 流式推理

长视频必须用 stream=True,否则所有帧结果堆在内存里会 OOM。

python 复制代码
results = model.predict(source="long_video.mp4", stream=True, save=True)

for result in results:
    n = len(result.boxes)
    # 处理完即释放,内存稳定

实时摄像头

python 复制代码
import cv2

results = model.predict(source=0, stream=True, show=False)
for r in results:
    frame = r.plot()
    cv2.imshow("YOLO", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cv2.destroyAllWindows()

8.4 推理参数详解

参数 默认 说明 调优
conf 0.25 置信度阈值 误检↑conf,漏检↓conf
iou 0.7 NMS IoU 重复框↓iou
imgsz 640 输入尺寸 小目标↑imgsz
max_det 300 最大检测数 密集场景调大
classes None 过滤类别 [0,2] 只检人/车
half False FP16 GPU 加速
device auto 设备 0/cpu
batch 1 批次 目录推理可增大
rect True 最小矩形填充 导出模型匹配用 False
python 复制代码
results = model.predict(
    source="street.jpg",
    conf=0.5,
    classes=[0, 2, 5],
    imgsz=1280,
    save=True,
    save_txt=True,
    save_crop=True,
    line_width=2,
)

8.5 Results 对象深入

python 复制代码
r = results[0]

# 属性
r.orig_img, r.orig_shape, r.path, r.speed
r.boxes    # 检测
r.masks    # 分割
r.keypoints  # 姿态

# 提取数据
xyxy = r.boxes.xyxy.cpu().numpy()
conf = r.boxes.conf.cpu().numpy()
cls  = r.boxes.cls.cpu().numpy()

# 可视化
r.show()
r.save("out.jpg")
img = r.plot()  # BGR ndarray

8.6 性能优化

技巧 方法 效果
GPU device=0 5~10x
FP16 half=True 1.5~2x
小模型 yolo26n 2~5x
小尺寸 imgsz=320 2~4x
批量 batch=8 1.5~2x
导出 TensorRT 2~5x
python 复制代码
import time
model = YOLO("yolo26n.pt")
model("warmup.jpg", verbose=False)

times = []
for _ in range(100):
    t0 = time.time()
    model("test.jpg", verbose=False)
    times.append(time.time() - t0)
print(f"平均: {sum(times)/len(times)*1000:.1f}ms, FPS: {len(times)/sum(times):.1f}")

8.7 应用集成示例

Flask API

python 复制代码
from flask import Flask, request, jsonify
from ultralytics import YOLO
import cv2, numpy as np, base64

app = Flask(__name__)
model = YOLO("best.pt")

@app.route("/detect", methods=["POST"])
def detect():
    img_b64 = request.json["image"]
    arr = np.frombuffer(base64.b64decode(img_b64), np.uint8)
    img = cv2.imdecode(arr, cv2.IMREAD_COLOR)
    results = model(img, conf=0.5)
    dets = [{
        "class": model.names[int(b.cls[0])],
        "conf": float(b.conf[0]),
        "bbox": b.xyxy[0].tolist(),
    } for b in results[0].boxes]
    return jsonify({"detections": dets})

# uvicorn 用户可换 FastAPI,逻辑相同
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

视频处理管道

python 复制代码
def process_video(inp, out, model_path="yolo26n.pt"):
    model = YOLO(model_path)
    cap = cv2.VideoCapture(inp)
    fps = int(cap.get(cv2.CAP_PROP_FPS)) or 30
    w, h = int(cap.get(3)), int(cap.get(4))
    writer = cv2.VideoWriter(out, cv2.VideoWriter_fourcc(*'mp4v'), fps, (w, h))
    for r in model.predict(inp, stream=True):
        writer.write(r.plot())
    cap.release(); writer.release()

8.8 踩坑指南

坑 解决
长视频 OOM stream=True
无 GUI 无法 show save=True
RTSP 断流 加重连逻辑
导出模型尺寸不匹配 rect=False, imgsz=固定值
推理比训练慢很多 检查是否在用 CPU

8.9 常见问题 FAQ

Q1:model() 和 model.predict()?

A:完全等价。

Q2:能并发处理多路流吗?

A:可以,每路独立 model 实例或线程池。


8.10 本集小结

场景 推荐
单图 model("img.jpg")
批量 model("dir/", batch=16)
长视频 stream=True
监控 stream=True + RTSP

← 第07集 第09集:目标跟踪 →

相关推荐
benchmark_cc1 小时前
第一次补历史 K 线:按股票拆还是按日期拆请求?
python·数据分析·pandas·量化交易·股票数据·quantdash
v:PLLucky201 小时前
眼部疾病智能检测系统
算法·yolo·机器学习·百度·facebook
栈溢出了1 小时前
LangGraph State 学习笔记
开发语言·人工智能·python
Omics Pro1 小时前
00后大3休学创业!AI虚拟细胞
大数据·数据库·人工智能·算法·机器学习·自然语言处理
JAI科研1 小时前
CT重建(二) | 3D高斯泼溅:实时渲染的革命
图像处理·人工智能·计算机视觉·3d·视觉检测·ct重建
打工仔折腾 AI1 小时前
从零写一个CAD 04:中键拖动平移,抓住一个点让它一直待在鼠标底下
人工智能·后端·python·性能优化·计算机外设·ai agent 实战
workflower1 小时前
从生成式模型开始的技术延伸
人工智能·机器学习·机器人·云计算·无人机
kali-Myon1 小时前
ARTEX:AI 驱动的自动化漏洞挖掘平台
人工智能·安全·ai·自动化·web