INSTALL_RPI5.md 40 KB

PlateRecApp 树莓派5安装编译运行完整指南

适用平台: 树莓派 5 8G (BCM2712, Cortex-A76, aarch64)
操作系统: Ubuntu 24.04 LTS Server (aarch64)
项目版本: fix27 v44 | 2026-08-30
C++标准: C++17 | 编译器: GCC 13+
本文档持续更新


目录

  1. 系统准备
  2. 安装所有依赖
  3. 编译安装 MNN
  4. 安装 HyperLPR3 SDK
  5. 编译 PlateRecApp
  6. 部署运行
  7. 常见问题排查
  8. 性能优化建议

1. 系统准备

1.1 安装 Ubuntu 24.04

1.1.1 下载 Raspberry Pi Imager

从官方下载最新版本的 Raspberry Pi Imager:

平台 下载地址
Windows https://downloads.raspberrypi.org/imager/imager_latest.exe
macOS https://downloads.raspberrypi.org/imager/imager_latest.dmg
Linux (AppImage) https://downloads.raspberrypi.org/imager/imager_latest.appimage
Ubuntu (snap) sudo snap install rpi-imager

1.1.2 烧录 Ubuntu 24.04 Server

  1. 插入 microSD 卡(建议 64GB 以上,A2 等级,推荐 SanDisk Extreme)
  2. 打开 Raspberry Pi Imager
  3. 点击 CHOOSE DEVICE → 选择 Raspberry Pi 5
  4. 点击 CHOOSE OS → Other general-purpose OS → Ubuntu → Ubuntu Server 24.04 LTS (64-bit)
  5. 点击 CHOOSE STORAGE → 选择你的 microSD 卡

1.1.3 配置高级选项(重要)

点击右下角齿轮图标(或按 Ctrl+Shift+X)进入高级选项:

# 主机名
hostname: plate-rec

# 启用 SSH(必须!)
Enable SSH: ✅ Use password authentication

# 设置用户名和密码
Username: pi
Password: <your-password>

# WiFi 配置(如果需要无线连接)
Configure wireless LAN:
  SSID: YourWiFiName
  Password: YourWiFiPassword
  Wireless LAN country: CN

# 区域设置
Set locale settings:
  Time zone: Asia/Shanghai
  Keyboard layout: cn

1.1.4 首次启动配置

烧录完成后插入树莓派,接通电源启动。等待 1-2 分钟后通过 SSH 连接:

# 连接方式1: 通过主机名
ssh pi@plate-rec.local

# 连接方式2: 通过 IP 地址(在路由器管理页面查看)
ssh pi@192.168.x.x

# 首次登录,更新系统
sudo apt update && sudo apt upgrade -y
sudo reboot

⚠️ 注意: 树莓派5 的 Wi-Fi 支持 Wi-Fi 6 (802.11ac/ax),但强烈建议使用有线以太网连接以获得稳定的视频流传输。

1.1.5 扩展文件系统(如果使用较小容量的卡)

# Ubuntu 24.04 通常会自动扩展,如果没有:
sudo raspi-config
# 选择 Advanced Options → Expand Filesystem → 重启

1.2 系统更新与基础工具

# 更新系统到最新
sudo apt update && sudo apt upgrade -y

# 安装基础编译工具链
sudo apt install -y \
    build-essential \
    cmake \
    git \
    wget \
    curl \
    pkg-config \
    unzip \
    tree \
    htop \
    nano \
    net-tools \
    lsb-release

# 验证系统信息
uname -a
# 预期输出: Linux plate-rec 6.x.x xxx aarch64 GNU/Linux

cat /etc/os-release
# 预期输出: Ubuntu 24.04.x LTS (Noble Numbat)

gcc --version
# 预期输出: gcc (Ubuntu 13.x.x) 13.x.x

cmake --version
# 预期输出: cmake version 3.28.x

# 验证内存
free -h
# 预期输出: 约 7.8GB 可用

# 查看 CPU 信息
lscpu
# 预期: ARMv8 Processor rev 0 (v8l), 4 cores

1.3 配置静态IP(可选)

1.3.1 使用 Netplan 配置静态IP

Ubuntu 24.04 使用 Netplan 管理网络配置。

# 查看当前网络接口
ip link show
# 通常有线网卡为 eth0 或 end0

# 查看当前 Netplan 配置
cat /etc/netplan/50-cloud-init.yaml
# 或
ls /etc/netplan/

创建或编辑配置文件:

sudo nano /etc/netplan/01-static.yaml

写入以下内容(根据实际网卡名修改):

# /etc/netplan/01-static.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    end0:  # 树莓派5有线网卡名通常是 end0,用 ip link show 确认
      dhcp4: no
      addresses:
        - 192.168.1.100/24    # 修改为你需要的静态IP
      routes:
        - to: default
          via: 192.168.1.1    # 网关地址
      nameservers:
        addresses:
          - 223.5.5.5         # 阿里DNS
          - 8.8.8.8           # Google DNS

应用配置:

# 验证配置语法
sudo netplan try

# 确认无误后应用
sudo netplan apply

# 验证IP
ip addr show end0

1.3.2 配置 mDNS(可选)

如果需要通过 plate-rec.local 访问:

sudo apt install -y avahi-daemon
sudo systemctl enable avahi-daemon
sudo systemctl start avahi-daemon

2. 安装所有依赖

按以下顺序安装所有编译和运行依赖。所有命令均为精确的 apt 命令。

2.1 一键安装全部依赖(推荐)

sudo apt install -y \
    libopencv-dev \
    libavformat-dev \
    libavcodec-dev \
    libavutil-dev \
    libswscale-dev \
    libsqlite3-dev \
    libcurl4-openssl-dev \
    libssl-dev \
    libfreetype-dev \
    libcjson-dev \
    libmosquitto-dev \
    libmosquittopp-dev \
    libprotobuf-dev \
    protobuf-compiler \
    libcrypt-dev

2.2 分步安装(便于排查问题)

