MetrPikeska/roundabout-exit-detection

GitHub: MetrPikeska/roundabout-exit-detection

基于 YOLOv8 和 ByteTrack 的环形交叉口视觉分析流水线,将车辆检测、轨迹跟踪与 GIS 空间分析整合,输出速度、流向、密度及冲突等多维交通指标。

Stars: 0 | Forks: 0

# 环形交叉路口交通分析 – 基于视觉的 GIS 流水线 使用 YOLOv8 + ByteTrack 结合地理参考单应性标定,对环形交叉路口的车辆和行人进行自动检测、跟踪和空间分析。输出包括 GeoPackage/GeoTIFF 图层,可直接导入 QGIS 或 PostGIS。 ## 结果 处理了**5分钟**的航拍镜头(Kopřivnice,Obránců míru 交叉路口): | 指标 | 值 | |---|---| | 检测到的车辆(轨迹 ≥ 5 个点) | **142**(130辆乘用车,12辆卡车) | | 平均运行速度 | **23.1 km/h** | | 第85百分位速度 | **31.9 km/h** | | 平均轨迹长度 | **46.6 m** | | 记录的驶离交叉总次数 | 5分钟内 **93** 次 | | 高峰流量 | **23 辆/分钟**(第4分钟) | | 主要 O/D 流向 | SW(西南)入口 → NE(东北)入口(25辆车,26 %) | | 出口加速度(驶离阶段) | **29.8 km/h**,而驶近时为 20.8 km/h | | 检测到的车辆-行人冲突 | **139**(132次 SW 横穿,7次 NE 横穿) | **单应性标定:** 来自 ČÚZK 正射影像的 11 个地面控制点(QGIS,S-JTSK EPSG:5514)。 平均重投影误差:**0.51 m**,最大 **0.97 m**。 速度估计未与 GPS 参考进行验证。对 3 个经过的样本进行人工比对:误差在约 ±3 km/h 范围内一致。 ## 输出示例 **车辆跟踪回放(YOLOv8 + ByteTrack,带有瞬时速度的轨迹拖尾):** ![跟踪演示](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/7cfa095b63060408.gif) **检测输出帧:** ![检测样本](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/2bbc11e8fc060414.jpg) **GIS 可视化 – 正射影像上的轨迹(QGIS):** ![QGIS 可视化](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/a2080ed40d060421.png) ## 空间统计 `spatial_stats.py` 读取 `data/tracks.pkl` 并在 `output/` 中生成三种可视化图表。 ``` python spatial_stats.py ``` ![密度热力图与速度着色轨迹](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/461e93b76c060426.png) ![带有罗盘玫瑰的所有轨迹](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/d4bad63190060432.png) ![总结仪表板](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/32b41ce960060438.png) ## 项目结构 该项目为不同的分析目标提供了**两个独立的工作流**: ``` roundabout-exit-detection/ │ │ ── Workflow A: Exit counting (pixel-space) ────────────────── ├── define_exclusion.py # interactive exclusion zone definition ├── 01_detect_and_count.py # YOLOv8 + pixel polygons → CSV │ └── output/car_crossings.csv (flow per exit per minute) │ │ ── Workflow B: GIS tracking pipeline ──────────────────────── ├── extract_frame.py # frame extraction for calibration ├── calibrate.py # GCP clicking → homography.npy ├── detect_track.py # YOLOv8 + ByteTrack + homography → pkl ├── speed_estimator.py # speed computation module (importable) ├── export_geo.py # tracks.pkl → GeoPackage (QGIS/PostGIS) │ │ ── Analysis modules ───────────────────────────────────────── ├── spatial_stats.py # spatial statistics + visualisations │ └── output/stats_*.png ├── od_matrix.py # origin–destination matrix between arms │ └── output/od_matrix.csv ├── speed_profile.py # speed profile per phase (approach/circulating/departure) │ └── output/speed_profile.csv + speed_profile.png ├── heatmap.py # movement density → GeoTIFF + PNG preview │ └── output/heatmap.tif (EPSG:4326) + heatmap_preview.png ├── pedestrian_conflicts.py # vehicle × pedestrian conflicts at crossings │ └── output/conflicts.csv ├── export_postgis.py # export tracks + conflicts → PostGIS schema │ ├── data/ │ ├── frames/ # extracted calibration frames │ ├── gcp/ # GCP shapefile (EPSG:4326, 11 points) │ ├── gcps.csv # GCP table (pixel + world coordinates) │ ├── homography.npy # 3×3 homography matrix (gitignored) │ ├── tracks.pkl # track history {id: [(x, y, frame)]} (gitignored) │ └── tracks.gpkg # GeoPackage: tracks + positions layers (gitignored) ├── output/ │ ├── car_crossings.csv │ ├── od_matrix.csv │ ├── speed_profile.csv + .png │ ├── heatmap.tif + heatmap_preview.png │ ├── conflicts.csv │ └── stats_*.png └── requirements.txt ``` ## 安装说明 ``` python -m venv .venv source .venv/bin/activate # Linux / macOS # .venv\Scripts\Activate.ps1 # Windows PowerShell pip install -r requirements.txt ``` **GPU(推荐):** ``` pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 pip install -r requirements.txt ``` ## 流水线 ### 步骤 1 – 帧提取 ``` python extract_frame.py "data/recording.avi" ``` 保存 `data/frames/frame_0000s.png`、`frame_0060s.png`、… 并将第 0 帧复制为 `frame_ref.png` 用于标定。 ### 步骤 2 – 地面控制点 填充 `data/gcps.csv`。列 `world_x_m` 和 `world_y_m` 是相对于交叉路口中心的以米为单位的坐标: ``` id,description,pixel_x,pixel_y,world_x_m,world_y_m,lon_wgs84,lat_wgs84 1,ne_entry_kerb,,,−12.5,38.2,, 2,se_lane_marking,,,42.1,5.0,, ``` 有关从 QGIS 获取坐标的信息,请参见**第 4 节**。 ### 步骤 3 – 单应性标定 ``` python calibrate.py ``` 显示参考帧并提示按顺序点击 GCP。确认后保存: - `data/homography.npy` – 单应性矩阵 - 像素坐标回写到 `data/gcps.csv` 目标重投影误差:平均值 < 0.5 m。数值高于 2 m 表示存在问题。 ### 步骤 4 – 检测与跟踪 ``` python detect_track.py python detect_track.py --model yolov8s.pt --conf 0.30 --device 0 ``` 输出: - `data/tracks.pkl` – 世界坐标系下的轨迹历史 - `data/tracks_annotated.mp4` – 标注后的视频 ### 步骤 5 – GIS 导出 编辑 `export_geo.py`:将 `REF_X_SJTSK` 和 `REF_Y_SJTSK` 设置为交叉路口中心的实际 S-JTSK 坐标(见第 4 节)。 ``` python export_geo.py ``` `data/tracks.gpkg` 包含两个图层: - **tracks** – 每辆车一条 LineString(速度、类别、时间戳) - **positions** – 每次检测为一个 Point ### 步骤 6 – 分析模块 独立运行任何模块: ``` python od_matrix.py # origin–destination matrix python speed_profile.py # speed by phase python heatmap.py # movement density GeoTIFF python pedestrian_conflicts.py # vehicle × pedestrian conflicts (full video) python spatial_stats.py # combined visualisations ``` ### 步骤 7 – PostGIS 导出 ``` python export_postgis.py --db gis --user postgres --drop ``` 在 EPSG:4326 中创建带有空间索引的 `roundabout` 模式以及 `tracks`、`positions`、`conflicts` 表。有关连接选项,请参见 `export_postgis.py --help`。 ## 从 QGIS 获取 GCP 坐标 ### QGIS(推荐 – 亚米级精度) 1. 打开 QGIS → 项目 → 属性 → CRS → 设置为 **EPSG:5514**(S-JTSK/Krovak East North) 2. 添加正射影像底图(WMS/WMTS): - ČÚZK 正射影像:`https://ags.cuzk.cz/arcgis1/services/ORTOFOTO/MapServer/WMSServer` 3. 导航至交叉路口 4. 从状态栏读取交叉路口中心坐标 → 这些即为 `REF_X_SJTSK`、`REF_Y_SJTSK` 5. 对于每个 GCP,在帧图像上点击并计算: - `world_x_m = gcp_easting − REF_X_SJTSK` - `world_y_m = gcp_northing − REF_Y_SJTSK` ### 坐标转换(Python) ``` from pyproj import Transformer t = Transformer.from_crs("EPSG:4326", "EPSG:5514", always_xy=True) x_sjtsk, y_sjtsk = t.transform(lon, lat) ``` ## 在 QGIS 中打开 tracks.gpkg 1. **图层 → 添加图层 → 添加矢量图层** → 选择 `data/tracks.gpkg` 2. 添加两个图层(tracks + positions) 3. 将项目 CRS 设置为 **EPSG:4326** 或 **EPSG:5514** 4. 要可视化速度:右键点击 tracks 图层 → 属性 → 符号化 → 渐变 → 字段 `speed_avg_kmh` ## 注意事项 - 单应性精度仅限于道路表面平面。在具有强烈透视畸变的帧边缘附近的车辆,其位置精度可能会降低。 - `speed_estimator.py` 会过滤掉低于 1 km/h(静止车辆)和高于 80 km/h(错误检测)的速度。 - FPS 通过 `cap.get(cv2.CAP_PROP_FPS)` 从视频中自动读取。 - `yolov8n.pt` 在首次运行时自动下载(约 6 MB)。`yolov8s.pt`(约 22 MB)提供更高的检测精度。
标签:ByteTrack, GeoJSON, GeoPackage, GeoTIFF, GIS, PostGIS, QGIS, Shapely, YOLOv8, 交通流量分析, 冲突检测, 凭据扫描, 单应性矩阵, 地理配准, 多边形ROI, 数据导出CSV, 智能交通系统, 热力图, 状态机, 环形交叉路口, 目标检测, 空间分析, 行人检测, 计算机视觉, 车辆追踪, 轨迹分析, 逆向工具, 速度估算