公交车站违停自动检测:视频AI与车牌识别取证系统实战

发布时间:2026/9/1 17:51:33
公交车站违停自动检测:视频AI与车牌识别取证系统实战 公共道路资源被违章车辆占用尤其是公交车站这种“即停即走”区域一直是城市交通治理的痛点。最近网传一段视频网约车司机把车停在公交车站和公交车驾驶员发生争执全程情绪激动最后被现场视频完整记录。这类事件多到不新鲜真正值得关注的是背后的技术问题——如果每个公交站都靠驾驶员自己下车去理论问题永远解决不完。这次我们来看一套可行的解法基于视频 AI 和车牌识别的公交车站占用检测与取证系统专门用于识别“非公交车辆违规停靠公交站”这一场景并自动生成证据链。这套项目思路的核心不是让公交车驾驶员当场和对方争执而是通过摄像头 本地推理服务实时识别进入公交站区域的车辆类型、停留时长、是否属于公交车一旦满足“非公交车 停留超时”两个条件就自动保存视频片段、抓拍关键帧、记录时间戳和车牌号形成一个可追溯的取证包。整个过程不依赖人工盯着屏幕也不需要驾驶员在冲突现场冒险沟通。本文会按本地部署实操的路线展开先说这套系统能做什么、硬件门槛大概在哪再给你一套可以跑通的环境准备和启动流程然后按“车辆检测 - 区域判定 - 停留计时 - 车牌识别 - 证据生成”的顺序做功能验证。最后我会单独讲清楚批量任务和 API 接口怎么接以及实际部署中常见的坑——端口冲突、显存不足、车牌识别不准、视频卡顿这些都怎么排查。如果你正在做智慧交通、安防摄像头、视频结构化、违规取证相关的项目或者你只是想知道“公交站被占用到底能不能自动检测”这篇文章可以直接收藏。1. 核心能力速览这套系统的完整名字可以叫“公交车站违章占用自动检测与视频取证系统”。不同团队的开源实现结构可能略有差异但核心流程基本一致视频流输入 - 车辆检测 - 车辆分类 - 区域停留判断 - 车牌识别 - 证据保存。能力项说明项目类型视频结构化分析 违章检测 自动取证主要功能公交站区域车辆检测、车型分类、停留超时判定、车牌识别、视频片段回传输入形式RTSP 摄像头流、本地视频文件、图片批量检测输出形式标注视频、抓拍图片、车牌文本、JSON 结构化记录硬件门槛可 CPU 推理但多路视频建议使用 NVIDIA GPU显存占用以视频路数和模型大小为准推荐模型目标检测模型如 YOLO 系 车牌 OCR 模型具体以项目实际集成为准启动方式命令行启动或 Docker Compose 启动可单独启动检测服务与 Web 服务是否支持 API支持可提供 HTTP 接口提交视频/图片并获取检测结果是否支持批量任务支持可批量处理历史视频文件也可对多路 RTSP 流做并行分析适合场景公交站台监控、公交专用道治理、停车场违停取证、历史视频翻查这里要说明一点不同 GitHub 开源项目的检测器版本、接口路径和模型权重差异很大下面所有代码示例给的是通用模板路径和端口需要按你实际拉取的项目替换。2. 适用场景与使用边界这套系统最大的价值在于把“人盯监控”变成“算法盯监控”。具体能解决以下问题公交站被网约车、出租车、私家车长时间占用时系统自动记录占用起止时间不需要公交驾驶员下车交涉。多路公交站同时监控时人工看不过来算法可以 7x24 小时不间断跑。事件发生后平台能直接导出“抓拍图 视频片段 车牌号 时间戳”四件套提供给管理方复核。对历史监控视频做批量回溯可以统计某个公交站的高频占用时段和车牌为现场执法和站点优化提供数据支持。不过也要说清楚边界。纯视觉方案存在几个天然限制摄像头视野固定遮挡严重时检测不到车。夜间、逆光、雨天对目标检测和车牌识别都有影响需要挑选合适的摄像头安装位置或加补光。系统只能证明“车停了”不能直接证明“驾驶员在斗气”或“车内是否有人”情绪冲突类细节还需要结合现场录音或人工复核。车辆分类公交车/网约车/私家车依赖模型训练数据极端情况下可能把一类车误判成另一类。合规使用方面要特别强调凡是涉及道路监控、车牌、行人面部信息必须在合法授权范围内使用只能在授权的测试环境、自有测试素材或已获得拍摄许可的路口/站台部署。不能把系统用于未经同意的个人车辆跟踪、扒取车牌库、公共或私域流量下的任意监控。发布和商用前需要确认符合当地关于公共区域视频采集和隐私保护的规定。人脸信息默认不进存储车牌数据访问要有权限控制。3. 环境准备与前置条件在动手部署之前把环境先梳理清楚。一套最小可运行的配置包括下面几部分。3.1 操作系统与基础软件操作系统Ubuntu 20.04 / 22.04 为最稳妥Windows 也可以跑但 Docker 和 CUDA 环境配置会麻烦一些。Python 版本3.8 到 3.10 之间具体以项目 requirements.txt 为准。Docker如果采用镜像启动需要安装 Docker 和 Docker Compose。3.2 显卡与推理加速如果只处理单路摄像头或少量历史视频CPU 推理也可以但速度会比较慢。对于多路 RTSP 流实时分析推荐NVIDIA GPU显存 6G 起步具体占用取决于目标检测模型的分辨率和批量大小。需要安装 NVIDIA 驱动、CUDA toolkit、cuDNN。如果使用 Docker 启动需要额外配置nvidia-container-toolkit。3.3 摄像头或测试视频准备阶段不需要真实现场摄像头用两段测试视频就够一段包含公交车停在公交站区域内的画面。一段包含社会车辆网约车/私家车在公交站临停或长停的画面。如果手头没有现场视频也可以先用公开的交通监控样例视频验证流程。3.4 磁盘与目录规划视频证据会占磁盘。规划目录时建议把输入、输出、模型分开放project/ ├── models/ # 检测模型与 OCR 模型权重 ├── inputs/ # 测试视频、历史视频 ├── outputs/ # 抓拍图、标注视频、JSON 结果 └── logs/ # 服务日志与任务日志4. 安装部署与启动方式下面给出两种启动方式命令行启动和 Docker 启动。无论用哪种先把项目代码拉下来然后安装依赖。4.1 克隆项目与安装依赖# 以通用项目路径为例实际仓库地址需要替换 git clone https://github.com/example/bus-station-monitor.git cd bus-station-monitor # 创建虚拟环境 python -m venv venv source venv/bin/activate # 安装依赖 pip install -r requirements.txt依赖安装如果很慢可以换国内 PyPI 镜像pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple4.2 命令行启动检测服务很多视频分析项目会提供一个 CLI 入口作用是读取一个视频文件或 RTSP 流输出检测结果。通用命令模板如下python detect.py \ --source ./inputs/test_car.mp4 \ --output ./outputs/ \ --model ./models/yolov8s_vehicle.pt \ --ocr-model ./models/plate_ocr.pth \ --zone-polygon [(100,200),(500,200),(500,600),(100,600)] \ --max-stay-seconds 60参数含义参数作用--source输入视频路径或 RTSP 地址--output结果输出目录--model车辆检测模型权重路径--ocr-model车牌识别模型权重路径--zone-polygon公交站区域多边形坐标需要根据实际画面标定--max-stay-seconds超过该秒数判定为长时间占用这里面的zone-polygon是最关键的一个参数它的坐标对应画面里公交站台的实际位置。你需要在画面上手动框一个区域把公交站允许即停即走的范围圈出来。区域标定越准误报越少。4.3 Docker 启动整套服务如果项目提供了docker-compose.yml可以一条命令启动检测服务和 Web 管理端docker compose up -d启动后访问 Web 管理端默认端口可能是 8080 或 7860具体看项目里的docker-compose.yml配置。如果页面打不开先检查容器状态docker compose ps日志查看方式docker compose logs -f4.4 端口冲突处理启动服务时如果出现端口被占用先找占用进程sudo lsof -i :8080然后换端口启动或者直接修改 docker-compose 中的端口映射services: app: ports: - 8081:80805. 功能测试与效果验证部署启动之后按下面顺序做功能测试。每项测试都给出测试目的、输入素材、操作步骤和判断标准方便直接对照检查。5.1 测试一车辆检测是否正常测试目的确认检测服务能识别画面里的车辆。输入素材一段公交站区域有车辆经过的普通视频。操作步骤运行检测命令输出目录里生成带标注框的视频。python detect.py \ --source ./inputs/station_sample01.mp4 \ --output ./outputs/test1/ \ --model ./models/yolov8s_vehicle.pt判断标准输出视频中车辆身上出现目标框框的类别标签正确公交车、小轿车、货车分类基本准确。常见失败画面里车没框出来优先调低检测置信度阈值或者换更大的模型权重。5.2 测试二公交站区域判定与停留计时测试目的确认“进入区域 - 离开区域 - 计算停留时长”这条链路能跑通。输入素材一辆社会车辆停在公交站区域内约 90 秒后离开。操作步骤在配置中设置--max-stay-seconds 60跑完整段视频。预期结果车辆进入区域后开始计时超过 60 秒触发“占用”事件输出 JSON 中包含{ event_id: evt_20250712_093001, plate: 京A12345, vehicle_type: sedan, enter_time: 2025-07-12 09:30:01, leave_time: 2025-07-12 09:31:31, stay_seconds: 90, violation: true }判断标准JSON 中stay_seconds与视频实际停车时长基本一致误差在 1 到 2 秒内。常见失败停留时间误差大通常是目标跟踪丢失导致。需要调小跟踪算法的丢失帧阈值或者多路摄像头画面之间做轨迹衔接。5.3 测试三公交车白名单豁免测试目的确认公交车停在站点不会被误判为违章。输入素材真实公交车进站上下客停留约 40 秒后离开。操作步骤保持相同配置运行视频。预期结果公交车在区域内停留不生成报警或者生成一条“合法停靠”记录且不打违规标签。判断标准vehicle_type识别为bus事件中violation为false。常见失败公交车被识别成普通客车说明车型分类模型训练数据不足需要补充样本微调。5.4 测试四车牌识别与夜间效果测试目的确认车牌 OCR 在白天和夜间都能出结果。输入素材白天车牌清晰的视频一段以及夜间或逆光视频一段。操作步骤单独跑车牌识别模块用两张抓拍图片做输入。预期结果白天车牌输出正确夜间只要车牌区域有补光也能输出大部分字符。import requests # 单张图片车牌识别接口示例 url http://127.0.0.1:8000/api/v1/plate/recognize files {image: open(./outputs/plate_shot.jpg, rb)} response requests.post(url, filesfiles, timeout30) print(response.json())判断标准字符识别准确率白天不低于 95%夜间不低于 80%具体数值以实际模型为准。常见失败夜间识别不出来优先检查摄像头红外补光其次考虑对车牌区域做超分辨率或亮度增强预处理。5.5 测试五证据链完整性测试目的确认一个完整的取证包是否包含抓拍图、视频片段、车牌、时间戳。输入素材一次完整的违章占用事件。操作步骤事件触发后查看输出目录。预期结果outputs/evt_20250712_093001/ ├── snapshot.jpg ├── clip.mp4 ├── plate.jpg ├── event.json └── raw_frames/判断标准五个文件都在event.json能正常解析clip.mp4覆盖了进站到出站的完整过程snapshot.jpg能看清车辆外观和车牌区域。常见失败视频片段被截断通常是存储写入速度跟不上推理速度需要降低保存视频的分辨率或帧率。6. 接口 API 与批量任务服务跑通后真正进入业务系统的是 API 和批量处理能力。这里分两块讲。6.1 HTTP API 调用检测服务通常提供两类接口文件上传分析和 RTSP 实时分析。文件上传接口通用调用模板import requests url http://127.0.0.1:8000/api/v1/video/analyze payload { zone_polygon: [[100, 200], [500, 200], [500, 600], [100, 600]], max_stay_seconds: 60, save_evidence: True } with open(./inputs/test_car.mp4, rb) as f: files {video: (./inputs/test_car.mp4, f, video/mp4)} response requests.post(url, datapayload, filesfiles, timeout300) print(response.json())返回结果结构示例{ task_id: 20250712_A001, events: [ { plate: 京A12345, vehicle_type: sedan, stay_seconds: 90, violation: true, evidence_dir: outputs/evt_20250712_093001/ } ], processed_frames: 1200, elapsed_seconds: 32.5 }RTSP 流接入模板import requests url http://127.0.0.1:8000/api/v1/stream/start payload { stream_url: rtsp://admin:password192.168.1.64:554/Streaming/Channels/101, zone_polygon: [[100, 200], [500, 200], [500, 600], [100, 600]], max_stay_seconds: 60 } response requests.post(url, jsonpayload, timeout30) print(response.json())需要注意RTSP 的 URL 里如果带密码不要在生产环境明文传到日志里。建议通过环境变量或密钥管理服务注入。6.2 批量处理历史视频批量任务的思路很简单把一批视频文件放到固定目录通过脚本遍历调用检测服务结果按视频名归档。import os import glob import requests import json input_dir ./inputs/history/ output_dir ./outputs/history/ api_url http://127.0.0.1:8000/api/v1/video/analyze video_list glob.glob(os.path.join(input_dir, *.mp4)) for video_path in video_list: video_name os.path.basename(video_path).replace(.mp4, ) with open(video_path, rb) as f: files {video: (video_path, f, video/mp4)} try: resp requests.post(api_url, filesfiles, timeout600) result resp.json() except Exception as e: print(f{video_name} 处理失败: {e}) continue # 每个视频结果单独保存 out_path os.path.join(output_dir, f{video_name}.json) with open(out_path, w, encodingutf-8) as fp: json.dump(result, fp, ensure_asciiFalse, indent2) print(f{video_name} 完成耗时 {result.get(elapsed_seconds)} 秒)批量处理要注意两点。第一任务要加失败重试机制单条视频解析失败不能中断整个任务队列。第二输出要和输入一一对应建议每条视频单独生成一个结果目录不要把所有事件的图片视频混在一起。6.3 批量任务队列设计如果处理几十上百路视频直接 for 循环不现实建议用消息队列做任务分发。最简单的方案是 Redis 简单 Worker任务生产者扫描视频目录把视频路径写入 Redis 队列 任务消费者从 Redis 取任务调用检测服务写结果伪代码import redis import json r redis.Redis(host127.0.0.1, port6379, db0) # 生产者 def push_task(video_path, zone_polygon): task {video_path: video_path, zone_polygon: zone_polygon} r.lpush(analysis_tasks, json.dumps(task)) # 消费者 def pop_task(): task_json r.rpop(analysis_tasks) if task_json: return json.loads(task_json) return None当检测服务不稳定时队列方案天然支持失败重试任务执行失败后重新放回队列末尾并记录重试次数。7. 资源占用与性能观察这部分直接决定你能同时接几路摄像头。先说观察方法再说影响因素。7.1 怎么看资源占用Linux 下用nvidia-smi看显存和 GPU 利用率nvidia-smi实时刷新nvidia-smi -l 2CPU 和内存占用top # 或者 htop7.2 影响性能的主要因素因素影响输入分辨率分辨率越高检测越慢。建议先用 1280x720 做目标检测车牌区域单独用 ROI 放大画面帧率公交站场景不需要每秒都检测抽帧到 5 FPS 或 10 FPS 足够检测模型大小YOLOv8n 和 YOLOv8x 推理耗时能差 5 到 10 倍车牌 OCR 频率不需要每帧都做 OCR只在车辆进站和出站两个时机各识别一次视频路数每增加一路 RTSP 流GPU 占用线性增加证据保存策略同时保存 MP4 和逐帧 JPEG 会大量消耗磁盘 IO按需选择7.3 降低资源占用的实践检测帧率与视频保存帧率分开。检测可以用 5 FPS保存的证据片段用 25 FPS。车辆未进入公交站区域时不启动车牌识别模块。如果 CPU 推理优先选择量化模型例如 TensorRT 或 ONNX 的 FP16 版本。多路摄像头共用同一个目标检测服务不要每路都单独启动一个模型实例。7.4 进程残留与端口占用检测服务异常退出后进程可能还占着显存或端口。排查方式ps aux | grep python kill -9 pid如果是在 Docker 里容器退出后 GPU 显存没释放重启容器前先确认没有残留容器docker ps -a8. 常见问题与排查方法问题现象可能原因排查方式解决方案依赖安装失败Python 版本不匹配或缺少编译工具查看错误日志确认 PIL/numpy/onnxruntime 等是否编译失败创建 Python 3.9 虚拟环境重新安装使用国内镜像源模型文件缺失权重未下载或路径配置错误检查 models 目录和启动参数按 README 下载对应权重或调整--model路径CUDA 不可用驱动版本过低或 PyTorch 的 CUDA 版本不匹配python -c import torch; print(torch.cuda.is_available())安装匹配的 CUDA 版本或回退 CPU 推理显存不足检测分辨率太大批量值过高nvidia-smi查看显存占用降低输入分辨率、批量值设为 1、压缩模型启动后页面打不开端口被占用或服务未启动检查服务日志和端口状态更换端口或重启服务API 调用超时单段视频推理时间过长检查视频时长和分辨率加大请求超时时间或改用异步任务接口批量任务卡住单条视频损坏或模型推理死锁查看任务日志定位卡住的任务增加任务级超时和失败跳过输出视频没有标注框检测置信度阈值过高查看结果 JSON 是否为空调低置信度阈值车牌识别结果乱码图像中有遮挡或字体模糊查看抓拍图车牌区域提高抓拍分辨率调整摄像头角度公交车被误判违章车型分类模型不准查看事件 JSON 的 vehicle_type补充公交车样本重新微调分类模型9. 最佳实践与使用建议从项目能被真正用到生产环境的角度下面这些建议很关键。9.1 第一次运行先小参数测试不要上来就接 10 路摄像头。先用 1 路视频流、低分辨率、单模型跑通整个链路确认事件能产生、证据能落盘、接口能返回结果再逐步加路数。9.2 保留一套最小可运行配置把一组合适的参数固化下来比如区域多边形坐标、置信度阈值、停留时长阈值、抽帧间隔写进一个配置文件。这样遇到问题可以快速复位。9.3 区域标定是误报率的关键公交站区域画太大路边临时停的车会被误报画太小真正停在站台里的车可能不在区域内。标定之后用 30 分钟以上的不同时段视频做回放验证。9.4 模型、素材、结果分目录管理模型的权重文件、输入素材、输出证据不能混在同一个目录。建议按本文第 3 节的目录结构长期运行下来找问题会快很多。9.5 批量任务要加日志和失败重试跑历史视频批量回溯时没有日志等于白跑。每条视频处理结束后至少输出一行结果摘要包含视频名、耗时、事件数、是否成功。2025-07-12 10:33:01 [INFO] station_001.mp4 完成耗时 45.2s事件 2 条 2025-07-12 10:33:47 [ERROR] station_002.mp4 失败OCR 服务超时9.6 接口服务要限制访问范围API 服务不要直接暴露在公网。如果必须提供外部访问至少加一层 Token 或 API Key 校验并限制来源 IP。车牌和视频证据信息敏感建议走内网访问日志里不要明文打印车牌之外的隐私字段。9.7 涉及人脸、车牌、版权素材时必须确认授权视频巡检测试永远使用自有素材或已授权的测试数据不要拿着系统去扫公共摄像头、抓取他人车辆信息或采集未授权的人脸数据。发布和商用之前确认系统符合相关隐私保护要求并向管理方报备部署点位和采集范围。10. 总结与下一步回到最初那个网约车司机和公交车驾驶员争论的案例。单次争执解决不了公交站被反复占用的问题真正有效的方案是把“人工争论”变成“自动记录”。这套基于视频检测和车牌识别的公交站占用取证系统最值得尝试的点在于只要把区域画好、停留时长阈值设好它能自动完成从车辆进站到证据打包的全过程一整天不需要人盯。最先应该验证的功能是第 5.2 节里的“区域判定 停留计时”。这一步通没通直接决定后续证据输出是否可信。最容易踩的坑有两个一是区域多边形标得不准二是停留计时误差太大。前者用真实画面反复调坐标后者从跟踪丢失上找原因。后续可以扩展的方向很明确多路摄像头跨镜跟踪、夜间低照度增强、占用时段统计分析、公交站违停高发时段预测、与现有交通管理平台对接。如果再把检测模型换成支持更多车型分类的版本还能覆盖更多违章场景。这个项目的路线基本就是当前智慧交通里“AI 巡检 自动取证”的标准套路。拿一段 10 分钟的历史视频先跑一遍你就能直观感受到这套系统的价值。建议收藏备用需要做公交站占用检测或类似违停取证项目时按这篇文章的流程走一遍就行。