2.2.1 OpenCV 4.x(计算机视觉库)

sudo apt install -y libopencv-dev

# 验证
pkg-config --modversion opencv4
# 预期输出: 4.x.x(Ubuntu 24.04 默认提供 OpenCV 4.x)

# 检查头文件
pkg-config --cflags opencv4
# 应包含 -I/usr/include/opencv4

# 检查库
pkg-config --libs opencv4

说明: OpenCV 用于图像处理、ROI 裁剪、格式转换等。系统包约占用 200-300MB 磁盘空间。

2.2.2 FFmpeg(视频解码库,v43+ 核心依赖)

sudo apt install -y \
    libavformat-dev \
    libavcodec-dev \
    libavutil-dev \
    libswscale-dev

# 验证
pkg-config --modversion libavformat
pkg-config --modversion libavcodec
pkg-config --modversion libavutil
pkg-config --modversion libswscale

# 可选:安装 ffmpeg 命令行工具用于测试 RTSP 流
sudo apt install -y ffmpeg

说明: FFmpeg 用于 RTSP 视频流解码,支持 HEVC DRM 硬件解码和 H.264 软解。这是 v43 版本的核心新增依赖。

2.2.3 SQLite3(轻量级数据库)

sudo apt install -y libsqlite3-dev

# 验证
pkg-config --modversion sqlite3
# 预期输出: 3.x.x

# 可选:安装命令行工具
sudo apt install -y sqlite3

2.2.4 cURL + OpenSSL(网络/加密库)

sudo apt install -y libcurl4-openssl-dev libssl-dev

# 验证
pkg-config --modversion libcurl
pkg-config --modversion openssl

# 检查 cURL 支持 HTTPS
curl --version | grep -i https

2.2.5 FreeType2(字体渲染库)

sudo apt install -y libfreetype-dev

# 验证
pkg-config --modversion freetype2
# 预期输出: 2x.x.x

说明: FreeType2 用于在图像上绘制中文字符(通过 cvxFont 模块)。

2.2.6 cJSON(JSON 解析库)

sudo apt install -y libcjson-dev

# 验证
pkg-config --modversion cjson
# 预期输出: 1.7.x

# 检查头文件位置
dpkg -L libcjson-dev | grep cJSON.h
# 通常在 /usr/include/cjson/cJSON.h

2.2.7 MQTT(消息队列库)

sudo apt install -y libmosquitto-dev libmosquittopp-dev

# 验证
ls /usr/lib/aarch64-linux-gnu/libmosquitto*
ls /usr/lib/aarch64-linux-gnu/libmosquittopp*

# 检查头文件
ls /usr/include/mosquitto.h
ls /usr/include/mosquittopp.h

说明: mosquitto 是 C 库,mosquittopp 是 C++ 封装库。两者都需要安装。

2.2.8 Protobuf(协议缓冲区)

sudo apt install -y libprotobuf-dev protobuf-compiler

# 验证
protoc --version
# 预期输出: libprotoc 3.x.x

pkg-config --modversion protobuf

2.2.9 libcrypt(密码哈希库,fix24 认证系统)

sudo apt install -y libcrypt-dev

# 验证
ls /usr/lib/aarch64-linux-gnu/libcrypt.so
ls /usr/include/crypt.h

说明: libcrypt 提供 crypt_r() 函数用于 bcrypt 密码哈希。这是 fix24 认证系统的必要依赖。

2.3 验证所有依赖安装完成

# 一键验证脚本
echo "=== 依赖验证 ==="
pkg-config --modversion opencv4 && echo "✅ OpenCV" || echo "❌ OpenCV"
pkg-config --modversion libavformat && echo "✅ FFmpeg-libavformat" || echo "❌ FFmpeg-libavformat"
pkg-config --modversion libavcodec && echo "✅ FFmpeg-libavcodec" || echo "❌ FFmpeg-libavcodec"
pkg-config --modversion libavutil && echo "✅ FFmpeg-libavutil" || echo "❌ FFmpeg-libavutil"
pkg-config --modversion libswscale && echo "✅ FFmpeg-libswscale" || echo "❌ FFmpeg-libswscale"
pkg-config --modversion sqlite3 && echo "✅ SQLite3" || echo "❌ SQLite3"
pkg-config --modversion libcurl && echo "✅ cURL" || echo "❌ cURL"
pkg-config --modversion openssl && echo "✅ OpenSSL" || echo "❌ OpenSSL"
pkg-config --modversion freetype2 && echo "✅ FreeType2" || echo "❌ FreeType2"
pkg-config --modversion cjson && echo "✅ cJSON" || echo "❌ cJSON"
ls /usr/lib/aarch64-linux-gnu/libmosquitto.so && echo "✅ Mosquitto" || echo "❌ Mosquitto"
ls /usr/lib/aarch64-linux-gnu/libmosquittopp.so && echo "✅ Mosquittopp" || echo "❌ Mosquittopp"
protoc --version && echo "✅ Protobuf" || echo "❌ Protobuf"
ls /usr/lib/aarch64-linux-gnu/libcrypt.so && echo "✅ libcrypt" || echo "❌ libcrypt"
echo "=== 验证完成 ==="

3. 编译安装 MNN

MNN(Mobile Neural Network)是阿里巴巴开源的轻量级深度学习推理引擎,HyperLPR3 依赖 MNN 进行车牌检测与识别模型的推理。

3.1 克隆源码

cd ~
git clone https://github.com/alibaba/MNN.git
cd MNN

# 切换到稳定版本(推荐使用 2.9.x 或更高)
git checkout 2.9.6
# 或使用 master 分支
# git checkout master

3.2 编译(aarch64 专用参数)

cd ~/MNN
mkdir -p build && cd build

完整 CMake 配置命令及参数说明

