在智能交通和安防监控领域,车牌自动识别(LPR)技术已经发展得相当成熟。但传统方案往往依赖高性能服务器或工控机,而Luxonis OAK系列边缘计算设备通过将深度学习模型直接部署到嵌入式视觉模块,实现了低功耗、高并发的实时识别能力。这个项目将带您完成从数据准备到模型部署的全流程,最终在OAK设备上运行一个能实时检测车牌的轻量化AI应用。
我选择OAK平台主要基于三个优势:首先是其独特的神经计算棒架构,能在1-2W功耗下实现4TOPS算力;其次是内置的深度感知相机支持双目测距,这对车牌定位很有帮助;最重要的是OpenVINO工具链对模型优化的支持,能让YOLO这类检测模型在资源受限环境下保持高帧率。
Luxonis OAK产品线包含多个型号,对于车牌检测推荐:
关键参数对比:
型号 相机配置 深度能力 价格区间 OAK-D Lite 4MP RGB + 双目 支持 $199 OAK-D Pro 12MP全局快门+双目 支持 $399 OAK-1 4MP RGB 不支持 $99
开发环境需要以下组件协同工作:
安装基础环境的命令如下:
bash复制# 创建Python虚拟环境
python -m venv oak_lpr
source oak_lpr/bin/activate
# 安装核心依赖
pip install depthai openvino-dev==2022.3.0 numpy opencv-python
优质的车牌检测数据集需要覆盖:
建议使用OAK设备直接采集原始数据,这样能保证输入数据与最终部署环境的一致性。通过DepthAI的录制功能可以轻松创建数据集:
python复制import depthai as dai
pipeline = dai.Pipeline()
cam = pipeline.create(dai.node.ColorCamera)
xout = pipeline.create(dai.node.XLinkOut)
xout.setStreamName("video")
cam.video.link(xout.input)
with dai.Device(pipeline) as device:
q = device.getOutputQueue("video")
while True:
frame = q.get().getCvFrame()
cv2.imshow("Recording", frame)
if cv2.waitKey(1) == ord('s'):
cv2.imwrite(f"plate_{time.time()}.jpg", frame)
使用LabelImg进行标注时需注意:
标注文件示例:
code复制0 0.543 0.612 0.125 0.048 # class x_center y_center width height
通过Roboflow应用以下增强组合效果最佳:
增强后的数据集应达到3000+样本量,各类增强样本比例建议:
对比测试显示,在OAK设备上表现最好的模型架构:
推荐使用YOLOv6的Nano版本,其结构优化更适合边缘设备:
python复制# yolov6n_backbone.yaml
depth_multiple: 0.33
width_multiple: 0.25
backbone:
[[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
[-1, 3, C3, [128]],
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8
[-1, 6, C3, [256]],
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16
[-1, 9, C3, [512]],
[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
[-1, 3, C3, [1024]],
[-1, 1, SPPF, [1024, 5]], # 9
]
关键训练参数设置建议:
yaml复制# hyp.yaml
lr0: 0.01 # 初始学习率
lrf: 0.01 # 最终学习率
momentum: 0.937 # SGD动量
weight_decay: 0.0005 # 权重衰减
warmup_epochs: 3.0 # 热身训练轮数
batch_size: 64 # 根据GPU显存调整
启动训练命令:
bash复制python train.py --batch 64 --epochs 100 --data plate_data.yaml --cfg yolov6n.yaml --weights '' --device 0 --hyp hyp.yaml
使用OpenVINO进行INT8量化的关键步骤:
bash复制python export_onnx.py --weights runs/train/exp/weights/best.pt --simplify
bash复制pot -q default -m best.onnx -w best.onnx --ac config.yaml
量化配置文件示例:
yaml复制# config.yaml
model:
model_name: plate_detector
model: best.onnx
weights: best.onnx
engine:
type: accuracy_checker
config: accuracy_checker_config.yaml
compression:
- algorithm: quantization
preset: performance
target_device: CPU
将优化后的模型转换为OAK可用的blob格式:
bash复制python3 /opt/intel/openvino/deployment_tools/model_optimizer/mo.py \
--input_model best_int8.xml \
--output_dir ./blob \
--data_type FP16 \
--scale 255 \
--reverse_input_channels
然后使用DepthAI的编译工具生成blob文件:
bash复制./compile_model.sh -m best_int8.xml -o plate_detector.blob -sh 320 -sw 320
完整的车牌检测Pipeline实现:
python复制import depthai as dai
import cv2
pipeline = dai.Pipeline()
# 定义神经网络节点
detection_nn = pipeline.create(dai.node.NeuralNetwork)
detection_nn.setBlobPath("plate_detector.blob")
# 配置摄像头
cam = pipeline.create(dai.node.ColorCamera)
cam.setPreviewSize(320, 320)
cam.setInterleaved(False)
cam.setColorOrder(dai.ColorCameraProperties.ColorOrder.BGR)
# 创建输出
xout_nn = pipeline.create(dai.node.XLinkOut)
xout_nn.setStreamName("nn")
xout_frame = pipeline.create(dai.node.XLinkOut)
xout_frame.setStreamName("frame")
# 连接节点
cam.preview.link(detection_nn.input)
detection_nn.out.link(xout_nn.input)
cam.preview.link(xout_frame.input)
# 设备连接与处理
with dai.Device(pipeline) as device:
q_nn = device.getOutputQueue("nn")
q_frame = device.getOutputQueue("frame")
while True:
in_frame = q_frame.get().getCvFrame()
in_nn = q_nn.get()
detections = in_nn.detections
for detection in detections:
bbox = detection.boundingBox
x1 = int(bbox.xmin * in_frame.shape[1])
y1 = int(bbox.ymin * in_frame.shape[0])
x2 = int(bbox.xmax * in_frame.shape[1])
y2 = int(bbox.ymax * in_frame.shape[0])
cv2.rectangle(in_frame, (x1,y1), (x2,y2), (0,255,0), 2)
cv2.imshow("Plate Detection", in_frame)
if cv2.waitKey(1) == ord('q'):
break
帧率提升方案:
精度优化方案:
内存优化:
-sh/-sw参数匹配模型输入尺寸收费站场景:
python复制# 配置适合收费站的高角度拍摄
cam.setBoardSocket(dai.CameraBoardSocket.RGB)
cam.setResolution(dai.ColorCameraProperties.SensorResolution.THE_1080_P)
cam.setPreviewSize(640, 360) # 16:9比例
cam.setFps(25)
停车场场景:
python复制# 低光照环境配置
cam.setIspScale(1,3) # 启用数字变焦
cam.setManualFocus(80) # 固定焦距
cam.setBrightness(2) # 提高亮度
检测漏报问题:
误检问题处理:
性能下降排查:
bash复制# 监控设备状态
depthai_viewer -s all
检查指标:
车牌识别一体化:
添加OCR模型分支,实现检测识别端到端方案
python复制# 在YOLO尾部添加识别头
[[-1, 1, Conv, [128, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]],
[-1, 3, C3, [128, False]],
[-1, 1, Conv, [78, 1, 1]]] # 78=26字母+10数字+各省缩写
多相机协同方案:
使用OAK PoE型号通过交换机组网,实现多角度覆盖
云端协同分析:
将检测结果通过MQTT上传,结合云端大数据分析车辆轨迹
在真实场景测试中获得的优化参数组合:
| 场景类型 | 输入分辨率 | 置信度阈值 | NMS阈值 | 平均帧率 |
|---|---|---|---|---|
| 城市道路 | 416x416 | 0.4 | 0.6 | 18 FPS |
| 地下停车场 | 320x320 | 0.3 | 0.5 | 25 FPS |
| 高速公路收费站 | 640x360 | 0.5 | 0.7 | 15 FPS |
调试中发现的最佳实践: