SIYI 相机 + YOLO + UDP 推流
完整 Python 脚本 · Jetson 实时检测 · FFmpeg 编码 · 网络推流
SIYI RTSP YOLO 人检测 FFmpeg UDP 推流 VLC 播放 Jetson 优化
系统架构
SIYI Camera RTSP
↓
Jetson / Orin Python OpenCV
↓
YOLO human detection
↓
FFmpeg encodes video
↓
UDP stream to Windows
↓
VLC opens udp://@0.0.0.0:5600
配置参数
| 参数 | 值 | 说明 |
|---|---|---|
| RTSP_URL | rtsp://192.168.144.25:8554/main.264 | SIYI 相机 RTSP 流地址 |
| WINDOWS_IP | 192.168.1.14 | Windows 电脑 IP(UDP 接收端) |
| UDP_PORT | 5600 | UDP 推流端口 |
| MODEL_PATH | /home/drobotics/yolov8n.pt | YOLOv8 模型路径 |
| CONF_THRES | 0.25 | 检测置信度阈值 |
| FRAME_WIDTH | 640 | 输出帧宽度 |
| FRAME_HEIGHT | 480 | 输出帧高度 |
| FPS | 25 | 输出帧率 |
完整 Python 脚本
#!/usr/bin/env python3
import cv2
import time
import subprocess
from ultralytics import YOLO
RTSP_URL = "rtsp://192.168.144.25:8554/main.264"
WINDOWS_IP = "192.168.1.14"
UDP_PORT = 5600
MODEL_PATH = "/home/drobotics/yolov8n.pt"
CONF_THRES = 0.25
FRAME_WIDTH = 640
FRAME_HEIGHT = 480
FPS = 25
def open_camera():
cap = cv2.VideoCapture(RTSP_URL, cv2.CAP_FFMPEG)
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
return cap
print("[SIYI YOLO] Loading model...")
model = YOLO(MODEL_PATH)
print("[SIYI YOLO] Opening camera...")
cap = open_camera()
if not cap.isOpened():
print("[SIYI YOLO] ERROR: Cannot open RTSP stream")
exit(1)
ffmpeg_cmd = [
"ffmpeg",
"-y",
"-loglevel", "warning",
"-fflags", "nobuffer",
"-flags", "low_delay",
"-f", "rawvideo",
"-vcodec", "rawvideo",
"-pix_fmt", "bgr24",
"-s", f"{FRAME_WIDTH}x{FRAME_HEIGHT}",
"-r", str(FPS),
"-i", "-",
"-an",
"-c:v", "libx264",
"-preset", "ultrafast",
"-tune", "zerolatency",
"-pix_fmt", "yuv420p",
"-b:v", "2500k",
"-maxrate", "2500k",
"-bufsize", "500k",
"-f", "mpegts",
f"udp://{WINDOWS_IP}:{UDP_PORT}?pkt_size=1316"
]
print("[SIYI YOLO] Opening FFmpeg UDP output...")
process = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE)
print("[SIYI YOLO] Running. Open VLC on Windows:")
print(f"udp://@:{UDP_PORT}")
frame_count = 0
last_time = time.time()
try:
while True:
ret, frame = cap.read()
if not ret:
print("[SIYI YOLO] No frame, reconnecting...")
cap.release()
time.sleep(1)
cap = open_camera()
continue
frame = cv2.resize(frame, (FRAME_WIDTH, FRAME_HEIGHT))
results = model(frame, conf=CONF_THRES, classes=[0], verbose=False)
detection_count = 0
for r in results:
for box in r.boxes:
detection_count += 1
cls = int(box.cls[0])
conf = float(box.conf[0])
name = model.names[cls]
x1, y1, x2, y2 = map(int, box.xyxy[0])
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(
frame,
f"{name} {conf:.2f}",
(x1, max(y1 - 10, 20)),
cv2.FONT_HERSHEY_SIMPLEX,
0.6,
(0, 255, 0),
2
)
frame_count += 1
if time.time() - last_time >= 1:
print(f"[SIYI YOLO] FPS: {frame_count}, person detections: {detection_count}")
frame_count = 0
last_time = time.time()
process.stdin.write(frame.tobytes())
except KeyboardInterrupt:
print("\n[SIYI YOLO] Stopped by user")
except BrokenPipeError:
print("[SIYI YOLO] ERROR: FFmpeg pipe broken")
finally:
cap.release()
if process.stdin:
process.stdin.close()
process.wait()
print("[SIYI YOLO] Clean exit")
代码功能详解
1 配置参数
RTSP_URL:SIYI 相机 RTSP 流地址
WINDOWS_IP / UDP_PORT:UDP 推流目标
MODEL_PATH / CONF_THRES:YOLO 模型路径与置信度阈值
FRAME_WIDTH / FRAME_HEIGHT / FPS:输出视频参数
WINDOWS_IP / UDP_PORT:UDP 推流目标
MODEL_PATH / CONF_THRES:YOLO 模型路径与置信度阈值
FRAME_WIDTH / FRAME_HEIGHT / FPS:输出视频参数
2 相机打开 (open_camera)
cap = cv2.VideoCapture(RTSP_URL, cv2.CAP_FFMPEG)
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
使用 FFmpeg 后端打开 RTSP 流,设置缓冲区大小为 1 以减少延迟。
3 FFmpeg 子进程
- 输入:原始 BGR24 帧 (640x480, 25fps)
- 编码:libx264 (ultrafast, zerolatency)
- 码率:2500k
- 输出:mpegts UDP 推流到 Windows
- 编码:libx264 (ultrafast, zerolatency)
- 码率:2500k
- 输出:mpegts UDP 推流到 Windows
4 YOLO 检测循环
- 读取 RTSP 帧 → resize
- YOLO 推理 (classes=[0] 只检测人, conf=0.25)
- 绘制检测框和标签
- 帧率统计 (每秒输出一次)
- 帧数据写入 FFmpeg 子进程
- YOLO 推理 (classes=[0] 只检测人, conf=0.25)
- 绘制检测框和标签
- 帧率统计 (每秒输出一次)
- 帧数据写入 FFmpeg 子进程
5 断线重连
if not ret:
print("No frame, reconnecting...")
cap.release()
time.sleep(1)
cap = open_camera()
continue
RTSP 流断开时自动重新连接,确保系统长时间稳定运行。
6 清理退出
释放摄像头 → 关闭 FFmpeg 管道 → 等待子进程结束 → 干净退出
FFmpeg 参数详解
| 参数 | 说明 |
|---|---|
-f rawvideo -vcodec rawvideo -pix_fmt bgr24 | 输入原始 BGR24 视频数据 |
-s 640x480 -r 25 | 输入分辨率与帧率 |
-c:v libx264 | H.264 视频编码 |
-preset ultrafast -tune zerolatency | 极速编码,零延迟 |
-b:v 2500k -maxrate 2500k -bufsize 500k | 视频码率控制 |
-f mpegts udp://IP:PORT?pkt_size=1316 | UDP 推流输出 |
VLC 播放地址
udp://@0.0.0.0:5600
Windows 端 VLC 媒体 → 打开网络串流 → 输入以上地址即可实时观看检测画面。
性能参考
Jetson Orin Nano (CUDA 加速): ~25 FPS
YOLO 检测对象: 人 (class 0)
端到端延迟:< 200ms (相机 → 检测 → UDP 推流 → VLC 显示)
YOLO 检测对象: 人 (class 0)
端到端延迟:< 200ms (相机 → 检测 → UDP 推流 → VLC 显示)