cmake .. \
    -DCMAKE_BUILD_TYPE=Release \
    -DMNN_BUILD_SHARED_LIBS=ON \
    -DMNN_BUILD_CONVERTER=OFF \
    -DMNN_BUILD_DEMO=OFF \
    -DMNN_BUILD_TOOLS=OFF \
    -DMNN_BUILD_TRAIN=OFF \
    -DMNN_BUILD_QUANTOOLS=OFF \
    -DMNN_BUILD_MINIMAL=OFF \
    -DMNN_ARM82=ON \
    -DMNN_FP16=ON \
    -DMNN_OPENCL=OFF \
    -DMNN_VULKAN=OFF \
    -DMNN_METAL=OFF \
    -DMNN_USE_THREAD_POOL=ON \
    -DMNN_NUM_THREADS=4 \
    -DCMAKE_INSTALL_PREFIX=/usr/local

参数详细说明:

参数 值 说明
CMAKE_BUILD_TYPE Release 发布模式,启用 -O3 优化
MNN_BUILD_SHARED_LIBS ON 编译为动态库 (.so),减小程序体积
MNN_BUILD_CONVERTER OFF 不编译模型转换工具(节省编译时间和空间)
MNN_BUILD_DEMO OFF 不编译示例程序
MNN_BUILD_TOOLS OFF 不编译额外工具
MNN_BUILD_TRAIN OFF 不编译训练模块
MNN_BUILD_QUANTOOLS OFF 不编译量化工具
MNN_BUILD_MINIMAL OFF 不启用最小化构建
MNN_ARM82 ON 关键参数!启用 ARMv8.2 fp16 指令集加速,树莓派5 Cortex-A76 支持
MNN_FP16 ON 启用半精度浮点运算,配合 ARM82 大幅提升推理速度
MNN_OPENCL OFF 不使用 OpenCL GPU 加速(树莓派5 支持有限)
MNN_VULKAN OFF 不使用 Vulkan GPU 加速
MNN_METAL OFF Apple Metal 专用,Linux 不需要
MNN_USE_THREAD_POOL ON 启用线程池,提升多核利用率
MNN_NUM_THREADS 4 线程数设为 4,匹配树莓派5的4个核心
CMAKE_INSTALL_PREFIX /usr/local 安装到 /usr/local 目录

开始编译

# 使用 4 核并行编译(树莓派5 有 4 个核心)
make -j4

# 编译过程约需 5-15 分钟,取决于 microSD 卡速度
# 使用 SSD/USB 会更快

# 安装
sudo make install

# 更新动态链接库缓存
sudo ldconfig

3.3 验证安装

# 检查头文件
ls /usr/local/include/MNN/
# 应包含: Interpreter.hpp, MNNDefine.h, MNNForwardType.h 等

# 检查库文件
ls /usr/local/lib/libMNN*
# 应包含: libMNN.so, libMNN*.so 等

# 使用 pkg-config 验证(如果 MNN 提供了 .pc 文件)
pkg-config --libs MNN 2>/dev/null || echo "MNN 无 pkg-config 文件,使用手动路径"

# 验证库是否可加载
ldconfig -p | grep MNN

4. 安装 HyperLPR3 SDK

HyperLPR3 是开源车牌识别库,提供车牌检测、字符识别的预训练模型和推理接口。

4.1 预编译 SDK 安装(推荐)

4.1.1 下载 SDK

cd /root/PlateRecApp
mkdir -p hyperlpr3
cd hyperlpr3

# 下载预编译的 aarch64 Linux SDK
# 方式1: 从 GitHub Releases 下载
wget https://github.com/nicklasxyz/hyperlpr3/releases/download/v0.1.0/hyperlpr3-linux-aarch64.tar.gz

# 方式2: 如果上述链接不可用,从 HyperLPR 官方获取
# https://github.com/nicklasxyz/HyperLPR3
# 注意:需要根据实际发布版本调整 URL

# 方式3: 从自有服务器下载(如果有预编译版本)
# wget http://your-server/hyperlpr3-linux-aarch64.tar.gz

4.1.2 解压并安装

cd /root/PlateRecApp/hyperlpr3

# 解压
tar -xzf hyperlpr3-linux-aarch64.tar.gz

# 预期目录结构
tree /root/PlateRecApp/hyperlpr3/

标准目录结构:

hyperlpr3/
├── include/                 # 头文件目录
│   ├── hyperlpr3.h          # C API 头文件
│   └── hyper_lpr_sdk.h     # SDK 接口头文件
├── lib/                     # 库文件目录
│   ├── libhyperlpr3.so      # 主库(动态链接)
│   └── libMNN.so            # MNN 运行时库(如果未单独安装 MNN)
├── models/                  # 模型文件目录
│   ├── det/                 # 车牌检测模型
│   │   └── det.mnn         # MNN 格式检测模型
│   ├── rec/                 # 字符识别模型
│   │   └── rec.mnn         # MNN 格式识别模型
│   └── seg/                 # 分割模型(如果有)
│       └── seg.mnn
└── README.md

4.1.3 运行时库路径配置

# 添加 HyperLPR3 库路径到系统动态链接器
echo "/root/PlateRecApp/hyperlpr3/lib" | sudo tee /etc/ld.so.conf.d/hyperlpr3.conf

# 更新动态链接库缓存
sudo ldconfig

# 验证库是否被识别
ldconfig -p | grep hyperlpr3

4.2 源码编译安装(备选)

如果预编译 SDK 不可用,可自行编译:

cd ~
git clone https://github.com/nicklasxyz/HyperLPR3.git
cd HyperLPR3

# 编译(需要已安装 MNN)
mkdir build && cd build
cmake .. \
    -DCMAKE_BUILD_TYPE=Release \
    -DMNN_DIR=/usr/local \
    -DCMAKE_INSTALL_PREFIX=/root/PlateRecApp/hyperlpr3

make -j4
make install

⚠️ 注意: 源码编译需要确保 MNN 已正确安装,且需要下载模型文件放到 models/ 目录。


5. 编译 PlateRecApp

5.1 克隆代码

cd /root
git clone https://git.zhonjin.com:40717/steven_roc/PlateRecApp.git
cd PlateRecApp

