# 车牌识别系统 PlateRecApp > 基于 HyperLPR3 / MNN 的嵌入式 C++ 车牌识别平台,运行于树莓派5 + Ubuntu 24.04 > 版本: fix27 v44 | 最后更新: 2026-08-30 > Gogs 仓库: https://git.zhonjin.com:40717/steven_roc/PlateRecApp --- ## 系统概述 PlateRecApp 是一套面向工业园区/物流场站的全功能车牌识别与称重管理系统。支持多路 RTSP 视频流实时识别、飞书消息推送、MQTT 数据上报、Web 管理后台、登录认证、frpc 内网穿透管理等核心功能。 ### 核心能力 | 模块 | 功能说明 | |------|---------| | **车牌识别** | HyperLPR3 + MNN 推理引擎,支持低位/高位摄像头 ROI 裁剪推理 | | **视频流** | 4路独立 RTSP 视频流 (前/侧 × 进/出) + Web 端 ROI 手动调整 | | **飞书推送** | 进出站消息推送,支持携带重量信息,独立开关控制 (`g_feishu_enabled`) | | **MQTT** | 数据上报到 MQTT Broker,独立开关控制 (`g_mqtt_enabled`),v43 并行模式支持 | | **称重系统** | TCP 连接称重仪表,重量调度器 (promise/future 异步机制),预检测锁定 (fix27 v44) | | **Web 管理** | 登录认证、系统监控、日志管理、frpc 管理、SSH 密钥管理、ROI 调整 | | **站点锁** | 交替锁定机制 (AlternatingMerge),防止重复抓拍竞态,2小时超时清零 | | **时间窗口** | TIME_WINDOW 工单配额管理,支持 SQLite 持久化缓存 | | **并行同步** | fix24 v43 并行同步引擎,API创建工单+照片上传+飞书通知并行执行 | | **日志管理** | logrotate 自动清理,内存缓冲区+定时刷盘,系统指标历史记录 | | **安全认证** | bcrypt 密码哈希 + Session + CSRF 防护 + 速率限制 + 三级角色控制 | ## 系统架构 ``` ┌──────────────────────────────────────────────────────────────┐ │ PlateRecApp │ ├───────────┬───────────┬───────────┬──────────────────────────┤ │ 车牌识别 │ 重量调度 │ Web服务 │ 消息推送 │ │ HyperLPR3 │ 异步引擎 │ 认证+监控 │ 飞书 / MQTT (独立开关) │ │ +MNN推理 │ promise/ │ cpp-httplib│ │ │ │ future │ +SSL/HTTPS │ │ ├───────────┴───────────┴───────────┴──────────────────────────┤ │ 统一配置管理 (config.ini) │ ├──────────────────────────────────────────────────────────────┤ │ SQLite DB │ MQTT Client │ RTSP Capture (FFmpeg/DRM硬解) │ └──────────────────────────────────────────────────────────────┘ │ │ │ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ │ 飞书API │ │MQTT Brkr│ │ RTSP摄像头│ └─────────┘ └─────────┘ └─────────┘ ``` ### 数据流 ``` RTSP视频流 → 帧抓取(rtsp_capture) → ROI裁剪 → HyperLPR3推理 ↓ 车牌识别结果 → 去重检查 → 交替锁定检查 → 创建工单(API) ↓ ↓ 照片保存(SQLite记录) ← 联单编号(tb_num) ← API返回 ↓ 并行同步引擎(v43): ├── 照片上传 → API ├── 飞书通知 → 飞书Bot └── MQTT上报 → MQTT Broker ``` ## 运行环境 | 项目 | 要求 | |------|------| | **硬件** | 树莓派5 8G(兼容 Ubuntu-24.04 / Raspberry Pi OS) | | **编译器** | GCC 11+, C++17 | | **核心依赖** | OpenCV 4.x, MNN, HyperLPR3 SDK | | **其他依赖** | cJSON, cpp-httplib, bcrypt, ini-parser, FFmpeg (DRM硬解) | | **数据库** | SQLite3 | | **网络** | 飞书 API, MQTT Broker, RTSP 视频流, 称重仪表 (TCP) | ## 项目结构 ``` PlateRecApp/ ├── src/ # 源代码 │ ├── main.cpp # 主程序入口 (信号处理+主循环+清理) │ ├── common.cpp/h # 公共定义与全局变量 (枚举/结构体/常量) │ ├── config.cpp/h # 配置文件解析 (config.ini, 大小写不敏感) │ ├── plate_recognizer.cpp/h # 车牌识别核心 (HyperLPR3+MNN推理) │ ├── rtsp_capture.cpp/h # RTSP 视频流采集 (FFmpeg+DRM硬解) │ ├── web_server.cpp/h # Web 管理服务器 (cpp-httplib+SSL) │ ├── database.cpp/h # SQLite 数据库操作 (上传记录/时间窗口缓存) │ ├── feishu_client.cpp/h # 飞书消息推送客户端 (curl) │ ├── mqtt_client.cpp/h # MQTT 客户端 (mosquitto) │ ├── weight_dispatcher.cpp/h # 重量调度器 (promise/future异步) │ ├── weight_scale.cpp/h # 称重模块 (TCP连接仪表) │ ├── station_lock.cpp/h # 站点交替锁定机制 (内存+SQLite持久化) │ ├── system_monitor.cpp/h # 系统监控 (CPU/内存/温度/磁盘) │ ├── system_metrics_manager.cpp/h # 系统指标管理+历史记录 │ ├── log_manager.cpp/h # 日志管理+logrotate (内存缓冲+定时刷盘) │ ├── frpc_manager.cpp/h # frpc 内网穿透管理 (配置热更新+自动回滚) │ ├── ssh_manager.cpp/h # SSH 密钥管理 (authorized_keys读写) │ ├── network_client.cpp/h # 网络客户端 (API创建工单+照片上传) │ ├── utils.cpp/h # 工具函数 (帧去重/时间窗口/重试策略) │ ├── auth_api.cpp/h # 认证 API (登录/登出/状态) │ ├── auth_db.cpp/h # 认证数据库 (用户表+审计日志) │ ├── auth_session.cpp/h # 会话管理 (Session ID + CSRF Token) │ ├── auth_middleware.cpp/h # 认证中间件 (路由守卫+角色控制) │ ├── auth_crypto.cpp/h # 加密工具 (bcrypt 哈希+验证) │ ├── auth_rate_limiter.h # 速率限制 (防暴力破解) │ └── bcrypt/ # bcrypt 密码哈希库 ├── config/ # 配置示例 │ ├── config一号门.ini # 一号门配置模板 │ └── config二号门.ini # 二号门配置模板 ├── scripts/ # 部署脚本 │ ├── deploy.sh # 一键部署脚本 (systemd service) │ ├── reset_passwords.py # Web 管理密码重置工具 │ └── setup_frpc_sudoers.sh # frpc sudoers 配置 ├── third_party/ # 第三方依赖源码 │ ├── cJSON.c/h # JSON 解析 │ ├── cvxFont.cpp/h # OpenCV 中文字体 │ ├── httplib.h # cpp-httplib 头文件库 │ ├── hyper_lpr_sdk.h # HyperLPR3 SDK 头文件 │ ├── ini.c/h # INI 配置解析 │ └── md5ex1.c/h # MD5 工具 ├── assets/web/ # Web 前端资源 (HTML/CSS/JS) │ ├── index.html # 首页仪表盘 │ ├── login.html # 登录页面 │ ├── monitor.html # 系统监控 │ ├── frpc.html # frpc 管理 │ ├── ssh.html # SSH 密钥管理 │ ├── logs.html # 日志查看 │ ├── video.html # 视频预览 │ ├── weight.html # 称重记录 │ └── config.html # 配置管理 ├── sync_to_gogs.sh # Gogs 自动同步脚本 ├── CMakeLists.txt # CMake 构建配置 ├── CHANGELOG.md # 详细变更日志 └── README.md # 本文件 ``` ## 快速开始 ### 1. 克隆仓库 ```bash git clone https://git.zhonjin.com:40717/steven_roc/PlateRecApp.git cd PlateRecApp ``` ### 2. 编译 ```bash mkdir build && cd build cmake .. make -j4 ``` 编译产物: `build/PlateRecApp` 可执行文件 ### 3. 配置 ```bash # 复制配置模板并修改 cp config/config一号门.ini /opt/openAI/project/003.PlateRecAPP/config.ini # 编辑 config.ini 填入实际参数(见下方配置说明) ``` ### 4. 部署 ```bash sudo bash scripts/deploy.sh ``` deploy.sh 会自动: - 复制可执行文件到 `/opt/openAI/project/003.PlateRecAPP/` - 安装 systemd service 文件 - 设置文件权限 - 启动服务 ### 5. 验证 ```bash # 检查服务状态 sudo systemctl status PlateRecApp # 查看运行日志 sudo journalctl -u PlateRecApp -f # 访问 Web 管理 # http://<设备IP>:8080 (HTTP) 或 https://<设备IP>:8443 (HTTPS) ``` ## 配置文件详细说明 核心配置通过 `config.ini` 管理,支持以下配置段: ### [config] 主配置段 ```ini [config] project_name = 一号门站 # 项目名称(日志标识) point_number = P001 # 站点编号(API上报) throughway = 1 # 通道号 # RTSP 视频流地址(4路:前/侧 × 进/出) rtsp_url_front_in = rtsp://admin:xxx@192.168.1.101:554/stream1 rtsp_url_front_out = rtsp://admin:xxx@192.168.1.102:554/stream1 rtsp_url_side_in = rtsp://admin:xxx@192.168.1.103:554/stream1 rtsp_url_side_out = rtsp://admin:xxx@192.168.1.104:554/stream1 # API 配置 app_api = https://api.example.com/v1 app_key = your_app_key app_secret = your_app_secret # 运行模式 DEBUG_LOG = 0 # 0=正式运行, 1=调试模式(详细日志) TestFlag = 0 # 0=正式环境, 1=测试环境 wType = 1 # 称重类型 (1=类型A, 3=类型B) # 时间窗口与配额 TIME_WINDOW = 5 # 时间窗口(分钟),同一车牌5分钟内仅处理1次 MAX_PHOTO_GROUPS = 3 # 每侧最多保存照片组数 in_out_interval = 5 # 进出站间隔(分钟),交替锁定等待时间 # 车牌识别 PLATE_CONFIDENCE_THRESHOLD = 0.5 # 识别置信度阈值 PLATE_LOG_THRESHOLD = 0.3 # 日志记录阈值 # 交替锁定 AlternatingMerge = 1 # 1=启用交替锁定(推荐) # ROI 区域 (像素坐标) roi_in_x = 100 roi_in_y = 200 roi_in_w = 800 roi_in_h = 600 roi_in_enabled = 1 roi_out_x = 100 roi_out_y = 200 roi_out_w = 800 roi_out_h = 600 roi_out_enabled = 1 roi_debug_enabled = 0 # 1=显示ROI调试框 # 硬件解码 hw_decode_mode = drm # auto/drm/soft hw_decode_device = /dev/dri/card0 # DRM设备路径 rtsp_transport = tcp # rtsp传输协议 # 文件清理 PhotoMaxCapacityMB = 2048 # 照片目录最大容量(MB),超出自动清理旧文件 LogRetentionDays = 30 # 日志保留天数 ``` ### [feishu] 飞书推送 ```ini [feishu] ENABLED = 1 # 1=启用飞书消息推送 APP_ID = cli_xxx # 飞书应用 App ID APP_SECRET = xxx # 飞书应用 App Secret CHAT_ID = oc_xxx # 目标群聊 Chat ID TIMEOUT_SECOND = 10 # HTTP 请求超时(秒) WarningSigns = 0 # 1=抑制紧急告警 ``` ### [mqtt] MQTT 推送 ```ini [mqtt] MQTT_ENABLED = 1 # 1=启用MQTT消息推送 MQTT_HOST = broker.example.com # MQTT Broker 地址 MQTT_PORT = 1883 # MQTT Broker 端口 MQTT_USER = user # 用户名 MQTT_PASS = password # 密码 MQTT_TOPIC = plate_rec/data # 发布主题 MQTT_CLIENT_ID = PlateRecApp_01 # 客户端ID PLATE_COLOR = 绿色 # 车牌颜色 VEHICLE_TYPE = 渣土车 # 车辆类型 ``` ### [weight] 称重系统 ```ini [weight] flagWeight = 1 # 飞书消息是否携带重量信息 weight_threshold_in = 500 # 进站重量阈值(kg),低于此值不触发称重 weight_threshold_out = 300 # 出站重量阈值(kg) default_entry_weight = 15000 # 默认进站重量(kg) default_exit_weight = 5000 # 默认出站空车重量(kg) weight_detection_time = 15 # 称重检测等待时间(秒) tcp_connect_timeout = 5 # TCP连接超时(秒) weight_server_ip = 192.168.1.200 # 称重仪表IP weight_server_port = 502 # 称重仪表端口 MAX_WEIGHT = 60000 # 最大有效重量(kg) STABLE_SAMPLE_COUNT = 5 # 稳定采样次数 STABLE_THRESHOLD_KG = 50 # 稳定判定阈值(kg) CANDIDATE_DATA_COUNT = 10 # 候选数据计数 MAX_UPLOAD_RETRIES = 3 # 最大上传重试次数 RETRY_DELAY_MS = 2000 # 重试间隔(毫秒) # 预检测锁定 (fix27 v44 P0) PRELOCK_THRESHOLD_KG = 5000 # 预检测阈值(kg),超过此值启动预锁定 # 设为0则禁用预检测 PRELOCK_STABLE_SAMPLES = 3 # 预检测稳定采样次数 (2-20) ``` ### [sync] 并行同步 ```ini [sync] enabled = 1 # 1=并行同步(v43), 0=串行同步(v41) reporter_timeout_sec = 30 # 上报超时(秒) weight_retry_max = 2 # 重量获取最大重试次数 weight_retry_interval_sec = 3 # 重量重试间隔(秒) tb_num_dedup_sec = 60 # 联单编号去重窗口(秒) weight_snapshot_max_age_sec = 60 # 重量快照最大年龄(秒) ``` ### [server] / [ssl] Web 服务 ```ini [server] ip = http://0.0.0.0:8080 # Web服务监听地址(自动解析端口) [ssl] enabled = 1 # 1=启用HTTPS cert_path = /path/to/cert.pem # SSL证书路径 key_path = /path/to/key.pem # SSL私钥路径 ``` ### [auth] 认证系统 ```ini [auth] enabled = 1 # 1=启用登录认证 db_path = data/auth.db # 认证数据库路径 ``` ### [system] 系统监控 ```ini [system] monitor_interval = 30 # 监控采样间隔(秒) temp_alert_threshold = 75 # 温度告警阈值(℃) cpu_alert_threshold = 85 # CPU使用率告警阈值(%) db_path = data/system_metrics.db # 指标数据库路径 history_retention_days = 30 # 历史记录保留天数 aggregation_retention_days = 365 # 聚合数据保留天数 flush_time = 02:00 # 每日刷盘时间 ``` ### [frpc] 内网穿透管理 ```ini [frpc] config_path = /etc/frpc/frpc.ini # frpc配置文件路径 backup_path = /opt/frpc_backup/ # 配置备份目录 protected_tunnels = web,ssh # 受保护的隧道(不可删除) restart_check_timeout = 5 # 重启后检查超时(秒) auto_rollback = 1 # 配置失败自动回滚 web_enabled = 1 # 启用frpc Web管理 admin_addr = 127.0.0.1 # admin API监听地址(仅本机) admin_port = 7400 # admin API端口 admin_user = admin # admin用户名 admin_password = xxx # admin密码 ``` ### [terminal] / [log] ```ini [terminal] ttyd_port = 7681 # ttyd Web终端端口 ttyd_credential = admin:admin # ttyd认证凭据 ttyd_max_clients = 3 # 最大连接数 ssh_keys_path = /root/.ssh/authorized_keys [log] enabled = 1 # 1=启用内存缓冲日志 log_file = /var/log/PlateRecApp.log # 日志文件路径 buffer_size_mb = 20 # 内存缓冲区大小(MB) flush_time = 02:00 # 每日刷盘时间 retention_days = 30 # 日志保留天数 redirect_stdout = 1 # 1=重定向stdout到日志 auto_flush_on_exit = 1 # 1=退出时自动刷盘 ``` ## Web 管理功能 | 功能 | 路径 | 权限 | 说明 | |------|------|------|------| | 首页仪表盘 | `/` | 所有用户 | 系统概览、最新抓拍、统计信息 | | 登录认证 | `/login` | 公开 | 超级管理员/管理员/普通用户三角色 | | 系统监控 | `/monitor` | 超级管理员 | CPU/内存/磁盘/温度实时监控 | | frpc 管理 | `/frpc` | 超级管理员 | 内网穿透服务配置+热更新 | | SSH 密钥 | `/ssh` | 超级管理员 | Web 端 SSH 公钥管理 | | 日志管理 | `/logs` | 超级管理员 | 在线查看 + logrotate | | ROI 调整 | `/roi` | 所有用户 | Web 端 4 路视频 ROI 手动调整 | | 视频预览 | `/video` | 公开 | 实时视频流预览 (MJPEG) | | 称重记录 | `/weight` | 公开 | 称重数据查询 | | 配置管理 | `/config` | 管理员 | 在线修改配置参数 | | 锁定管理 | `/locks` | 管理员 | 查看/清除交替锁定状态 | ## 账号与角色 | 角色 | 级别 | 用户名 | 密码 | 权限 | |------|------|--------|------|------| | 普通用户 | role=0 | zhonjin | zhonjin | 首页/视频/称重等基础页面 | | 管理员 | role=1 | - | - | 基础页面 + 配置/锁定管理 | | 超级管理员 | role=2 | admin | zhonjin188A | 所有页面(含系统/frpc/SSH/日志) | > ⚠️ 首次部署后务必通过 `scripts/reset_passwords.py` 修改默认密码 ## 安全规则 - ✅ 所有管理操作必须经过超级管理员登录认证 - ✅ bcrypt 密码哈希 + Session 管理 + CSRF Token 防护 - ✅ 速率限制 (Rate Limiter) 防暴力破解 - ✅ frpc admin API 仅允许本机 127.0.0.1 调用,禁止通过 frp 隧道暴露到公网 - ✅ HTTPS/SSL 支持 (可选) - ✅ 安全响应头: X-Frame-Options, X-Content-Type-Options, CSP 等 - ✅ 永久失败告警受飞书开关 (`g_feishu_enabled`) 控制 ## 自动同步到 Gogs 项目包含 `sync_to_gogs.sh` 脚本,支持自动同步代码到 Gogs 仓库。 ### 配置 Access Token 为安全起见,建议通过环境变量传递 Access Token: ```bash # 方式1: 导出环境变量(推荐) export GOGS_ACCESS_TOKEN="your_access_token_here" # 方式2: 直接在命令中指定 GOGS_ACCESS_TOKEN="xxx" bash sync_to_gogs.sh # 方式3: 使用默认值(脚本内已内置,但不推荐) bash sync_to_gogs.sh ``` ### 手动同步 ```bash bash sync_to_gogs.sh "commit message here" ``` ### Git 本地开发推送 ```bash # 配置 remote(已配置则跳过) git remote set-url origin "https://steven_roc:YOUR_TOKEN@git.zhonjin.com:40717/steven_roc/PlateRecApp.git" # 推送代码 git add -A git commit -m "your commit message" git push origin master ``` ## 版本历史 | 版本 | 日期 | 主要内容 | |------|------|---------| | **fix27 v44** | 2026-08-30 | 飞书消息携带重量、水印居中修复、MQTT修复、内存泄漏修复、共享摄像头方向修复、空指针保护 | | fix26 v44 | 2026-08-30 | 飞书/MQTT独立开关控制 | | fix25 v44 | 2026-08-30 | P0 预检测锁定优化 (prelock) | | fix24 v43 | 2026-08-30 | 并行同步引擎、系统指标历史、日志管理 | | fix24 v32-v41 | 2026-07~08 | Web管理、认证系统、frpc管理、SSH密钥 | | fix24 v21 | 2026-07-03 | P0 时间对齐 bug 修复 (fix24-v21) | | fix18 | 2026-07-06 | 重复抓拍竞态修复、4路视频流+Web ROI、MQTT合并主进程 | | fix17 | 2026-07-06 | 交替锁定2小时超时清零 | | V5 fix19 | 2026-06-25 | 基础版本 | 详细变更记录请查看 [CHANGELOG.md](CHANGELOG.md) ## 许可证 本项目为内部使用项目,未经授权不得外部分发。 ## 联系方式 - **作者**: steven_roc - **邮箱**: steven_roc@126.com - **Gogs**: https://git.zhonjin.com:40717/steven_roc/PlateRecApp