Git Product home page Git Product logo

carplate-recognition's Introduction

说明

设计语言为python3.6,设计平台为PyCharm,opencv版本为3.4.0.12,scikit-learn版本为0.22.1。处理的原始图片来自于中科大整理的数据集CCPD。车牌识别是基于图像分割和图像识别理论,对含有车牌识别车辆号牌的图像进行分析处理,从而确定车牌在图像中的位置,并进一步提取和识别出文本字符。车牌识别过程包括图像采集、预处理、车牌定位、字符分割、字符识别、结果输出等一系列算法运算。

车牌定位

车牌定位就是把车牌区域完整的从一副具有复杂背景的车辆图像中分割出来,本报告借用开源库opencv-python对图片进行相应的预处理操作,主要包括滤波、形态学处理、边缘检测、阈值分割、支持向量机分类等方法,完成了对车牌的定位。

灰度化处理

其中灰度化处理主要是将原始三通道彩色图像转换为单通道的灰度图,方便后续的处理 。通过cv2.cvtColor实现。

高斯滤波

高斯滤波是一种线性平滑滤波,主要是为了消除图像噪声。为了尽可能减少噪声对边缘检测结果的影响,所以必须滤除噪声以防止由噪声引起的错误检测。利用高斯核与图像进行卷积运算,得到的结果就是滤波的结果。高斯卷积核大小的选择将影响Canny检测器的性能。尺寸越大,检测器对噪声的敏感度越低,但是边缘检测的定位误差也将略有增加。高斯滤波通过调用函数cv2.GaussianBlur实现。

形态学处理

形态学处理包括腐蚀与膨胀操作,灰度形态学中的腐蚀就是类似卷积的一种操作,设结构元素B覆盖住的图像A的区域记为P,用P减去结构元素B形成的小矩形,取其中最小值赋到对应原点的位置即可。灰度形态学中的膨胀就是类似卷积的一种操作,用P加上B,然后取这个区域中的最大值赋值给结构元素B的原点所对应的位置。腐蚀和膨胀分别通过cv2.erode 与cv2.dilate两个函数实现。

边缘检测

在阈值分割之后就可以进行边缘检测了,Canny边缘检测算法可以分为以下4个步骤:

1**、计算图像中每个像素点的梯度强度和方向。**

边缘检测主要是利用sobel算子与图像进行卷积,提取图像中的边缘特征,图像中的边缘可以指向各个方向,因此经典Canny算法使用四个算子来检测图像中的水平、垂直和对角边缘。但是通常都不用四个梯度算子来分别计算四个方向。常用边缘差分算子(如Rober,Prewitt,Sobel)计算水平和垂直方向的差分Gx和Gy。 水平方向的sobel算子 垂直方向梯度的sobel算子 在opencv中利用函数cv2.Canny来进行边缘检测,Canny算法应用双阀值,这里的阈值指的是梯度阈值,而不是灰度阈值。一般的边缘检测算法用一个阀值来滤除噪声或颜色变化引起的小的梯度值,而保留大的梯度值。即一个高阀值和一个低阀值来区分边缘像素。如果边缘像素点梯度值大于高阀值,则被认为是强边缘点。如果边缘梯度值介于高阀值与低阀值之间,则标记为弱边缘点,用于下一步的处理。小于低阀值的点则被抑制掉。

2**、应用非极大值抑制[5]****,以消除边缘检测带来的杂散响应。**

非极大值抑制是一种边缘稀疏技术,非极大值抑制的作用在于“瘦”边。对图像进行梯度计算后,仅仅基于梯度值提取的边缘仍然很模糊(边缘比较粗)。而非极大值抑制则可以帮助将局部最大值之外的所有梯度值抑制为0,对梯度图像中每个像素进行非极大值抑制的算法是:

  1. 将当前像素的梯度强度与沿正负梯度方向上的两个像素进行比较。梯度方向垂直于边缘方向。但实际上,我们只能得到像素点邻域的8个点的值,用于比较的两个像素点并不在其中,要得到这两个值就需要对该两个点两端的已知灰度进行线性插值。如下图的P1 与P2就是插值的结果。

  2. 如果当前像素的梯度强度与另外两个像素相比最大,则该像素点保留为边缘点,否则该像素点将被抑制。

  3. 完成非极大值抑制后,会得到一个二值图像,非边缘的点灰度值均为0,可能为边缘的局部灰度极大值点可设置其灰度为128。检测结果还是包含了很多由噪声及其他原因造成的假边缘。因此还需要进一步的处理。

图10. 像素P领域的非极大值抑制

3**、应用双阈值(Double-Threshold****)检测来确定真实的和潜在的边缘。**

Canny算法应用双阀值,这里的阈值指的是梯度阈值,而不是灰度阈值。一般的边缘检测算法用一个阀值来滤除噪声或颜色变化引起的小的梯度值,而保留大的梯度值。即一个高阀值和一个低阀值来区分边缘像素。如果边缘像素点梯度值大于高阀值,则被认为是强边缘点。如果边缘梯度值介于高阀值与低阀值之间,则标记为弱边缘点,用于下一步的处理。小于低阀值的点则被抑制掉。

4**、通过抑制孤立的弱边缘最终完成边缘检测。**

到目前为止,被划分为强边缘的像素点已经被确定为边缘,因为它们是从图像中的真实边缘中提取出来的。然而,对于弱边缘像素,将会有一些争论,因为这些像素可以从真实边缘提取也可以是因噪声或颜色变化引起的。为了获得准确的结果,应该抑制由后者引起的弱边缘。通常,由真实边缘引起的弱边缘像素将连接到强边缘像素,而噪声响应未连接。为了跟踪边缘连接,通过查看弱边缘像素及其8个邻域像素,只要其中一个为强边缘像素,则该弱边缘点就可以保留为真实的边缘。