# 如果使用已有代码,直接进入目录
# cd /root/PlateRecApp

# 查看当前版本
head -5 README.md

5.2 检查项目结构

确认以下文件和目录存在:

# 检查源码目录
ls src/
# 应包含: main.cpp, config.cpp, plate_recognizer.cpp, web_server.cpp 等

# 检查第三方依赖
ls third_party/
# 应包含: cvxFont.cpp, cvxFont.h, httplib.h, ini.c, ini.h, md5ex1.c, md5ex1.h

# 检查 HyperLPR3 SDK
ls hyperlpr3/include/ hyperlpr3/lib/
# 应包含头文件和库文件

# 检查 CMakeLists.txt
ls CMakeLists.txt

5.3 CMake 配置

cd /root/PlateRecApp
mkdir -p build && cd build

cmake .. \
    -DCMAKE_BUILD_TYPE=Release \
    -DUSE_STATIC_LIBS=OFF \
    -DCMAKE_CXX_FLAGS="-march=armv8.2-a+fp16" \
    -DCMAKE_C_FLAGS="-march=armv8.2-a+fp16"

CMake 参数说明:

参数 值 说明
CMAKE_BUILD_TYPE Release 发布模式,启用 -O3 优化 + strip
USE_STATIC_LIBS OFF 使用动态链接,减小程序体积
CMAKE_CXX_FLAGS -march=armv8.2-a+fp16 启用 ARMv8.2 fp16 指令集
CMAKE_C_FLAGS -march=armv8.2-a+fp16 同上,用于 C 文件

注意: CMake 配置阶段会检查所有依赖。如果某个依赖缺失,会报 FATAL_ERROR。请根据错误提示安装缺失的库。

CMake 预期输出(关键信息):

-- ========================================
-- 项目配置信息:
--   项目名称: HyperLPR3-LinuxAPP
--   项目版本: 1.0.0
--   C++ 标准: C++17
--   构建类型: Release
--   使用静态库: OFF
-- ----------------------------------------
-- 库路径信息:
--   OpenCV: /usr/include/opencv4
--   HyperLPR3: /root/PlateRecApp/hyperlpr3/include
--   cJSON 库: /usr/lib/aarch64-linux-gnu/libcjson.so
--   libcrypt: /usr/lib/aarch64-linux-gnu/libcrypt.so
-- ========================================

5.4 编译

cd /root/PlateRecApp/build

# 使用 4 核并行编译
make -j4

# 编译过程约需 3-10 分钟
# Release 模式下会自动 strip 符号表

# 如果编译出错,可查看详细错误
make VERBOSE=1

5.5 验证编译产物

# 检查可执行文件
ls -lh /root/PlateRecApp/build/PlateRecApp
# 应为一个可执行文件

# 查看文件信息
file /root/PlateRecApp/build/PlateRecApp
# 预期: ELF 64-bit LSB executable, ARM aarch64

# 查看动态链接依赖
ldd /root/PlateRecApp/build/PlateRecApp
# 检查所有依赖库都能找到(无 "not found")

# 快速测试运行(会因缺少 config.ini 报错,但不应报库缺失)
./PlateRecApp --help 2>&1 || true

关键验证: ldd 输出中不应出现 not found,否则需要安装缺失的库。


6. 部署运行

6.1 目录结构

生产环境推荐以下目录结构:

/root/PlateRecApp/              # 项目根目录
├── PlateRecApp                 # 编译产物(可执行文件)或 build/PlateRecApp
├── config.ini                  # 主配置文件
├── hyperlpr3/                  # HyperLPR3 SDK
│   ├── include/
│   ├── lib/
│   └── models/
├── data/                       # 运行时数据目录
│   ├── plate_rec.db            # SQLite 数据库
│   └── auth.db                 # 认证数据库
├── fonts/                      # 字体文件目录
│   └── font.ttf               # 中文字体文件
├── html/                       # Web 前端文件(如果有)
├── logs/                       # 日志目录
│   └── plate_rec.log
├── scripts/                    # 脚本目录
└── src/                        # 源码目录

创建必要目录:

cd /root/PlateRecApp
mkdir -p data fonts html logs scripts

# 复制编译产物到项目根目录(可选)
cp build/PlateRecApp ./PlateRecApp
chmod +x ./PlateRecApp

6.2 config.ini 配置

创建配置文件:

cat > /root/PlateRecApp/config.ini << 'EOF'
[system]
# 设备名称
device_name=plate-rec-01
# 日志级别: DEBUG, INFO, WARN, ERROR
log_level=INFO
# 日志文件路径
log_path=/root/PlateRecApp/logs/plate_rec.log
# 日志最大大小(MB)
log_max_size=50
# 日志保留份数
log_backup_count=3

[rtsp]
# RTSP 视频流地址(支持最多4路)
# 格式: rtsp://username:password@ip:port/stream
url1=rtsp://admin:password@192.168.1.100:554/Streaming/Channels/101
url2=
url3=
url4=
# 每路流的 ROI 区域 (x,y,w,h) 逗号分隔
roi1=0,0,1920,1080
roi2=0,0,1920,1080
roi3=0,0,1920,1080
roi4=0,0,1920,1080
# 解码模式: auto, drm(HEVC硬解), cpu(H264软解)
decode_mode=auto
# 帧跳过间隔(每N帧处理1帧)
frame_skip=3

[plate_recognition]
# 置信度阈值 (0.0-1.0)
confidence_threshold=0.5
# 模型路径
model_dir=/root/PlateRecApp/hyperlpr3/models

[database]
# SQLite 数据库路径
db_path=/root/PlateRecApp/data/plate_rec.db

[web_server]
# Web 管理后台端口
port=8080
# 静态文件目录
html_dir=/root/PlateRecApp/html
# 超级管理员账号(首次启动会自动创建)
admin_user=admin
admin_password=zhonjin188A

[feishu]
# 飞书推送开关
enabled=false
# 飞书 Webhook URL
webhook_url=https://open.feishu.cn/open-apis/bot/v2/hook/your-hook-id
# 推送消息模板
entry_msg=🟢 进站 | 车牌: {plate} | 时间: {time}
exit_msg=🔴 出站 | 车牌: {plate} | 时间: {time}

[mqtt]
# MQTT 上报开关
enabled=false
# Broker 地址
broker=tcp://192.168.1.200:1883
# 客户端 ID
client_id=plate_rec_01
# 主题
topic=plate_recognition/result
# 用户名密码(如果有)
username=
password=

[station_lock]
# 站点锁定超时(秒)
lock_timeout=120

[frpc]
# frpc 可执行文件路径
frpc_path=/usr/local/bin/frpc
# frpc 配置文件路径
frpc_config_path=/root/PlateRecApp/frpc.toml
# frpc admin API 端口(仅允许 127.0.0.1 访问)
admin_port=7400
EOF

⚠️ 重要: 请根据实际环境修改 RTSP 地址、飞书 Webhook、MQTT Broker 等配置。

6.3 systemd service 配置

创建系统服务文件:

sudo tee /etc/systemd/system/plate-rec.service << 'EOF'
[Unit]
Description=PlateRecApp - License Plate Recognition Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
Group=root
WorkingDirectory=/root/PlateRecApp
ExecStart=/root/PlateRecApp/PlateRecApp
Restart=always
RestartSec=5
StartLimitIntervalSec=60
StartLimitBurst=3

# 环境变量
Environment=LD_LIBRARY_PATH=/root/PlateRecApp/hyperlpr3/lib:/usr/local/lib
Environment=MNN_NUM_THREADS=4

# 资源限制
LimitNOFILE=65536
LimitNPROC=4096
MemoryMax=2G
CPUQuota=300%

# 安全加固
NoNewPrivileges=yes
ProtectSystem=strict
ReadWritePaths=/root/PlateRecApp
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes

# 日志
StandardOutput=journal
StandardError=journal
SyslogIdentifier=plate-rec

[Install]
WantedBy=multi-user.target
EOF

服务文件关键配置说明:

配置项 值 说明
LD_LIBRARY_PATH hyperlpr3/lib + /usr/local/lib 确保能找到 MNN 和 HyperLPR3 动态库
MNN_NUM_THREADS 4 MNN 推理线程数,匹配树莓派5核心数
LimitNOFILE 65536 最大打开文件数(4路 RTSP 流需要较多 fd)
MemoryMax 2G 内存上限,防止 OOM
CPUQuota 300% CPU 使用上限(4 核 = 400%,留 1 核给系统)
RestartSec 5 崩溃后 5 秒重启
StartLimitBurst 3 60秒内最多重启 3 次,防止频繁崩溃

6.4 启动和验证

# 重新加载 systemd 配置
sudo systemctl daemon-reload

# 启用开机自启
sudo systemctl enable plate-rec

# 启动服务
sudo systemctl start plate-rec

# 检查服务状态
sudo systemctl status plate-rec

# 预期输出:
# ● plate-rec.service - PlateRecApp - License Plate Recognition Service
#      Loaded: loaded (/etc/systemd/system/plate-rec.service; enabled)
#      Active: active (running) since ...

验证运行:

# 检查进程
ps aux | grep PlateRecApp

# 检查端口监听
ss -tlnp | grep 8080
# 或
netstat -tlnp | grep 8080

# 检查数据库文件是否创建
ls -la /root/PlateRecApp/data/

# 测试 Web 管理后台
curl -s http://localhost:8080/ | head -20

# 检查日志输出
sudo journalctl -u plate-rec -f --no-pager -n 50

6.5 日志查看

# 实时查看服务日志
sudo journalctl -u plate-rec -f

# 查看最近 100 行日志
sudo journalctl -u plate-rec -n 100 --no-pager

# 查看今天的日志
sudo journalctl -u plate-rec --since today --no-pager

# 查看应用自身日志文件
tail -f /root/PlateRecApp/logs/plate_rec.log

# 查看应用日志(带颜色)
tail -f /root/PlateRecApp/logs/plate_rec.log | grep -E "ERROR|WARN" --color=always

# 配置 logrotate 自动清理日志(如果应用未自带)
sudo tee /etc/logrotate.d/plate-rec << 'LOGEOF'
/root/PlateRecApp/logs/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 0644 root root
    postrotate
        systemctl reload plate-rec 2>/dev/null || true
    endscript
}
LOGEOF

常用运维命令:

# 重启服务
sudo systemctl restart plate-rec

# 停止服务
sudo systemctl stop plate-rec

# 禁用开机自启
sudo systemctl disable plate-rec

# 查看服务资源使用
systemctl status plate-rec
systemd-cgtop

# 查看 crash 日志
sudo journalctl -u plate-rec --since "1 hour ago" -p err --no-pager

7. 常见问题排查

编译类问题

Q1: CMake 报错 "Could NOT find OpenCV"

原因: OpenCV 开发包未安装。

解决:

sudo apt install -y libopencv-dev
# 如果仍有问题,检查 pkg-config
pkg-config --modversion opencv4

Q2: CMake 报错 "Could NOT find CURL" 或 "Failed to find curl.h"

原因: cURL 开发包未安装。

解决:

sudo apt install -y libcurl4-openssl-dev

Q3: 编译报错 "hyper_lpr_sdk.h: No such file or directory"

原因: HyperLPR3 SDK 未正确安装到 hyperlpr3/ 目录。

解决:

ls /root/PlateRecApp/hyperlpr3/include/hyper_lpr_sdk.h
# 如果不存在,重新安装 HyperLPR3 SDK(参见第4节)

Q4: 链接报错 "undefined reference to `MNN::Interpreter::createFromFile'"

原因: MNN 未安装或链接器找不到 MNN 库。

解决:

# 检查 MNN 是否安装
ls /usr/local/lib/libMNN.so

