YOLO 人员距离速度检测

项目地址:YQisme/Personnel-ranging

基于 YOLO 人员检测 + ByteTrack 跟踪 + 摄像机地面标定,实现稳定的人员距离速度靠近/远离摄像头方向判断。适用于固定摄像头的厂区监控场景。

支持两种使用方式:

  • 命令行main.py 本地 OpenCV 窗口实时预览
  • Web 界面:标定 + 浏览器实时监控(MJPEG 流 + 人员列表)

功能

  • 人员检测:YOLOv8 检测 person 类别
  • 多目标跟踪:ByteTrack 为每个人分配稳定 ID
  • 地面定位:检测框底部中心点作为脚点,Homography 映射到地面坐标
  • 距离计算:人员到摄像头地面投影点 O 的地面距离(米)
  • 速度计算:滑动窗口内距离变化率,卡尔曼滤波平滑
  • 方向判断:距离持续减少 → 靠近摄像头;持续增加 → 远离摄像头
  • RTSP 优化:TCP 传输、小缓冲、读帧失败自动重连
  • 画面标注:OpenCV 英文叠加(低延迟,无 PIL 整帧转换)

系统架构

摄像头 (RTSP) / 本地视频
    │
    ▼
视频解码 (VideoSource,可选自动重连)
    │
    ▼
YOLO 人员检测 + ByteTrack 跟踪
    │
    ▼
脚点计算 (bbox 底部中心)
    │
    ▼
Homography 透视变换
    │
    ├──────────────┐
    ▼              ▼
距离 D=√(X²+Y²)   距离变化率 → 速度
    │              │
    └──────┬───────┘
           ▼
    靠近 / 远离判断
           │
           ├─────────────┬──────────────┐
           ▼             ▼              ▼
    OpenCV 画面标注   JSON 事件    Web MJPEG 流
    (main.py)      (output/)     (/monitor)

距离定义

距离不是「人体框越大越近」,而是:

                 摄像头 📷
                     │
                     ▼
              O 摄像头地面投影点 (0, 0)
                     │
                     │  D 米
                     │
                     ● 👤 人员脚点 P(X, Y)

D = √(X² + Y²)

即:摄像头正下方地面投影点 → 人员脚点 的地面直线距离。

环境要求

  • Python 3.10+
  • Windows / Linux
  • 可选:NVIDIA GPU + CUDA(显著加速 YOLO 推理)

安装

cd yolo判断距离速度
pip install -r requirements.txt

首次运行会自动下载 YOLOv8 模型权重(默认 yolov8n.pt)。

依赖概览:

用途
ultralyticsYOLOv8 检测与 ByteTrack
opencv-python视频读写、画面标注
filterpy卡尔曼滤波
fastapi / uvicornWeb 标定与实时监控
pyyaml配置文件

快速开始

1. 配置视频源

编辑 config/config.yaml

camera:
  rtsp_url: "rtsp://admin:密码@192.168.1.64:554/Streaming/Channels/101"
  # 本地视频优先于 RTSP(非空时使用 video_file)
  video_file: ""
  rtsp_transport: tcp   # RTSP 建议 tcp,更稳定

video_file 非空时优先使用本地文件,便于离线调试。

2. 摄像机标定(必做)

标定建立「像素坐标 → 地面坐标」映射,是距离计算的基础。O 点为坐标原点 (0, 0)通常在画面外,无需在画面上点击

方式一:Web 标定(推荐)

python web/server.py

浏览器打开 http://127.0.0.1:8080

  1. 点击「从视频源抓拍」或「上传图片」加载画面
  2. 在地面用卷尺从 O(摄像头正下方地面点)量出距离
  3. 在画面上点击该可见地面位置,输入卷尺实测距离(如 5m / 10m / 15m / 20m)
  4. 可选填写横向偏移(左负右正,提高透视精度)
  5. 至少 4 个点后点击「保存标定」

自定义端口:

python web/server.py --host 0.0.0.0 --port 8080

方式二:OpenCV 窗口标定

python calibrate.py
# 或指定配置 / 视频源
python calibrate.py --config config/config.yaml --source test.mp4

