以车牌识别为例学习AI应用实现

2026 年 02 月 08 日

车牌识别有很多人做过了。虽然简单,但对于我这种初学者来说,作为练手是个不错的选择。

基础概念和工具整理

要做车牌识别,要依序经过以下几个步骤:

  1. 从输入的图片中,(用 YOLO)提取出车牌所在的区域。
  2. 对图片进行几何变换,将其矫正为长方形,也就是拉平。(注:这步实际上是可选的,但对于正确率影响很大)
  3. 通过 OCR 或深度学习方式识别图片文字(以及其他信息,如颜色等)。

第 1 步是要做的重点,具体到实现层面,就是用推理引擎(如 ort)运行模型(onnx 格式,本质是权重集)得到区域坐标集合。

之前一篇文章里,已经学到了几个基础概念,包括:

  • 推理引擎 + 权重集 + 用户输入 = 推理输出。
  • 训练引擎 + 数据集 = 权重集(.pt/.pth/.ckpt/.onnx 等)。

这里暂时先不考虑训练部分,直接找可以运行的 onnx 模型。我找到了两套,但肯定还有更多:

我用 rust 的 ort 做推理,所以第二套的模型可以直接用。但模型的使用方法仍需参考对应的源码。

注: onnx 文件可以用 netron.app 直接打开,以检查其输入输出格式。

实现过程中学到的知识

我参考 ort 本身的 yolov8 范例代码,以及第二套模型对应的 java 代码,配合 AI 助手(我这次用的 codex)帮忙,可以很快生成可以运行的代码。

我找了几张图片来验证,虽然确实能识别一些清晰且矩形外框变形较小的车牌,但对于变形较大的车牌,识别率就差很多了。而且我认为 AI 能够轻松生成的代码价值不高,这里就不贴代码了。

下面是实现过程中学到的知识点。

关于模型及其使用方式

上面提到的,可以直接用的 onnx 模型,提供了两个 onnx 文件。

第一个 plate_detect.onnx 负责从原始图片中,找到车牌区域所在的区域。大部分情况下,车牌并非正对镜头,所以近大远小,车牌原本的矩形框一定会变形为非矩形。但这个模型只能给出包含完整车牌区域的矩形,而不是给出车牌矩形框的角点。

第二个 plate_rec_color.onnx 负责从车牌矩形框的输入中,提取颜色和车牌号。这部分是用深度学习分析车牌,而不是传统的 OCR 方式。

对于矩形失真较小的车牌图片,直接丢进第二个模型,基本就能得到正确结果。比如这张:

经过第一个模型,得到的区域做 letterbox 处理,得到第二个模型的输入,是这样的:

然后直接丢给第二个模型就能得到正确结果。

车牌图片处理的不确定性

虽然上一个例子看起来能用,但事情不是那么简单。比如下面这张图片:

注意,这张图片里有两个车牌,从第一个模型里面拿到的图片经过 letterbox 处理,结果是这样的:

将上面两张图片直接丢给第二个模型,那么后面一张图片还能勉强识别出来(中文错误,颜色、字母和数字正确),前面一张图片就错的离谱了。

由于我对图像处理算法不了解,让 AI 引入了 opencv,做了下面几个尝试:

将图片不加 letterbox,只是简单拉伸到目标分辨率。

结果还是中文错误,第一张图片的车牌颜色错误。

对上面的图片再做一次处理,AI 用了 BlackHat 方法,尝试找到车牌的四个角点,并通过矫正转换为矩形。

然后再做字符锐化处理,不过这步我觉得用处似乎不大。

经过上面一系列处理,第一张车牌总算识别正确了;但第二张仍然错误,"辽"字识别成了"使"。

注:以上算法全靠 AI 帮忙,要是让我自己写,估计我花半年时间看算法书都不一定写的出来。

下一步的可能性

由于这次只是练习推理的实现,到这里就基本结束了。

虽然不算成功,但思路基本是清晰的。如果要想进一步改善,还有几个可选的点,比如:

  • 找到或自行训练能够直接定位车牌角点的模型,这样第一步的结果可以直接得到车牌精确位置,方便拉平为更易读的车牌图片。
  • 找到或训练从车牌图片中提取准确信息的模型,这样可以简化中间的图片处理的过程,同时提高精确率。

所以,下一步需要看看如何根据数据集,比如 CCPD 或者 CBLPRD-330K,训练得到所需要的权重集,然后结合推理过程使用。

Top