# 如果不存在,重新编译安装 MNN(参见第3节)
# 如果存在但找不到,更新 ldconfig
echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/mnn.conf
sudo ldconfig

Q5: 链接报错 "cannot find -lmosquittopp" 或 "cannot find -lcjson"

原因: 对应的开发包未安装。

解决:

sudo apt install -y libmosquittopp-dev libcjson-dev

Q6: 编译报错 "'crypt_r' was not declared in this scope"

原因: libcrypt-dev 未安装。

解决:

sudo apt install -y libcrypt-dev

Q7: 编译报错 "libavformat/libavcodec 相关头文件找不到"

原因: FFmpeg 开发包未安装。

解决:

sudo apt install -y libavformat-dev libavcodec-dev libavutil-dev libswscale-dev
pkg-config --modversion libavformat

Q8: 链接阶段 OOM (Out of Memory)

原因: 树莓派5 8G 内存在链接大型项目时可能不够(特别是 Debug 模式)。

解决:

# 方法1: 增加 swap
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# 方法2: 使用单线程编译
make -j1

# 方法3: 使用 Release 模式(体积更小,内存占用更少)
cmake -DCMAKE_BUILD_TYPE=Release ..

运行时问题

Q9: 启动报错 "error while loading shared libraries: libMNN.so: cannot open shared object file"

原因: 动态链接器找不到 MNN 库。

解决:

# 确认库存在
ls /usr/local/lib/libMNN.so

# 添加路径
echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/mnn.conf
sudo ldconfig

# 验证
ldconfig -p | grep MNN

Q10: 启动报错 "error while loading shared libraries: libhyperlpr3.so"

原因: HyperLPR3 库路径未配置。

解决:

echo "/root/PlateRecApp/hyperlpr3/lib" | sudo tee /etc/ld.so.conf.d/hyperlpr3.conf
sudo ldconfig
ldconfig -p | grep hyperlpr3

Q11: RTSP 流无法连接,日志报 "Failed to open RTSP stream"

原因: 网络不通、RTSP 地址错误或摄像头未开启。

解决:

# 测试网络连通性
ping 192.168.1.100

# 使用 ffmpeg 测试 RTSP 流
ffmpeg -rtsp_transport tcp -i "rtsp://admin:password@192.168.1.100:554/Streaming/Channels/101" -frames:v 1 test.jpg

# 检查 config.ini 中 RTSP 地址是否正确
grep "url1=" /root/PlateRecApp/config.ini

Q12: Web 管理后台无法访问(浏览器打不开 8080 端口)

原因: 服务未启动、端口被占用或防火墙阻止。

解决:

# 检查服务状态
sudo systemctl status plate-rec

# 检查端口
ss -tlnp | grep 8080

# 检查防火墙
sudo ufw status
sudo ufw allow 8080/tcp

# 检查是否有端口冲突
sudo lsof -i :8080

Q13: 飞书推送不工作

原因: 配置错误或网络问题。

解决:

# 检查配置
grep -A5 "\[feishu\]" /root/PlateRecApp/config.ini

# 手动测试 Webhook
curl -X POST "https://open.feishu.cn/open-apis/bot/v2/hook/your-hook-id" \
  -H "Content-Type: application/json" \
  -d '{"msg_type":"text","content":{"text":"test"}}'

# 查看日志中飞书相关错误
journalctl -u plate-rec | grep -i feishu

Q14: MQTT 连接失败

原因: Broker 地址错误、网络不通或认证失败。

解决:

# 检查 Broker 连通性
mosquitto_sub -h 192.168.1.200 -p 1883 -t "test" -d

# 检查配置
grep -A10 "\[mqtt\]" /root/PlateRecApp/config.ini

# 查看 MQTT 相关日志
journalctl -u plate-rec | grep -i mqtt

Q15: 程序运行一段时间后崩溃 (Segmentation fault)

原因: 可能是内存泄漏、RTSP 断流重连问题或模型加载异常。

解决:

# 查看崩溃前的日志
journalctl -u plate-rec -p err --since "10 min ago"

# 启用 core dump
sudo sysctl -w kernel.core_pattern=/root/PlateRecApp/logs/core.%e.%p

# 使用 Debug 模式编译以获取更多信息
cd /root/PlateRecApp/build
cmake -DCMAKE_BUILD_TYPE=Debug ..
make -j4

# 检查内存使用
htop
free -h

# systemd 会自动重启服务(Restart=always)

Q16: 车牌识别率低

原因: 摄像头角度、光线、ROI 设置或置信度阈值问题。

解决:

# 调整 ROI 区域(通过 Web 管理后台或修改 config.ini)
# roi1=x,y,width,height

# 降低置信度阈值(可能增加误识别)
# confidence_threshold=0.3

# 检查摄像头画面质量
ffmpeg -rtsp_transport tcp -i "rtsp://..." -frames:v 1 snapshot.jpg

# 检查模型文件是否完整
ls -la /root/PlateRecApp/hyperlpr3/models/

Q17: 数据库文件权限问题

原因: 服务以 root 用户运行时创建的数据库文件,其他用户无法访问。

解决:

# 确保 data 目录权限正确
ls -la /root/PlateRecApp/data/