标定步骤:

  1. 在地面用卷尺从 O 量距离,在画面上点击该位置并输入实测距离
  2. 建议沿主视野方向标 5m / 10m / 15m / 20m,并在同一距离加左右横向点
  3. 至少 4 个点后按 s 保存

操作键:

功能
左键添加标定点(终端输入距离)
s保存标定(至少 4 点)
r重置
q退出

标定结果:

  • config/homography_matrix.npy — 单应性矩阵
  • config/homography_matrix.json — 标定点元数据

无摄像头时生成示例标定:

python generate_sample_calibration.py

3. 运行检测

方式 A:命令行(OpenCV 窗口)

python main.py
# 或指定配置
python main.py --config config/config.yaml

q 退出。可选保存视频与 JSON 事件(见配置 output.*)。

方式 B:Web 实时监控

python web/server.py

打开 http://127.0.0.1:8080/monitor

  1. 确认已完成标定
  2. 点击「开始检测」
  3. 左侧为 MJPEG 实时画面,右侧为当前检测到的人员列表(距离 / 速度 / 方向)

Web 服务同时提供标定页(/)与监控页(/monitor),共用 config/config.yaml 中的视频源与标定文件。

画面标注说明

视频叠加文字使用 OpenCV putText(英文),避免 PIL 整帧转换带来的延迟。

叠加示例:

#12
Dist 7.40m
Speed 1.32m/s (4.8km/h)
Approaching

框与文字颜色:

颜色含义
红色靠近摄像头(Approaching)
绿色远离摄像头(Retreating)
灰色静止(Stationary)
黄色方向未确认(Unknown)
青色圆点脚点位置
橙色十字摄像头地面投影点 O(若在画面内)

配置说明

主配置文件:config/config.yaml

camera — 视频源

参数说明默认
rtsp_urlRTSP 地址
video_file本地视频路径(非空时优先)""
width / height / fps参考分辨率与帧率1920×1080 @ 25
rtsp_transportRTSP 传输协议tcp
max_read_fails连续读帧失败多少次后重连5
reconnect_delay重连等待秒数2

detection — YOLO 检测

参数说明默认
model模型权重yolov8n.pt
confidence检测置信度阈值0.5
classes检测类别 ID 列表[0](person)
imgsz推理输入尺寸,越小越快640
skip_frames每推理 1 帧额外跳过的读帧数;1 表示隔帧检测0

tracking — ByteTrack

参数说明默认
tracker跟踪器配置bytetrack.yaml
persist跨帧保持跟踪 IDtrue

calibration — 标定

参数说明默认
homography_file标定矩阵路径config/homography_matrix.npy

motion — 运动分析

参数说明默认
speed_window_seconds速度滑动窗口(秒)1.0
distance_threshold静止阈值(米),|ΔD| 小于此值视为静止0.3
direction_confirm_frames方向变更需连续满足的帧数5
kalman_process_noise卡尔曼过程噪声0.1
kalman_measurement_noise卡尔曼观测噪声1.0

