题目基于OpenCV和Python车牌识别系统的设计与实现
1.1 题目的主要研究内容
(1)工作的主要描述
利用python中自带的opencv库中的模式识别算法制作一个简易的模式识别系统,使用自己搜集到的数据集对模型进行训练,最终完成特征提取、分类等工作,并且在最后的推理过程中,实现了车牌识别的工作。
(2)系统流程图
1.2 题目研究的工作基础或实验条件
项目的编程环境为python,编译器使用pycharm2021.3 x64,设计一个车牌识别系统,有GUI界面。选择一张有车牌的图片后,完成车牌定位、倾斜校正、字符分割,最后通过k-NN 算法对车牌的字母和数字进行识别,将识别结果在GUI界面中显示出来
1.3 数据集描述
车牌定位就是在图片中识别出哪个位置有车牌,是字符分割和字母数字识别的前提,是车牌识别系统的关键和难点。:
例如,训练数据的目录结构树如下所示:
1.4 特征提取过程描述
1.对原始图像进行高斯模糊,减少噪点。
2.提取图像边缘。首先将彩图像转为灰度图gray,利用大核对灰度图进行开操作得到图像open,相当于对灰度图进行涂抹操作,将灰度图gray和开操作后的图像open按1:-1的比例融合得到图像add,以上操作可以将大面积灰度值
相似的地方置黑,可以减少车灯、背景、地面、挡风玻璃等细节。接着使用canny 算法对融合图像add提取边缘,得到图像canny。
3.使用横向长条作为核对边缘图像进行一次闭操作,得到图像close,相当于对边缘横向涂抹,因为一般视角车牌是宽大于高的矩形。再对图像close进行一次开操作,得到图像open2,消除较细的线条和不大的竖向线条,从而将车牌位置的连通区域独立出来。
4.查连通区域,通过最小外接矩形的宽高比2~
5.5筛选合适的连通区域。
5.将最小外接矩形图像旋转矫正,上下左右向外扩展一点范围,避免连通区域没能覆盖车牌造成影响。
6.将连通区域原图转为HSV图像,确定图像的主要颜,若不为蓝、黄、绿,则排除。按照3种颜对车牌进行精细定位,缩小范围。
7.再次通过图像宽高比2.2~5.3筛选合适的位置,至此车牌定位结束
1.5 K-NN分类算法
在模式识别领域中,k-NN算法是一种用于分类和回归的非参数统计方法。在k-NN分类算法中,输入包含k个最接近的特征空间的训练样本,输出是一个分类族。一个对象的分类是由其邻近样本占多数的类别确定的,k为正整数,通常为奇数。k个最邻近样本中最多的分类类别决定了赋予该对象的类别,若k = 1 k = 1k=1,则该对象的类别直接由最近的一个节点赋予。
k-NN算法是所有的机器学习算法中最简单的之一。k个最邻近样本都是已经正确分类的对象,虽然没要求明确的训练步骤,但这也可以当作是此算法的一个训练样本集。训练样本是多维特征空间向量,其中每个训练样本带有一个类别标签。算法的训练阶段只包含存储的特征向量和训练样本的标签。k-NN算法的缺点是对数据的局部结构非常敏感。
在分类阶段,k是一个常数,项目中选取k = 7 k = 7k=7。
一般情况下,可以用欧氏距离作为距离度量。在欧几里得空间中,
k-NN算法分类会在类别分布不均时出现缺陷,也就是说,出现频率较多的样本将会影响测试样本的预测结果。因为样本更多的类别更可能出现在测试点的K 邻域,而测试点的属性又是通过k邻域内的样本计算出来的。解决这个缺点的方法之一是在进行分类时将样本到k个近邻点的距离考虑进去。k近邻点中每一个的分类都乘以与测试点之间距离的成反比的权重。
1.6 主要程序代码
from tkinter import *
import cv2
from tkinter.filedialog import *
from cv2 import *
from numpy import *
from PIL import ImageTk, Image
import operator
class recognition:
# oriImage
def open(self):
img_path = askopenfilename(initialdir='./testImage', title='选择待识别图片',
filetypes=[("jpg", "*.jpg"), ("png", "*.png")])
if img_path:
img = cv2.imdecode(fromfile(img_path, dtype=uint8), cv2.IMREAD_COLOR)
self.show(img, 400, oriImg)
colors, lisencePlates = ROI(img)
for m in range(len(lisencePlates)):
self.show(lisencePlates[m], 40, ROIImg)
letters = Letters(lisencePlates[m], colors[m])
results = []
for letter in letters:
feature = Feature(letter)
result = self.sort(feature, trainingMat, labels, 5)
results.append(result)
# print(result)
recogResult = ','.join(results)
def show(self, img, newheight, label):
global oriTk, ROITk
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = Image.fromarray(img)
height = img.height
width = img.width
scaleRatio = newheight / height
newwidth = int(width * scaleRatio)
img = size((newwidth, newheight), Image.ANTIALIAS)
if label == oriImg:
elif label == ROIImg:
self.ROITk = ImageTk.PhotoImage(image=img)
def getROI(self, img):
# oriImg = Image.fromarray(img)
# imgHeight = oriImg.height
# imgWidth = oriImg.width
# 尺寸太大则缩小
imgHeight, imgWidth = img.shape[:2]
if imgHeight > 1000:
scaleRatio = 1000 / imgHeight
imgHeight = 1000
imgWidth = int(imgWidth * scaleRatio)
img = size(img, (imgWidth, imgHeight), interpolation=cv2.INTER_AREA) oriImg = img # 保存原图副本
img = cv2.GaussianBlur(img, (3, 3), 0) # 高斯模糊
# print(img)
gaussianImg = img # 保存副本
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转灰度图
渐变颜代码大全# imshow("gray",img)
kernel = ones((20, 20), uint8)
imgOpen = phologyEx(img, cv2.MORPH_OPEN, kernel) # 开操作,突出黑
# imshow("open",imgOpen)
img = cv2.addWeighted(img, 1, imgOpen, -1, 0) # 图像融合
# imshow("add",img)
ret, img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # 二值化img = cv2.Canny(img, 100, 200) # canny算法查边缘
# imshow("canny",img)
kernel = ones((4, 19), uint8)
img = phologyEx(img, MORPH_CLOSE, kernel) # 闭操作,横向涂抹
# imshow("close",img)
# kernel = ones((4, 25), uint8)
img = phologyEx(img, MORPH_OPEN, kernel) # 开操作,去除细线
# imshow("open2",img)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论