车牌识别需自建OpenCV流水线:先用HSV颜色+形态学定位并矫正车牌,再用ONNX轻量OCR模型识别字符,部署时须应对光照突变、小车牌、遮挡,并加帧间投票提升视频流稳定性。

车牌识别不是OpenCV内置功能,得自己搭流水线
OpenCV本身不提供detect_plate()或recognize_license_plate()这类开箱即用的函数。它只提供底层图像处理能力(如滤波、二值化、轮廓查找)和基础模型接口(如cv::dnn::Net),识别流程必须手动串联:定位→校正→字符分割→识别。直接调cv::CascadeClassifier想靠Haar检测车牌?在复杂光照或倾斜角度下漏检率极高,不推荐作为主方案。
车牌定位推荐用颜色+形态学+轮廓过滤组合
国内蓝牌、黄牌、绿牌在HSV空间有较稳定色域,比单纯灰度边缘更鲁棒。关键不是“找到最大轮廓”,而是排除干扰:
- 先用
cv::inRange()提取蓝色/黄色通道(注意H值范围:蓝牌约100–124,黄牌约15–35) - 接
cv::morphologyEx()用矩形核做闭运算补全断裂字符区域 - 用
cv::findContours()找轮廓后,筛掉长宽比不在2.5–5.5、面积小于图像0.005倍的候选区 - 对剩余轮廓用
cv::minAreaRect()拟合旋转矩形,再用cv::warpPerspective()矫正成正视图
纯Canny+霍夫直线容易把栏杆、广告牌边框误判为车牌,HSV+形态学在实车视频流中准确率明显更高。
字符识别别硬写OCR,优先接入轻量模型
OpenCV的cv::ml::SVM或cv::ml::KNearest训练单字分类器,需要大量标注样本且泛化差。更可行的是用ONNX模型跑推理:
- 把车牌ROI缩放到
32×128(宽高比适配CNN输入) - 加载预训练中文车牌OCR模型(如
plate_ocr.onnx),用cv::dnn::readNetFromONNX()读取 - 注意预处理:归一化到
[0, 1]、cv::dnn::blobFromImage()时设swapRB=true(BGR→RGB) - 输出通常是CTC解码后的字符串,需调用
ctc_decode()逻辑(可复用PyTorch OCR项目里的C++版decode函数)
自己从零训练CRNN或DBNet太重,但直接用现成ONNX模型+OpenCV DNN模块,30行代码内就能跑通端到端识别。
实际部署要防三个坑:光照突变、小车牌、遮挡
测试时一切正常,上路就失效,大概率栽在这三处:
-
cv::inRange()阈值固定 → 改成自适应:先算ROI内HSV均值,再动态偏移H上下限±5 - 远距离车牌在图像中不足
20px高 → 在定位前加cv::resize()放大2倍,但只对ROI区域放大,避免全局计算浪费 - 雨滴、泥点造成字符粘连 → 分割前插一句
cv::morphologyEx(mask, mask, cv::MORPH_OPEN, kernel),用3×3椭圆核去噪
真正难的不是单帧识别精度,而是视频流中保持结果稳定——同一车牌连续5帧识别结果不一致时,得加简单投票逻辑,而不是盲目信最新一帧。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