output — 命令行输出(main.py

参数说明默认
show_window是否显示 OpenCV 窗口true
save_video是否保存标注视频false
video_output视频输出路径output/result.mp4
json_outputJSON 事件输出路径output/events.json

输出示例

JSON 事件(Web /api/detect/statusmain.py 均使用同一结构):

{
  "person_id": 12,
  "ground_x": 6.2,
  "ground_y": 8.5,
  "distance": 10.52,
  "speed": 1.32,
  "speed_kmh": 4.75,
  "direction": "approaching",
  "timestamp": "2026-08-31 10:30:21"
}

方向字段 direction

含义
approaching靠近摄像头(距离持续减少)
retreating远离摄像头(距离持续增加)
stationary静止(距离变化 < 阈值)
unknown尚未确认

性能调优

若画面或 Web 流延迟较大,可按优先级尝试:

  1. 使用 GPU:安装 CUDA 版 PyTorch,YOLO 会自动使用 GPU
  2. 降低推理尺寸detection.imgsz: 480320
  3. 隔帧检测detection.skip_frames: 1(跟踪仍保持,适合 25fps 以上)
  4. 换更小模型yolov8n.pt(已是最小);或确认未误用 yolov8x
  5. RTSP 子码流:改用 Channels/102 降低解码压力(需重新标定或保证视角一致)
  6. Web 场景:监控页为 MJPEG,编码与网络也会带来额外延迟;本地调试可用 main.py

算法说明

脚点

不使用检测框中心,使用底部中心点

foot_x = (x1 + x2) / 2
foot_y = y2

该点近似对应人在地面上的位置。

速度

不用每帧瞬时速度(抖动大),采用滑动窗口内距离变化率

v = |D(t₂) - D(t₁)| / (t₂ - t₁)

默认窗口 1 秒。地面坐标经卡尔曼滤波平滑后再参与计算。

靠近 / 远离

比较窗口内距离变化,并加阈值与连续确认,避免检测框抖动误判:

|ΔD| < 0.3m        → 静止
ΔD < -0.3m         → 靠近摄像头
ΔD > +0.3m         → 远离摄像头
连续 5 帧满足       → 确认状态变更

阈值与确认帧数可在 motion.* 中调整。

项目结构

yolo判断距离速度/
├── config/
│   ├── config.yaml              # 主配置
│   ├── homography_matrix.npy    # 标定矩阵(运行后生成)
│   └── homography_matrix.json   # 标定点元数据
├── src/
│   ├── detector.py              # YOLO + ByteTrack + 脚点
│   ├── homography.py            # 像素 ↔ 地面坐标变换
│   ├── kalman_filter.py         # 位置卡尔曼滤波
│   ├── motion_analyzer.py       # 距离 / 速度 / 方向
│   ├── visualizer.py            # OpenCV 英文画面标注
│   ├── pipeline.py              # 检测流水线(Web 与扩展共用)
│   ├── live_detection.py        # Web 后台检测线程 + MJPEG
│   ├── video_source.py          # RTSP 读帧与自动重连
│   └── calibration_service.py   # Web 标定 API 逻辑
├── calibrate.py                 # OpenCV 窗口标定工具
├── main.py                      # 命令行主入口
├── generate_sample_calibration.py
├── web/
│   ├── server.py                # FastAPI:标定 + 实时监控
│   └── static/                  # 前端(标定页 / 监控页)
├── requirements.txt
└── README.md

Web API 摘要

方法路径说明
GET/标定页面
GET/monitor实时监控页面
GET/api/status标定状态、视频源、检测是否运行
POST/api/capture从配置的视频源抓拍一帧
POST/api/upload上传标定用图片
GET/api/frame当前标定帧 JPEG
GET/api/existing读取已有标定点
POST/api/validate校验标定点
POST/api/save保存标定
POST/api/detect/start启动后台检测
POST/api/detect/stop停止检测
GET/api/detect/statusFPS、人员列表、错误信息
GET/api/detect/streamMJPEG 实时流

RTSP 地址格式

常见格式:

rtsp://admin:密码@IP:554/Streaming/Channels/101   # 主码流
rtsp://admin:密码@IP:554/Streaming/Channels/102   # 子码流

常见问题

标定文件不存在

先完成 Web 或 calibrate.py 标定,或运行 python generate_sample_calibration.py 生成示例(仅用于流程测试,距离不准)。

标定点几乎共线警告

仅在一条线上标定时 Homography 精度不足。请在同一距离处增加左右横向偏移点。

距离明显不准

  • 确认卷尺实测距离准确,标定点覆盖人员活动区域
  • 增加标定点数量,覆盖人员可能出现的区域
  • 摄像头位置或俯仰角变化后需重新标定

RTSP 连接失败

  • 确认 IP、端口、账号密码
  • 用 VLC 先验证 RTSP 是否可播
  • 检查 rtsp_transport(建议 tcp
  • 可改用 video_file 本地视频测试

Web 监控黑屏或 FPS 很低

  • 确认已标定且 /api/detect/statuserror
  • 检查 YOLO 是否在 CPU 上运行(安装 GPU 版 PyTorch)
  • 尝试 detection.imgszskip_frames 调优
  • 主码流 1080p 解码 + 推理压力大,可试子码流

画面延迟大

  • 优先排查 YOLO 推理与 RTSP 缓冲(已默认 CAP_PROP_BUFFERSIZE=1
  • Web MJPEG 比本地 main.py 窗口延迟更高,属正常现象