基于机器学习的车牌识别系统(Python实现基于SVM支持向量机的车牌分类)

news/2024/11/27 21:10:11/

基于机器学习的车牌识别系统(Python实现基于SVM支持向量机的车牌分类)

一、数据集说明
训练样本来自于github上的EasyPR的c++版本,包含一万三千多张数字及大写字母的图片以及三千多张中文字符图片。图片为已经处理好的二值化图像,已贴好标签(见每个子文件夹名),像素均为20×20。数字和大写字母图片保存在train\chars2目录下,中文字符图片保存在train\ charsChinese目录下。
测试样本来源于较为广泛,从各种网站搜集得到的各类车辆图片,保存在test目录下。

二、模型概述
本模型主要由四部分构成:训练字符分类器、车牌定位、字符分割、字符识别。其中训练字符分类器部分,将训练样本图片进行进一步抗扭曲处理后提取特征向量——方向梯度直方图,然后利用OpenCV自带的SVM模型训练模型,模型分为两个分类器,其中一个存放中文字符另外一个存放数字及大写字母。车牌定位部分是将测试集图片进行灰度化处理、高斯去躁、开运算和闭运算、Canny算子边缘检测、根据矩形框位置及颜色检测等处理,将车牌位置找到。字符分割部分从图片的波形直方图中找到波峰的位置,每个波峰范围内是一个字符,将字符分割开。字符识别部分就是将分割开的字符分别放入对应的分类器中进行识别,给出测试结果。下面我将结合具体代码及结果就以上四个部分给出详细的说明。

三、训练字符分类器
本字符分类器的训练是运用SVM的思想,利用OpenCV自带的SVM模型进行训练。
(一)SVM介绍
支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机;SVM还包括核技巧,这使它成为实质上的非线性分类器。SVM的的学习策略就是间隔最大化,可形式化为一个求解凸二次规划的问题,也等价于正则化的合页损失函数的最小化问题。SVM的的学习算法就是求解凸二次规划的最优化算法。
(二)具体实现过程
1、定义一个SVM类,用到OpenCV自带的方法
(1)参数说明
SVM模型有两个非常重要的参数C与gamma。其中C是惩罚系数,即对误差的宽容度。C越高,说明越不能容忍出现误差,容易过拟合。C越小,容易欠拟合。C过大或过小,泛化能力变差。
gamma是选择RBF函数作为kernel后(本模型即选用RBF为核函数),该函数自带的一个参数。隐含地决定了数据映射到新的特征空间后的分布,gamma越大,支持向量越少,gamma值越小,支持向量越多。支持向量的个数影响训练与预测的速度。
(2)相关代码

class SVM(StatModel):def __init__(self, C = 1, gamma = 0.5):self.model = cv2.ml.SVM_create()self.model.setGamma(gamma) #设置gamma参数self.model.setC(C) #设置正则化参数self.model.setKernel(cv2.ml.SVM_RBF) #核函数为RBF(径向基函数)self.model.setType(cv2.ml.SVM_C_SVC) #SVC为分类,SVR为回归
#训练svmdef train(self, samples, responses):self.model.train(samples, cv2.ml.ROW_SAMPLE, responses)
#cv2.ml.ROW_SAMPLE表示每一行是一个样本
#字符识别def predict(self, samples):r = self.model.predict(samples)return r[1].ravel() #返回值为一个行向量

2、训练集特征向量抗扭曲处理
相关代码:

#训练数据中有些图像是扭曲的,需要做抗扭曲处理,也就是把歪了的图片摆正
def deskew(img):m = cv2.moments(img) #算图像的中心矩if abs(m['mu02']) < 1e-2:return img.copy()skew = m['mu11']/m['mu02']M = np.float32([[1, skew, -0.5*SZ*skew], [0, 1, 0]])img = cv2.warpAffine(img, M, (SZ, SZ), flags=cv2.WARP_INVERSE_MAP | cv2.INTER_LINEAR)return img

