4.8 实时视觉流水线框架

为什么这很重要

仅有一个准确的模型并不能构成一个实时视觉系统。

一个能正常工作的系统还需要:

  • 来自摄像头或文件的输入
  • 解码与帧传输
  • 推理与后处理
  • 显示、存储或下游通信

整条链路被称为流水线。

本节将介绍理解实时视觉系统所需的框架思维,然后再进入 DeepStream 与 Jetson 专属服务的内容。

学习目标

学完本节后,你应该能够:

  • 解释实时视觉流水线的主要阶段
  • 比较简单的应用流水线与基于框架的流水线
  • 理解 OpenCVGStreamer 的角色
  • 编写读取并处理实时视频的小示例
  • 用端到端系统流的视角思考问题,而不是只看孤立的模型调用

核心概念 / 理论

实时流水线包含多个阶段

一个典型的实时视觉流水线包括:

  1. 源输入
  2. 解码与帧获取
  3. 预处理
  4. 模型推理
  5. 后处理
  6. 渲染、存储或传输

为什么流水线很重要

如果某一阶段不稳定或太慢,整个系统都会受影响。

例如:

  • 糟糕的 RTSP 流会造成丢帧
  • 慢速的预处理会增加延迟
  • 不必要的显示开销会限制吞吐

OpenCV vs GStreamer

OpenCV 适合用于学习和应用逻辑。

当你需要稳健的媒体流水线、流媒体和实时数据流时,GStreamer 更强大。

两者都很有用,但承担的角色不同。

关键术语

  • Source:帧的来源
  • Decode:将压缩视频转换为帧
  • Preprocessing:为推理准备帧
  • Post-processing:将原始预测转换为有用的输出
  • Latency:流水线的端到端延迟
  • Throughput:已处理的帧或流的总量

实例 / 代码示例

简单的 OpenCV 实时流水线

python
import cv2
import time

cap = cv2.VideoCapture(0)
prev_time = time.time()

while True:
    ok, frame = cap.read()
    if not ok:
        break

    current_time = time.time()
    fps = 1.0 / (current_time - prev_time)
    prev_time = current_time

    cv2.putText(frame, f"FPS: {fps:.2f}", (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
    cv2.imshow("OpenCV Live Pipeline", frame)

    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

cap.release()
cv2.destroyAllWindows()

GStreamer 示例

bash
gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink

RTSP 输入示例

bash
gst-launch-1.0 rtspsrc location=rtsp://<camera-ip>/<path> latency=200 ! \
  rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! autovideosink

常见误解

  • "模型就是流水线。"
    • 模型只是流水线中的一个阶段。
  • "如果模型基准测试达到了 30 FPS,整个系统就能跑到 30 FPS。"
    • 端到端性能取决于整条流水线。
  • "OpenCV 和 GStreamer 做的是同一件事。"
    • 它们在某些方面有重叠,但并不是同一种工具。

练习 / 思考

  1. 为一个网络摄像头检测器画一个五阶段的实时流水线。
  2. 运行 OpenCV 示例,并测量你机器上的近似 FPS。
  3. 比较视频文件输入与实时摄像头输入,你观察到了哪些实际的差异?
  4. 解释为什么端到端延迟通常比模型推理时间本身更重要。

总结

实时计算机视觉依赖于流水线的设计,而不仅是模型本身。理解输入、解码、预处理、推理、后处理和输出,能帮助学习者为更高级的边缘框架(如 DeepStream)做好准备。

建议的下一步

继续阅读 4.9 DeepStream 与 Jetson

参考资料