基于ensorlow的车牌号识别系统smile

为了简化生成的训练图片,减少计算量,我决定该网络可操作的输入图片为128*64的灰度图。

为了在更大的图片中检测车牌号,采用了一个多尺度的滑窗来解决。

右边的图片是神经网络的输入图片,大小为128*64,而左边的图片则展示了在原始输入图片的上下文中的滑窗。

对于每个滑窗,网络都会输出:

考虑一个车牌存在当且仅当:

为了检测这些号码,我们可以利用一个滑窗,每次滑动8个像素,而且在保证不丢失车牌的情况下提供一个缩放等级,缩放系数为,同时对于任何单个的车牌不会生成过量的匹配框。在后处理过程中会做一些复本(稍后解释)。

为了训练任何一个神经网络,必须提供一套拥有正确输出的训练数据。在这里表现为一套拥有期望输出的128*64大小的图片。这里给出一个本项目生成的训练数据的实例:

期望输出的第一部分表示网络应该输出的号码,第二部分表示网络应该输出的“存在”值。对于标记过的数据不存在的情况我在括号里作了解释。

生成图片的过程如下图所示:

文本和车牌的颜色是随机选择的,但是文本颜色必须比车牌颜色更深一些。这是为了模拟真实场景的光线变化。最后再加入一些噪音,这样不仅能够解释真实传感器的噪音,而且能够避免过多依赖于锐化的轮廓边界而看到的将会是离焦的输入图片。

拥有背景是很重要的,这意味着网络必须学习分辨没有“欺骗”的车牌号边界:使用一个黑色背景为例,网络可能会基于非黑色来学习分辨车牌的位置,这会导致分不清楚真实图片里的小汽车。

车牌变换采用了一种基于随机滚转、倾斜、偏转、平移以及缩放的仿射变换。每个参数允许的范围是车牌号可能被看到的所有情况的集合。比如,偏转比滚转允许变化更多(你更可能看到一辆汽车在拐弯而不是翻转到一边)。

使用的网络结构如下图所示:

输出层有一个节点(左边)被用来作为车牌是否存在的指示器。剩下的节点用来编码一个特定车牌号的概率:图中的每一列与车牌号中的每一位号码一致,每一个节点给出与存在的字符相符合的概率。例如,位于第2列第3行的节点给出车牌号中第二个号码是字符c的概率。

除了输出层使用ReLU激活函数之外,所有层都采用深度神经网络的标准结构。指示存在的节点使用sigmoid激活函数,典型地用于二值输出。其他输出节点使用softmax贯穿字符(结果是每一列的概率之和为1),是模型化离散概率分布的标准方法。

事实上为了从输入图片中检测和识别车牌号,搭建了类似于上面的一个检测网络,并采用了多位置和多尺度的128*64滑窗,这在滑窗那一节有所描述。

检测网络和训练网络的不同点在于最后两层采用了卷积层而不是全连接层,这样可以使检测网络的输入图片大小不仅限于128*64。将一张完整的图片以一种特定尺寸扔进网络中,然后返回一张每个“像素”拥有一个存在/字符概率值的图片。因为相邻的滑窗会共享很多卷积特征,所以将这些特定图片卷进同一个网络可以避免多次计算同样的特征。

可视化输出的“存在”部分会返回如下所示的图片:

图上的边界框是网络检测存在车牌概率大于99%的区域。设置高阈值的原因是为了解释训练过程中引进的一个偏差:几乎过半的训练图片都包含一个车牌,然而真实场景中有车牌的图片很少见,所以如果设置阈值为50%的话,那么检测网络的假阳性就会偏高。

在检测网络输出之后,我们使用非极大值抑制(NMS)的方法来过滤掉冗余的边界框:

首先将重叠的矩形框分组,然后针对每一组输出:

哎呦,字符R被误检成了P。上图中车牌存在概率最大的滑窗如下图所示:

第一眼似乎以为这个对于检测器来说是小菜一碟,然而事实证明这是过拟合的问题。下图给出了生成训练图片时所用的车牌号中R的字体:

注意字符R腿的角度是如何不同于输入图片中字符R腿的角度。由于网络仅仅学习过上面的那种R字体,因此当遇到不同字体的R字符时就迷惑了。为了测试这种假设,我在GIMP中改进了图片,使得其更接近于训练时的字体:

改进之后,检测得到了正确的输出:

我已经开源了一个拥有相对较短代码(大约800行)的系统,它不用导入任何特定领域的库以及不需要太多特定领域的知识,就能够实现车牌号自动识别。此外,我还通过在线合成图片的方法解决了上千张训练图片的需求问题(通常是在深度神经网络的情况下)。

另一方面,我的系统也存在一些缺点:

为了解决第1个问题,谷歌团队将他们的网络结构的高层拆分成了多个子网络,每一个子网络用于假定输出号码中的不同号码位。还有一个并行的子网络来决定存在多少号码。我觉得这种方法可以应用到这儿,但是我没有在这个项目中实现。

关于第2点我在上面举过例子,由于字体的稍微不同而导致字符R的误检。如果尝试着检测US车牌号的话,误检将会更加严重,因为US车牌号字体类型更多。一个可能的解决方案就是使得训练数据有更多不同的字体类型可选择,尽管还不清楚需要多少字体类型才能成功。

第3点提到的速度慢的问题是扼杀许多应用的cancer:在一个相当强大的GPU上处理一张适当尺寸的输入图片就要花费几秒钟。我认为不引进一种级联式结构的检测网络就想避开这个问题是不太可能的,比如Haar级联,HOG检测器,或者一个更简单的神经网络。

我很有兴趣去尝试和其他机器学习方法的比较会怎样,特别是姿态回归看起来有希望,最后可能会附加一个最基本的分类阶段。如果使用了像scikit-learn这样的机器学习库,那么应该同样简单。

总之,我使用单个CNN网络实现了一个车牌号检测器/识别器,然而从性能方面来讲,它还不能与传统的手工(但更繁琐的)管道线一较高下。

THE END
0.南宁车管部门新推20余万车牌号抢靓号快出手(图)|手机广西网当日下午,记者在南宁市金桥车管办理点看到,业务大厅悬挂的“小车入户自编号牌操作说明”横幅前,只有一位市民驻足观看,到业务大厅办理车管业务的市民也不多,两台供市民自编自选车号牌的电脑前,仅围坐着几个选号的市民。jvzquC41x0mypn|u0eun0ls1c1?15>838
1.【开源】轻松实现车牌检测与识别:yolov8+paddleocr【python源码+使用ocr进行车牌识别 def get_license_result(ocr,image):"""image:输入的车牌截取照片输出,车牌号与置信度"""result = ocr.ocr(image, cls=True)[0]if result:license_name, conf = result[0][1]if '·' in license_name:license_name = license_name.replace('·', '')return license_name, confeljvzquC41fg|fnxugt0gmk‚zp0eun1jwvkerf1::58895