3.获取训练集图片特征:方向梯度
(1)方向梯度直方图
对于本分类器研究的问题,图片的边缘十分重要,因此提取特征时应重点关注图像边缘。沿着一张图片X和Y轴的方向上的梯度是很有用的,因为在边缘和角点的梯度值是很大的,边缘和角点包含了很多物体的形状信息。因此本模型采用方向梯度直方图(HOG)中梯度的方向作为特征。
(2)具体步骤:
a.计算梯度图像:直接用OpenCV里面的kernel大小为1的Sobel算子来计算。
b.计算梯度的幅值g和方向theta。
c.将梯度量化为16×16个整数值。把每个图像分成四个子图方块。对于每个子正方形,计算加权其幅度的方向(16×16bins)的直方图。因此,每个子图有一个包含16×16个值的向量。四个这样的向量(分别代表四个子图的16×16向量)一起给我们一个特征向量包含1024个值。这就是我们用来训练数据的特征向量。
(3)HOG方法优缺点分析
优点:HOG表示的是边缘(梯度)的结构特征,因此可以描述局部的形状信息;位置和方向空间的量化一定程度上可以抑制平移和旋转带来的影响;采取在局部区域归一化直方图,可以部分抵消光照变化带来的影响。由于一定程度忽略了光照颜色对图像造成的影响,使得图像所需要的表征数据的维度降低了。
缺点:描述子生成过程冗长,导致速度慢,实时性差;很难处理遮挡问题;由于梯度的性质,该描述子对噪点相当敏感。
(4)相关代码:

#获取每张图片的特征,特征是方向梯度直方图
def preprocess_hog(digits):#方向梯度直方图samples = []for img in digits:gx = cv2.Sobel(img, cv2.CV_32F, 1, 0) #计算梯度图像gy = cv2.Sobel(img, cv2.CV_32F, 0, 1)mag, ang = cv2.cartToPolar(gx, gy) #计算梯度的幅值g和方向thetabin_n = 16bin = np.int32(bin_n*ang/(2*np.pi))bin_cells = bin[:10,:10], bin[10:,:10], bin[:10,10:], bin[10:,10:]mag_cells = mag[:10,:10], mag[10:,:10], mag[:10,10:], mag[10:,10:] 
#bincount()统计出现的次数
#ravel()将数组降为一维hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)] hist = np.hstack(hists)# transform to Hellinger kerneleps = 1e-7hist /= hist.sum() + epshist = np.sqrt(hist)hist /= norm(hist) + epssamples.append(hist)return np.float32(samples)

4.将数据导入分类器进行训练
相关代码:

def train_svm(self):self.model = SVM(C=1, gamma=0.5) #大写英文字母和数字分类器self.modelchinese = SVM(C=1, gamma=0.5) #中文字符分类器if os.path.exists("svm.dat"): self.model.load("svm.dat") #用于导入之前训练好的字母和数字分类模型else: #导入数据开始训练chars_train = []chars_label = []for root, dirs, files in os.walk("train\\chars2"):
#root为正在遍历的文件夹的名字 dirs为子文件夹的集合 
#files为在遍历的文件夹中的文件集合if len(os.path.basename(root))> 1:
#os.path.basename(root)返回文件名continueroot_int = ord(os.path.basename(root))
#ord返回的是ASCII值,此处是文件夹名字的ASCII值for filename in files:filepath = os.path.join(root,filename) #路径拼接digit_img = cv2.imread(filepath) #读取图像digit_img = cv2.cvtColor(digit_img, cv2.COLOR_BGR2GRAY)
#转为灰度图chars_train.append(digit_img) #训练数据为这个图像chars_label.append(root_int) #标签是它文件夹名字的ASCII码chars_train = list(map(deskew, chars_train)) #得到抗扭曲后的图像chars_train = preprocess_hog(chars_train) #获取样本方向梯度直方图chars_label = np.array(chars_label) #把图片的标签存起来self.model.train(chars_train, chars_label) #数据喂进分类器if os.path.exists("svmchinese.dat"): #开始训练汉字分类器,具体流程同上self.modelchinese.load("svmchinese.dat")else:chars_train = []chars_label = []for root, dirs, files in os.walk("train\\charsChinese"):if not os.path.basename(root).startswith("zh_"):continuepinyin = os.path.basename(root)index = provinces.index(pinyin) + PROVINCE_START + 1 
#1是拼音对应的汉字for filename in files:filepath = os.path.join(root,filename)digit_img = cv2.imread(filepath)digit_img = cv2.cvtColor(digit_img, cv2.COLOR_BGR2GRAY)chars_train.append(digit_img)chars_label.append(index)chars_train = list(map(deskew, chars_train))chars_train = preprocess_hog(chars_train)chars_label = np.array(chars_label)print(chars_train.shape)self.modelchinese.train(chars_train, chars_label)