轮廓查找

根据上一步检测出来的边缘,利用轮廓查找函数cv2.findContours()函数找出图像中所有的轮廓, 函数返回三个参数,其中的 hierarchy便代表了检测到的轮廓在原图中的与部分其他轮廓层级关系: hierarchy是一个ndarray,其中的元素个数和轮廓个数相同,每个轮廓contours[i]对应4个hierarchy元素:hierarchy[i][0] ~hierarchy[i][3],分别表示:后一个轮廓的序号、前一个轮廓的序号、子轮廓的序号、父轮廓的序号。在实际使用中是使用了contours这个参数。

轮廓拟合

利用opencv中的cv2.minAreaRect函数对轮廓进行拟合,找出轮廓的最小外接矩形。其输出结果是一个由三个元素组成的元组,依次代表旋转矩形的中心点坐标、尺寸和旋转角度(根据中心坐标、尺寸和旋转角度可以确定一个旋转矩形)。为了方便观察,可以结合cv2.boxPoints与cv2.drawContours函数将拟合的矩形画出来。

轮廓筛选

设定筛选条件,初步筛选出符合车牌长宽比(接近3:1)的矩形。

SVM分类

利用SVM分类器,对剩下矩形框中的图像进行分类。其中用于训练的数据集包括2800张蓝色车牌正样本(12030),以及8000张负样本(12030)。 经过训练之后得到对应的模型:based_SVM_plate_train_model.m用于检测车牌。定义检测函数:GetRes_plate加载模型并得到车牌结果:

def GetRes_plate(box):

  gray = cv2.cvtColor(box,cv2.COLOR_BGR2GRAY)

  character_Arr = np.zeros((1,3600))

  img = cv2.resize(gray, (120, 30), interpolation=cv2.INTER_LINEAR) 

  new_character_ = img.reshape((1,3600))[0]

  character_Arr[0,:] = new_character_

  clf = joblib.load("based_SVM_plate_train_model.m")

  predict_result = clf.predict(character_Arr)

  middle_route = ['0', '1']

return middle_route[predict_result.tolist()[0]]

仿射变换

上一步中已经找到了车牌的位置,考虑到不同图片中的车牌可能会发生视角倾斜, 这里采用透视变换,从原图中将车牌切割出来。仿射变换后平行四边形的各边仍操持平行,透视变换结果允许是梯形等四边形,所以仿射变换是透视变换的子集,仿射变化是二维的二维的变换,透视变换是三维到三维的变换。仿射变换包括:平移、旋转、放缩、剪切、反射等。图像变换的实质就是矩阵的变换。

字符分割

去除冗余的空间

观察图像可以发现,图像中上部有一部分冗余的空间,为了不对后续识别处理的结果产生影响,现在将图片上部空间处理掉。主要思路是统计每一行的像素值的和,建立像素和值的直方图,然后设定一个阈值,找出在阈值之上的波峰区域作为字符的区域,利用该区域对图像进行裁剪,

(二) 字符分割

现在需要对每个字符进行分割,然后分别进行识别,字符分割的思路是遍历图像的每一列,统计黑色像素(一定阈值范围内的像素值内的像素)的数目,然后设定像素数目阈值,当黑色像素数目大于数目阈值时,即认定其为可切割列,继续遍历即可获得连续的黑色像素区间,然后定位区间中位数进行切割。 至此字符分割已经完成,去掉字符“·”,则获得了期望的7个字符。

四、 字符识别

这里字符识别,仍然采用SVM训练的分类器,虽然SVM是一种用于二分类的机器学习方法,但是 sklearn中的SVM仍然可以完成多分类的任务。sklearn中的SVM算法底层的实现采用了**大学林智仁教授等发表的LibSVM运行库,LibSVM中采用了一对一(ovo)的多分类方法。

(一) 数据集的准备

省份字符的数据集与数字、字母字符的数据集来源不同,内容也相差比较大,为了不弄混淆,现在将其分别进行训练,数据集也分别准备。省份数据集共包含省份字符3216张(2020),数字字母字符共3450张。利用脚本将图片名读取并保存至txt文件中:

import os

filepath1 = "C:\\Users\\zh\\Desktop\\data_province\\data\\"

filepath2 = "C:\\Users\\zh\\Desktop\\data_province\\txt\\"

path_list1 = os.listdir(filepath1) # data文件列表

print(path_list1)

for i in range(len(path_list1)):

  path_list2 = os.listdir(filepath1+path_list1[i])

  for j in range(len(path_list2)):

​      with open(filepath2+path_list1[i]+".txt","a") as f:

​         f.write(path_list2[j] + "\n")

​        f.close()

(二) 训练与检测

训练得到相应的模型,并对对省份字符以及数字字母字符进行分类,将得到的结果进行拼接,至此字符识别已经完成。

五总结

本项目中的车牌定位单纯借助的是opencv开源库,导致本车牌识别系统泛化能力太差。本设计的改进就是在车牌定位环节运用目标检测算法进行检测。然后在进行后续的检测。考虑到数据集中的车牌颜色为蓝色,曾在车牌定位环节考虑将图片转换为HSV空间,试图通过设定颜色阈值筛选出车牌,但是考虑到这种方法会受到光线照射的影响,所以没有采用。也尝试过借用yolov3官方权重去做检测,但是该模型并未包含车牌这个类别,受疫情等客观因素的影响,暂时还没完成改进。

carplate-recognition's People

Contributors

flippedzh avatar

Stargazers

 avatar  avatar  avatar Li Kang avatar songjin avatar

Watchers

 avatar

Forkers

cryptoascetic

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.