# 修复权限
chmod 644 /root/PlateRecApp/data/*.db
chown root:root /root/PlateRecApp/data/*.db

Q18: config.ini 解析失败

原因: 配置文件格式错误(如包含多余空格、编码问题)。

解决:

# 检查配置文件编码
file /root/PlateRecApp/config.ini
# 应为: ASCII text 或 UTF-8 text

# 检查语法(简单验证)
cat /root/PlateRecApp/config.ini | grep -v "^#" | grep -v "^$"

# 重新创建配置文件(参考 6.2 节)

Q19: frpc 管理功能报错 "Connection refused"

原因: frpc 未安装或 admin API 端口未开放。

解决:

# 检查 frpc 是否安装
which frpc
ls -la /usr/local/bin/frpc

# 检查 frpc 配置文件
cat /root/PlateRecApp/frpc.toml

# 测试 admin API(仅允许 127.0.0.1)
curl http://127.0.0.1:7400/api/status

# 安全提示: frpc admin API 禁止通过 frp 隧道暴露到公网!

Q20: 登录认证系统无法登录

原因: 认证数据库未初始化或密码错误。

解决:

# 检查认证数据库
ls -la /root/PlateRecApp/data/auth.db

# 删除认证数据库让系统重新创建(会丢失用户数据)
# rm /root/PlateRecApp/data/auth.db
# sudo systemctl restart plate-rec

# 默认超级管理员账号
# 用户名: admin
# 密码: zhonjin188A(在 config.ini 中配置)

Q21: 温度过高导致降频

原因: 树莓派5 在高负载下温度可达 80°C+,触发降频保护。

解决:

# 查看当前温度
vcgencmd measure_temp
# 或
cat /sys/class/thermal/thermal_zone0/temp

# 查看是否降频
vcgencmd get_throttled
# 0x0: 正常, 非0: 有降频/ throttling

# 安装散热片/风扇
# 推荐使用主动散热(风扇)方案

Q22: systemd 服务启动失败 "Exit code: 127"

原因: 可执行文件路径错误或动态库找不到。

解决:

# 检查可执行文件路径
ls -la /root/PlateRecApp/PlateRecApp

# 手动运行查看错误
cd /root/PlateRecApp && ./PlateRecApp

# 检查 LD_LIBRARY_PATH 配置
grep LD_LIBRARY_PATH /etc/systemd/system/plate-rec.service

# 确认所有动态库都能找到
ldd /root/PlateRecApp/PlateRecApp | grep "not found"

Q23: 系统时间不准确

原因: NTP 同步未配置或网络不通。

解决:

# 检查时间同步状态
timedatectl status

# 启用 NTP
sudo timedatectl set-ntp true

# 设置时区
sudo timedatectl set-timezone Asia/Shanghai

# 手动同步时间
sudo apt install -y ntpdate
sudo ntpdate pool.ntp.org

8. 性能优化建议

8.1 CPU 调频优化

树莓派5 的 Cortex-A76 核心最高可达 2.4GHz,默认使用 ondemand 调频策略。对于实时车牌识别场景,建议设置为 performance 模式。

# 查看当前 CPU 调频策略
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

# 设置为 performance 模式(全速运行)
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

# 设置为 powersave 模式(省电)
echo powersave | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

# 持久化配置(每次启动自动设置)
sudo apt install -y cpufrequtils
sudo tee /etc/default/cpufrequtils << 'EOF'
GOVERNOR=performance
EOF
sudo systemctl enable cpufrequtils

注意: performance 模式会持续运行在最高频率,功耗和温度会增加。建议配合主动散热使用。

8.2 内存管理优化

# 查看内存使用
free -h

# 设置 swappiness(降低 swap 使用倾向,优先使用物理内存)
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# 预分配大页内存(可选,MNN 推理可能受益)
# echo "vm.nr_hugepages=16" | sudo tee -a /etc/sysctl.conf

# 禁用不必要的 systemd 服务释放内存
sudo systemctl disable bluetooth.service 2>/dev/null
sudo systemctl disable cups.service 2>/dev/null
sudo systemctl disable ModemManager.service 2>/dev/null

8.3 DRM 硬解优化

对于 HEVC (H.265) 编码的 RTSP 流,树莓派5 支持 DRM 硬件解码,可大幅降低 CPU 占用。

# 检查 DRM 设备
ls /dev/dri/

# 检查 V4L2 硬件解码支持
v4l2-ctl --list-devices

# 在 config.ini 中启用 DRM 硬解
# decode_mode=drm

# 测试 DRM 硬解
ffmpeg -hwaccel drm -hwaccel_output_format drm_prime \
  -rtsp_transport tcp -i "rtsp://..." \
  -frames:v 10 -f null -

DRM 硬解 vs 软解对比:

模式 CPU 占用 延迟 兼容性 推荐场景
auto 中 低 广 默认推荐
drm 极低 (~5%) 最低 HEVC 流 4路 HEVC 摄像头
cpu 高 (~60%每路) 中 最广 H.264 流或兼容性要求

8.4 RTSP 流优化

# 优化网络缓冲区(提高 RTSP 流稳定性)
sudo sysctl -w net.core.rmem_max=16777216
sudo sysctl -w net.core.wmem_max=16777216

# 持久化
cat >> /etc/sysctl.conf << 'EOF'
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
EOF
sudo sysctl -p

8.5 文件系统优化

# 使用 tmpfs 存放临时文件(减少 SD 卡写入)
sudo tee -a /etc/fstab << 'EOF'
tmpfs /tmp tmpfs defaults,noatime,size=256M 0 0
tmpfs /var/log tmpfs defaults,noatime,size=128M 0 0
EOF

# SD 卡优化:禁用 atime 减少写入
# 在 /etc/fstab 的挂载选项中添加 noatime
# 例如: /dev/mmcblk0p2 / ext4 defaults,noatime 0 1

# 强烈建议使用 SSD/USB 3.0 存储替代 microSD 卡
# 通过 USB 3.0 接口连接 SSD,性能提升 5-10 倍

8.6 MNN 推理优化

# 在 config.ini 或环境变量中配置 MNN 推理参数
# MNN_NUM_THREADS=4     # 推理线程数,匹配核心数
# MNN_ARM82=1           # 启用 fp16 加速(编译时已启用)

# 监控推理耗时
# 查看日志中的推理耗时统计
journalctl -u plate-rec | grep "inference" | tail -20

8.7 散热方案

方案 散热能力 噪音 推荐度
被动散热片(铝制) 中 无 ⭐⭐⭐
主动风扇(30mm) 高 低 ⭐⭐⭐⭐
冰塔散热器 极高 无 ⭐⭐⭐⭐⭐
金属外壳散热 高 无 ⭐⭐⭐⭐

建议: 4路 RTSP 流 + 车牌识别场景下,强烈推荐使用主动散热方案,确保 CPU 温度低于 70°C。

8.8 系统监控

# 安装监控工具
sudo apt install -y htop iotop iftop

# 实时监控
htop

# 查看温度
watch -n 1 "cat /sys/class/thermal/thermal_zone0/temp | awk '{print \$1/1000}'"

# 查看 CPU 频率
watch -n 1 "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq | awk '{print \$1/1000 \" MHz\"}'"

# 查看磁盘 IO
iotop -o

# 查看网络流量
iftop -i end0

附录 A: 完整安装脚本(一键执行)

将以下步骤合并为单个脚本,适合全新安装:

#!/bin/bash
# PlateRecApp 一键安装脚本 (树莓派5 + Ubuntu 24.04)
# 使用方法: chmod +x install.sh && sudo ./install.sh

set -e

echo "========================================="
echo " PlateRecApp 安装脚本"
echo " 平台: 树莓派5 8G + Ubuntu 24.04"
echo "========================================="

# 1. 系统更新
echo "[1/6] 更新系统..."
apt update && apt upgrade -y

# 2. 安装依赖
echo "[2/6] 安装编译依赖..."
apt install -y \
    build-essential cmake git wget curl pkg-config unzip \
    libopencv-dev \
    libavformat-dev libavcodec-dev libavutil-dev libswscale-dev \
    libsqlite3-dev \
    libcurl4-openssl-dev libssl-dev \
    libfreetype-dev \
    libcjson-dev \
    libmosquitto-dev libmosquittopp-dev \
    libprotobuf-dev protobuf-compiler \
    libcrypt-dev

# 3. 编译安装 MNN
echo "[3/6] 编译安装 MNN..."
if [ ! -d "/usr/local/include/MNN" ]; then
    cd /root
    git clone --depth 1 --branch 2.9.6 https://github.com/alibaba/MNN.git
    cd MNN && mkdir build && cd build
    cmake .. \
        -DCMAKE_BUILD_TYPE=Release \
        -DMNN_BUILD_SHARED_LIBS=ON \
        -DMNN_BUILD_CONVERTER=OFF \
        -DMNN_BUILD_DEMO=OFF \
        -DMNN_BUILD_TOOLS=OFF \
        -DMNN_BUILD_TRAIN=OFF \
        -DMNN_ARM82=ON \
        -DMNN_FP16=ON \
        -DMNN_USE_THREAD_POOL=ON \
        -DMNN_NUM_THREADS=4 \
        -DCMAKE_INSTALL_PREFIX=/usr/local
    make -j4
    make install
    ldconfig
    echo "✅ MNN 安装完成"
else
    echo "✅ MNN 已存在,跳过"
fi

# 4. 安装 HyperLPR3 SDK
echo "[4/6] 安装 HyperLPR3 SDK..."
if [ ! -d "/root/PlateRecApp/hyperlpr3/include" ]; then
    echo "⚠️ 请手动安装 HyperLPR3 SDK 到 /root/PlateRecApp/hyperlpr3/"
    echo "   参考本文档第4节"
else
    echo "/root/PlateRecApp/hyperlpr3/lib" > /etc/ld.so.conf.d/hyperlpr3.conf
    ldconfig
    echo "✅ HyperLPR3 SDK 配置完成"
fi

# 5. 编译 PlateRecApp
echo "[5/6] 编译 PlateRecApp..."
cd /root/PlateRecApp
mkdir -p build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j4
echo "✅ 编译完成: $(ls -lh PlateRecApp)"

# 6. 配置 systemd 服务
echo "[6/6] 配置系统服务..."
mkdir -p /root/PlateRecApp/{data,fonts,html,logs}

# 性能优化
echo "performance" > /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 2>/dev/null || true

echo ""
echo "========================================="
echo " ✅ 安装完成!"
echo ""
echo " 后续步骤:"
echo " 1. 编辑 /root/PlateRecApp/config.ini"
echo " 2. 安装 HyperLPR3 SDK 模型文件"
echo " 3. sudo systemctl daemon-reload"
echo " 4. sudo systemctl enable --now plate-rec"
echo "========================================="

附录 B: 系统信息收集(用于问题反馈)

遇到问题时,运行以下命令收集系统信息:

echo "=== 系统信息 ==="
uname -a
cat /etc/os-release | head -3
echo "=== CPU ==="
lscpu | grep -E "Model name|Architecture|CPU\(s\)|Thread"
echo "=== 内存 ==="
free -h
echo "=== 温度 ==="
cat /sys/class/thermal/thermal_zone0/temp | awk '{print $1/1000 "°C"}'
echo "=== 磁盘 ==="
df -h / /root
echo "=== 依赖版本 ==="
pkg-config --modversion opencv4 2>/dev/null && echo "OpenCV: ✅" || echo "OpenCV: ❌"
pkg-config --modversion libavformat 2>/dev/null && echo "FFmpeg: ✅" || echo "FFmpeg: ❌"
pkg-config --modversion sqlite3 2>/dev/null && echo "SQLite3: ✅" || echo "SQLite3: ❌"
echo "=== MNN ==="
ls /usr/local/lib/libMNN.so 2>/dev/null && echo "MNN: ✅" || echo "MNN: ❌"
echo "=== HyperLPR3 ==="
ls /root/PlateRecApp/hyperlpr3/lib/libhyperlpr3.so 2>/dev/null && echo "HyperLPR3: ✅" || echo "HyperLPR3: ❌"
echo "=== PlateRecApp ==="
file /root/PlateRecApp/PlateRecApp 2>/dev/null || echo "未编译"
echo "=== 动态库检查 ==="
ldd /root/PlateRecApp/PlateRecApp 2>/dev/null | grep "not found" || echo "所有库已找到 ✅"

📝 本文档持续更新
最后更新: 2026-08-30 | 版本: fix27 v44
如有问题或建议,请联系项目维护者。