数据集及所有代码资源链接:https://download.csdn.net/download/creampang/85766802


http://www.ppmy.cn/news/842312.html

相关文章

深度学习-机器学习(5.1支持向量机)

1.支持向量机(Support Vector Machine)&#xff08;英文简写SVM&#xff09;属于监督学习&#xff08;Supervised Learning&#xff09;:分类&#xff08;Classifcation&#xff09; 2.机器学习的一般框架&#xff1a; 训练集->提取特征向量->结合一定的算法&#xff08…

SAP顾问英语自学的免费且有效的方法汇总!--一文搞定英语学习

SAP顾问学习英语到底有多重要&#xff1f; 1.如果你英语水平可以用于工作&#xff0c;那么你能获取的项目机会&#xff0c;比不会英语的顾问&#xff0c;至少多一半以上&#xff1b; 2.不得不说&#xff0c;欧美企业的待遇是普遍优于国内企业的&#xff0c;而且更加遵守相关法律…

2019年你应该学习哪种编程语言?

▲点击上方"什么技术值得学"&#xff0c;关注持续获得知识 无论您是专业开发人员还是初学者&#xff0c;对学习新的编程语言总是一个好主意。 当然&#xff0c;并不是每个专业或有抱负的开发人员都必须绝对学习的单一语言。您选择学习的下一种语言取决于您当前的技能…

java实现一个感知机_感知机学习算法Java实现

感知机学习算法Java实现。 Perceptron类用于实现感知机&#xff0c; 其中的perceptronOriginal()方法用于实现感知机学习算法的原始形式&#xff1b; perceptronAnother()方法用于实现感知机学习算法的对偶形式(此处仍有bug)。 import java.util.Scanner; public class Percept…

机器学习 —— 感知机简单入门

机器学习 —— 感知机简单入门 第1关&#xff1a;感知机 - 西瓜好坏自动识别1. 感知机原理简介1.1 举例1.2 数学原理/公式1.3 算法流程 2. 实现代码 第2关&#xff1a;scikit-learn感知机实践 - 癌细胞精准识别1. 数据集介绍及使用2. 使用 sklearn.Perceptron 方法实现感知机算…

机器学习 之 感知机(Perceptron)

文章目录 〇、推荐一、简介二、模型三、感知机算法的原始形式1、理论2、实现3、效果 四、感知机算法的对偶形式1、理论2、实现3、效果 数学公式网站推荐 〇、推荐 无意中发现了一个巨牛的人工智能教程&#xff0c;忍不住分享一下给大家。教程不仅是零基础&#xff0c;通俗易懂…

深入理解Linux网络——本机网络IO

文章目录 一、相关实际问题二、跨机网络通信过程1&#xff09;跨机数据发送2&#xff09;跨机数据接收3&#xff09;跨机网络通信汇总 三、本机发送过程1&#xff09;网络层路由2&#xff09;网络设备子系统3&#xff09;驱动程序 四、本机接收过程五、问题解答 系列文章&#…

“深入解析Redis:高性能缓存与分布式数据存储“

标题&#xff1a;深入解析Redis&#xff1a;高性能缓存与分布式数据存储 摘要&#xff1a;本文将深入解析Redis&#xff0c;介绍其作为高性能缓存和分布式数据存储的特点和功能&#xff0c;并提供示例代码展示其使用方法。 正文&#xff1a; 一、引言 Redis是一个开源的内存…