更新记录
1.0.0(2026-08-22)
YOLO车牌检测 + CRNN OCR + 颜色识别, 端侧离线推理,包含 拍照识别 与 实时视频流识别 两种模式
平台兼容性
uni-app x(4.66)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | 8.0 | - | - | - |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| × | × | √ |
车牌识别 App 使用说明
基于 uni-app x 的 Android 端侧车牌识别应用,采用 YOLOv5 检测 + CRNN OCR + 颜色识别,ONNX 离线推理,无需后端服务器。
目录
一、简介
本项目是一个 纯端侧 车牌识别 Android 应用,核心算法管线为:
YOLOv5 车牌检测 → 透视矫正 → CRNN 字符识别 → 颜色分类
所有推理均在设备本地通过 ONNX Runtime 完成,不依赖任何网络后端。
核心能力
| 能力 | 说明 |
|---|---|
| 车牌检测 | YOLOv5 模型,输入 1280×1280,支持单图多车牌 |
| 字符识别 | CRNN + CTC 解码,支持单层/双层车牌 |
| 颜色识别 | softmax 分类,覆盖蓝/绿/黄/白/黑五种标准车牌颜色 |
| 拍照识别 | 选择相册图片或现场拍摄,单张识别 |
| 视频流识别 | CameraX 实时预览,逐帧推理,画框 Overlay + 悬浮结果 |
| 离线运行 | 无需网络,模型打包在 assets 内 |
二、功能特性
拍照识别模式
- 支持从相册选择图片或直接调用相机拍摄
- 识别结果展示车牌号、颜色、类型(单层/双层)、检测置信度
- 支持单张图片中的多车牌同时识别
- 页面加载时自动初始化引擎(首次约 1-2 秒)
视频流识别模式
- CameraX 实时相机预览,逐帧自动识别
- 画面上叠加亮绿色车牌框 + 车牌号标签(Overlay)
- 悬浮显示当前最优识别结果(车牌号/颜色/类型/置信度)
- 实时帧率显示
- 手电筒切换(支持设备)
- 识别历史记录(自动去重,最多保留 50 条)
- 一键复制最新车牌号
- 页面退出自动释放相机资源
颜色领域校正
内置中文车牌颜色规则引擎,对模型输出进行后校正:
- 末位"学"→黄牌(教练车);末位"挂"→黄牌(挂车);末位"警"→白牌(警车)
- 8 位 + 黄→绿牌(新能源);8 位 + 绿→绿牌(保留)
- 7 位 + 绿→按黑蓝概率翻色(7 位不可能是新能源绿牌)
- 前缀"使"/末位"领"→黑牌(使领车);含"港"/"澳"→黑牌;前缀"民航"→白牌
- 黑蓝边界抖动兜底:softmax 概率差 < 0.10 时归蓝
三、环境要求
运行环境
| 项目 | 要求 |
|---|---|
| 操作系统 | Android 5.0 (API 21) 及以上 |
| 架构 | armeabi-v7a / arm64-v8a / x86_64 |
| 相机 | 具备后置摄像头(视频流识别必需) |
| 存储 | ≥ 50MB 可用空间(含模型文件) |
4.3 制作自定义基座
由于项目依赖 onnxruntime-android 和 androidx.camera(CameraX),必须使用自定义基座才能真机运行。标准基座不含这些库。
操作路径:运行 → 运行到手机或模拟器 → 制作自定义调试基座
4.4 真机运行
- 手机开启 USB 调试,连接电脑
- 运行 → 运行到手机或模拟器 → 运行到 Android App 基座
- 选择刚才制作的自定义基座
- App 安装后自动启动,首页为功能入口选择页
五、使用指南
5.1 拍照识别
入口:App 启动 → 首页点击「拍照识别」,或从视频流页面点击「拍照识别 →」跳转。
操作步骤:
- 选择图片:点击「选择 / 拍照」按钮,从相册选取或现场拍摄一张包含车牌的图片
- 等待初始化:首次使用时页面会自动初始化引擎,状态栏显示初始化结果
- 开始识别:点击「开始识别」按钮,等待 1-3 秒
- 查看结果:识别完成后,页面下方展示车牌号、颜色、类型和置信度
- 重新识别:可重新选图或拍摄,每次识别覆盖上次结果
如果未识别到车牌,页面会提示「未识别到车牌」。请确保图片中车牌清晰、占比不过小。
5.2 视频流识别
入口:首页点击「视频流识别」,或从拍照识别页面点击「视频流识别 →」跳转。
操作步骤:
- 授权相机:首次点击「开始识别」时,系统弹出相机权限请求,点击「允许」
- 再次点击开始:授权后需再次点击「开始识别」启动相机预览
- 实时识别:相机启动后自动逐帧识别,画面上出现绿色车牌框 + 车牌号标签
- 悬浮结果:画面左上角悬浮显示当前最优车牌号(黄色大字)+ 颜色/类型/置信度
- 历史记录:每次新识别的车牌自动加入下方历史列表(同号不重复入栈)
- 手电筒:点击「手电筒」按钮切换闪光灯(暗光环境辅助)
- 复制车牌:点击「复制车牌」将最新车牌号复制到剪贴板
- 停止:点击「停止」暂停识别,退出页面自动释放相机
识别帧率显示在状态栏右侧(如
12 fps)。帧率受设备性能和图像复杂度影响。
六、API 参考
6.1 函数式 API
UTS 插件 uni-plate-recognizer 提供三个函数,适用于拍照识别场景:
import { initPlate, recognizeImage, releasePlate } from '@/uni_modules/uni-plate-recognizer'
initPlate(): InitResult
初始化识别引擎(加载 ONNX 模型)。幂等,重复调用无副作用。
| 返回字段 | 类型 | 说明 |
|---|---|---|
success |
boolean |
是否初始化成功 |
message |
string |
失败原因(成功时为空) |
const r = initPlate()
if (r.success) {
console.log('引擎就绪')
} else {
console.log('初始化失败: ' + r.message)
}
recognizeImage(path: string): string
识别单张本地图片,返回 JSON 数组字符串。
| 参数 | 类型 | 说明 |
|---|---|---|
path |
string |
图片文件绝对路径(支持 file:// 前缀,自动剥离) |
| 返回 | 说明 |
|---|---|
string |
JSON 数组字符串,无结果时返回 "[]" |
const json = recognizeImage('/storage/emulated/0/DCIM/photo.jpg')
// json = [{"plateNo":"京A12345","plateColor":"蓝色","rect":[120,80,300,160],"detectConf":0.92,"plateType":0}]
const list = JSON.parse<PlateResult[]>(json) ?? []
releasePlate(): void
释放引擎资源(全局单例)。通常在 App 退出时调用,普通使用无需手动释放。
releasePlate()
6.2 组件式 API
UTS 兼容模式组件 <plate-camera>,适用于实时视频流识别场景:
<plate-camera ref="cam" @recognize="onRecognize" @status="onStatus"></plate-camera>
事件
| 事件名 | 参数 | 触发时机 |
|---|---|---|
recognize |
string(JSON 数组字符串) |
每帧识别到结果时触发 |
status |
string(JSON:{"fps":N,"msg":"..."}) |
帧率更新或状态变化时触发 |
方法
通过 ref 获取组件实例后调用:
import { PlateCameraElement } from '@/uni_modules/uni-plate-recognizer'
const cam = ref<PlateCameraElement | null>(null)
// 启动相机预览 + 实时识别(内部检查 CAMERA 权限)
cam.value?.startCamera()
// 停止相机预览与识别
cam.value?.stopCamera()
// 切换手电筒开关
cam.value?.toggleTorch()
事件处理示例
// 识别结果回调:取置信度最高的一张
function onRecognize(json: string): void {
const list = JSON.parse<PlateResult[]>(json) ?? []
if (list.length == 0) return
let best = list[0]
for (let i = 1; i < list.length; i++) {
if (list[i].detectConf > best.detectConf) best = list[i]
}
// 更新 UI...
}
// 状态回调
function onStatus(payload: string): void {
const o = JSON.parse<StatusInfo>(payload)
if (o != null) {
fps.value = o.fps
statusMsg.value = o.msg
}
}
6.3 返回数据结构
PlateResult
| 字段 | 类型 | 说明 |
|---|---|---|
plateNo |
string |
车牌号码,如 "京A12345" |
plateColor |
string |
车牌颜色:黑色 / 蓝色 / 绿色 / 白色 / 黄色 |
rect |
number[] |
检测框坐标 [x1, y1, x2, y2](原图像素) |
detectConf |
number |
检测置信度,0~1 浮点数 |
plateType |
number |
车牌类型:0 = 单层,1 = 双层 |
InitResult
| 字段 | 类型 | 说明 |
|---|---|---|
success |
boolean |
是否初始化成功 |
message |
string |
失败原因(成功时为空) |
JSON 示例
[
{
"plateNo": "京A12345",
"plateColor": "蓝色",
"rect": [120, 80, 300, 160],
"detectConf": 0.92,
"plateType": 0
}
]
七、构建与部署
依赖声明
插件依赖声明在 uni_modules/uni-plate-recognizer/utssdk/app-android/config.json:
{
"dependencies": [
"com.microsoft.onnxruntime:onnxruntime-android:1.18.0",
"androidx.camera:camera-core:1.3.4",
"androidx.camera:camera-camera2:1.3.4",
"androidx.camera:camera-lifecycle:1.3.4",
"androidx.camera:camera-view:1.3.4"
],
"minSdkVersion": 21
}
onnxruntime-android:端侧 ONNX 推理运行时androidx.camera:*:CameraX 相机预览与帧分析(视频流识别用,1.3.4 稳定版)- 图像处理(letterbox 缩放、透视矫正、双层拼接)全部用 Android 原生 Bitmap/Canvas/Matrix 实现,不依赖 OpenCV
构建步骤
- 用 HBuilderX 打开工程
- 确认运行环境配置(Gradle / JDK / Android SDK 路径正确)
- 运行 → 运行到手机或模拟器 → 制作自定义调试基座
- 构建完成后运行到 Android 基座进行真机调试
重建基座的场景
以下情况需要删除旧基座并重新制作:
- 修改了
config.json中的依赖版本 - 新增/替换了
assets/下的 ONNX 模型文件 - 修改了 Kotlin 引擎代码(
PlateRecognizer.kt等) - 升级了 HBuilderX 版本
旧基座文件位置:unpackage/debug/android_debug.apk,删除后重新制作即可。
打包发布
使用 HBuilderX 云打包 功能,选择「自定义基座」方式打包正式 APK。发布前确保:
manifest.json中versionName/versionCode已更新- App 图标已配置(
manifest.json → app.distribute.icons) - 模型文件已打包进 assets
八、项目结构
vehicle_license_plate_recognition/
├── App.uvue # 应用入口(生命周期 + 双击退出)
├── main.uts # 主入口
├── manifest.json # 应用配置
├── pages.json # 页面路由(index / plate / plate-video)
├── pages/
│ ├── index/index.uvue # 首页(功能入口选择)
│ ├── plate/plate.uvue # 拍照识别页
│ └── plate-video/plate-video.uvue # 视频流识别页
├── static/
│ └── logo.png # 应用图标
├── uni_modules/
│ └── uni-plate-recognizer/ # UTS 车牌识别插件
│ ├── package.json # 插件清单
│ └── utssdk/
│ ├── interface.uts # 对外类型声明(PlateResult / InitResult)
│ └── app-android/
│ ├── index.uts # 插件 API 实现(initPlate / recognizeImage / releasePlate)
│ ├── index.vue # plate-camera UTS 组件实现
│ ├── config.json # 依赖声明(onnxruntime + CameraX)
│ ├── AndroidManifest.xml # CAMERA 权限
│ ├── PlateRecognizer.kt # 引擎主入口(全局单例 + 检测/识别主流程)
│ ├── PlateCameraView.kt # 相机封装(CameraX 预览 + 逐帧分析 + Overlay)
│ ├── PlateTypes.kt # 类型定义 + 算法常量(字符集/颜色/均值/方差)
│ ├── PlatePreprocess.kt # 前处理(letterbox / 检测预处理 / OCR 预处理)
│ ├── PlatePostprocess.kt # 后处理(NMS / 坐标还原 / 透视矫正 / CTC 解码)
│ └── assets/
│ ├── plate_detect.onnx # 车牌检测模型(1280×1280)
│ ├── plate_rec_color.onnx # 字符识别 + 颜色分类模型
│ └── fonts/platech.ttf # 中文字体
├── apk/ # 构建产物
└── unpackage/ # HBuilderX 打包输出
九、技术架构
算法管线
输入图片 / 相机帧
│
▼
letterbox 缩放 → 1280×1280(检测模型输入)
│
▼
YOLOv5 检测 → [batch, 100800, 15]
│
▼
NMS 去重 → 坐标还原到原图 → 透视矫正裁切车牌区域
│
▼
CRNN 识别(BGR 通道顺序)+ 颜色分类(softmax)
│
▼
CTC 解码 → 双层拼接 → 颜色领域校正
│
▼
输出 [{ plateNo, plateColor, rect, detectConf, plateType }]
视频流数据流
CameraX ImageAnalysis(后台线程)
→ ImageProxy (YUV_420_888)
→ NV21 + YuvImage.compressToJpeg + decodeByteArray
→ Matrix.postRotate(rotationDegrees) // 旋正
→ Bitmap.createScaledBitmap(宽 960) // 降采样
→ PlateRecognizer.recognizeToJson(bmp) // 复用全局单例
→ Handler(mainLooper).post → $emit('recognize', json)
性能策略
| 策略 | 说明 |
|---|---|
| 跳帧 | ImageAnalysis STRATEGY_KEEP_ONLY_LATEST,积压帧自动丢弃 |
| 降采样 | 每帧缩放到宽 960px 再送引擎 |
| 后台线程 | 分析跑在独立单线程执行器(plate-analyzer 守护线程),不阻塞 UI |
| 引擎复用 | PlateRecognizer 全局单例,照片页与视频页共用同一 OrtSession,零额外模型内存 |
| 主线程 emit | 识别结果通过 Handler(Looper.getMainLooper()) 切回主线程 |
十一、常见问题
Q1:提示「找不到名称"ai"」编译错误
原因:HBuilderX 未配置运行环境,Gradle 无法解析 onnxruntime-android 三方 AAR。
解决:在 HBuilderX 设置 → 运行配置 中正确填入 Gradle、Gradle JDK(17)、Android SDK 路径。
Q2:真机运行白屏或闪退
原因:使用了标准基座而非自定义基座。
解决:删除 unpackage/debug/android_debug.apk,重新制作自定义调试基座后运行。
Q3:视频流识别首次点击「开始识别」无反应
原因:首次使用需授予相机权限。
解决:点击「开始识别」→ 系统弹出授权框 → 点击「允许」→ 再次点击「开始识别」即可启动。
Q4:识别结果车牌号不完整或颜色错误
可能原因:
- 图片中车牌过小或模糊 → 尝试近距离拍摄
- 光线不足 → 视频流模式可开手电筒辅助
- 车牌角度过大 → 尽量正面拍摄
Q5:视频流帧率很低
可能原因:设备性能不足或图像复杂度过高。
优化:引擎已内置跳帧(KEEP_ONLY_LATEST)和降采样(宽 960px)策略。如帧率仍低于 5fps,建议在性能更好的设备上运行。

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 8
赞赏 0
下载 12525536
赞赏 1944
赞赏
京公网安备:11010802035340号