news 2026/4/28 13:11:33

毕业设计 python+opencv+机器学习车牌识别

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
毕业设计 python+opencv+机器学习车牌识别

文章目录

  • 0 前言
  • 1 课题介绍
    • 1.1 系统简介
    • 1.2 系统要求
    • 1.3 系统架构
  • 2 实现方式
    • 2.1 车牌检测技术
    • 2.2 车牌识别技术
    • 2.3 SVM识别字符
    • 2.4 最终效果

0 前言

🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

🚩基于机器学习的车牌识别系统

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:4分
  • 工作量:4分
  • 创新点:3分

🧿选题指导, 项目分享:见文末



1 课题介绍

1.1 系统简介

车牌识别这个系统,虽然传统,古老,却是包含了所有这四个特侦的一个大数据技术的缩影.

在车牌识别中,你需要处理的数据是图像中海量的像素单元;你处理的数据不再是传统的结构化数据,而是图像这种复杂的数据;如果不能在很短的时间内识别出车牌,那么系统就缺少意义;虽然一副图像中有很多的信息,但可能仅仅只有那一小块的信息(车牌)以及车身的颜色是你关心,而且这些信息都蕴含着巨大的价值。也就是说,车牌识别系统事实上就是现在火热的大数据技术在某个领域的一个聚焦,通过了解车牌识别系统,可以很好的帮助你理解大数据技术的内涵,也能清楚的认识到大数据的价值。

1.2 系统要求

  • 它基于openCV这个开源库,这意味着所有它的代码都可以轻易的获取。
  • 它能够识别中文,例如车牌为苏EUK722的图片,它可以准确地输出std:string类型的"苏EUK722"的结果。
  • 它的识别率较高。目前情况下,字符识别已经可以达到90%以上的精度。

1.3 系统架构

整体包含两个系统:

  • 车牌检测
  • 车牌字体识别(中文 + 数字 + 英文)

整体架构如下:

2 实现方式

2.1 车牌检测技术

车牌检测(Plate Detection):

对一个包含车牌的图像进行分析,最终截取出只包含车牌的一个图块。这个步骤的主要目的是降低了在车牌识别过程中的计算量。如果直接对原始的图像进行车牌识别,会非常的慢,因此需要检测的过程。在本系统中,我们使用SVM(支持向量机)这个机器学习算法去判别截取的图块是否是真的“车牌”。

车牌检测这里不详细说明, 只贴出opencv图像处理流程, 需要代码的可以留下邮箱


使用到的图像处理算法

  • 高斯模糊
  • 灰度化处理
  • Sobel算子(边缘检测)
  • 开操作
  • 闭操作
  • 仿射变换
  • 霍姆线性检测
  • 角度矫正

2.2 车牌识别技术

字符识别(Chars Recognition):

有的书上也叫Plate Recognition,我为了与整个系统的名称做区分,所以改为此名字。这个步骤的主要目的就是从上一个车牌检测步骤中获取到的车牌图像,进行光学字符识别(OCR)这个过程。其中用到的机器学习算法是著名的人工神经网络(ANN)中的多层感知机(MLP)模型。最近一段时间非常火的“深度学习”其实就是多隐层的人工神经网络,与其有非常紧密的联系。通过了解光学字符识别(OCR)这个过程,也可以知晓深度学习所基于的人工神经网路技术的一些内容。

我们这里使用深度学习的方式来对车牌字符进行识别, 为什么不用传统的机器学习进行识别呢, 看图就知道了:

图2 深度学习(右)与PCA技术(左)的对比
可以看出深度学习对于数据的分类能力的优势。

这里博主使用生成对抗网络进行字符识别训练, 效果相当不错, 识别精度达到了98%

2.3 SVM识别字符

定义

classSVM(StatModel):def__init__(self,C=1,gamma=0.5):self.model=cv2.ml.SVM_create()self.model.setGamma(gamma)self.model.setC(C)self.model.setKernel(cv2.ml.SVM_RBF)self.model.setType(cv2.ml.SVM_C_SVC)#训练svmdeftrain(self,samples,responses):self.model.train(samples,cv2.ml.ROW_SAMPLE,responses)

调用方法,喂数据

deftrain_svm(self):#识别英文字母和数字self.model=SVM(C=1,gamma=0.5)#识别中文self.modelchinese=SVM(C=1,gamma=0.5)ifos.path.exists("svm.dat"):self.model.load("svm.dat")

训练,保存模型

else:chars_train=[]chars_label=[]forroot,dirs,filesinos.walk("train\\chars2"):iflen(os.path.basename(root))>1:continueroot_int=ord(os.path.basename(root))forfilenameinfiles: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(1)chars_label.append(root_int)chars_train=list(map(deskew,chars_train))chars_train=preprocess_hog(chars_train)#chars_train = chars_train.reshape(-1, 20, 20).astype(np.float32)chars_label=np.array(chars_label)print(chars_train.shape)self.model.train(chars_train,chars_label)

车牌字符数据集如下


这些是字母的训练数据,同样的还有我们车牌的省份简写:

核心代码

predict_result=[]roi=Nonecard_color=Nonefori,colorinenumerate(colors):ifcolorin("blue","yello","green"):card_img=card_imgs[i]gray_img=cv2.cvtColor(card_img,cv2.COLOR_BGR2GRAY)#黄、绿车牌字符比背景暗、与蓝车牌刚好相反,所以黄、绿车牌需要反向ifcolor=="green"orcolor=="yello":gray_img=cv2.bitwise_not(gray_img)ret,gray_img=cv2.threshold(gray_img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)#查找水平直方图波峰x_histogram=np.sum(gray_img,axis=1)x_min=np.min(x_histogram)x_average=np.sum(x_histogram)/x_histogram.shape[0]x_threshold=(x_min+x_average)/2wave_peaks=find_waves(x_threshold,x_histogram)iflen(wave_peaks)==0:print("peak less 0:")continue#认为水平方向,最大的波峰为车牌区域wave=max(wave_peaks,key=lambdax:x[1]-x[0])gray_img=gray_img[wave[0]:wave[1]]#查找垂直直方图波峰row_num,col_num=gray_img.shape[:2]#去掉车牌上下边缘1个像素,避免白边影响阈值判断gray_img=gray_img[1:row_num-1]y_histogram=np.sum(gray_img,axis=0)y_min=np.min(y_histogram)y_average=np.sum(y_histogram)/y_histogram.shape[0]y_threshold=(y_min+y_average)/5#U和0要求阈值偏小,否则U和0会被分成两半wave_peaks=find_waves(y_threshold,y_histogram)#for wave in wave_peaks:# cv2.line(card_img, pt1=(wave[0], 5), pt2=(wave[1], 5), color=(0, 0, 255), thickness=2)#车牌字符数应大于6iflen(wave_peaks)<=6:print("peak less 1:",len(wave_peaks))continuewave=max(wave_peaks,key=lambdax:x[1]-x[0])max_wave_dis=wave[1]-wave[0]#判断是否是左侧车牌边缘ifwave_peaks[0][1]-wave_peaks[0][0]<max_wave_dis/3andwave_peaks[0][0]==0:wave_peaks.pop(0)#组合分离汉字cur_dis=0fori,waveinenumerate(wave_peaks):ifwave[1]-wave[0]+cur_dis>max_wave_dis*0.6:breakelse:cur_dis+=wave[1]-wave[0]ifi>0:wave=(wave_peaks[0][0],wave_peaks[i][1])wave_peaks=wave_peaks[i+1:]wave_peaks.insert(0,wave)#去除车牌上的分隔点point=wave_peaks[2]ifpoint[1]-point[0]<max_wave_dis/3:point_img=gray_img[:,point[0]:point[1]]ifnp.mean(point_img)<255/5:wave_peaks.pop(2)iflen(wave_peaks)<=6:print("peak less 2:",len(wave_peaks))continuepart_cards=seperate_card(gray_img,wave_peaks)fori,part_cardinenumerate(part_cards):#可能是固定车牌的铆钉ifnp.mean(part_card)<255/5:print("a point")continuepart_card_old=part_card w=abs(part_card.shape[1]-SZ)//2part_card=cv2.copyMakeBorder(part_card,0,0,w,w,cv2.BORDER_CONSTANT,value=[0,0,0])part_card=cv2.resize(part_card,(SZ,SZ),interpolation=cv2.INTER_AREA)#part_card = deskew(part_card)part_card=preprocess_hog([part_card])ifi==0:resp=self.modelchinese.predict(part_card)charactor=provinces[int(resp[0])-PROVINCE_START]else:resp=self.model.predict(part_card)charactor=chr(resp[0])#判断最后一个数是否是车牌边缘,假设车牌边缘被认为是1ifcharactor=="1"andi==len(part_cards)-1:ifpart_card_old.shape[0]/part_card_old.shape[1]>=7:#1太细,认为是边缘continuepredict_result.append(charactor)roi=card_img card_color=colorbreakreturnpredict_result,roi,card_color#识别到的字符、定位的车牌图像、车牌颜色

2.4 最终效果

最后算法部分可以和你想要的任何UI配置到一起:

可以这样 :

也可以这样:

甚至更加复杂一点:


🧿 项目分享:大家可自取用于参考学习,获取方式见文末!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/27 5:53:05

基于AD9833的DDS波形发生器设计入门必看

从零开始玩转AD9833&#xff1a;手把手教你打造高精度DDS波形发生器 你有没有遇到过这样的场景&#xff1f;调试一个音频滤波电路时&#xff0c;手头的信号源频率调不准&#xff1b;做电源环路测试需要扫频激励&#xff0c;却发现传统函数发生器响应太慢&#xff1b;甚至只是想…

作者头像 李华
网站建设 2026/4/15 17:45:39

为什么你的Java系统还不支持抗量子密钥管理?现在必须行动了

第一章&#xff1a;为什么你的Java系统还不支持抗量子密钥管理&#xff1f;现在必须行动了随着量子计算技术的突破&#xff0c;传统公钥加密体系&#xff08;如RSA、ECC&#xff09;面临前所未有的破解风险。Shor算法可在多项式时间内分解大整数&#xff0c;直接威胁现有密钥安…

作者头像 李华
网站建设 2026/4/23 17:48:27

【稀缺技术抢先看】:Java平台抗量子密钥管理的3种实现方案

第一章&#xff1a;Java平台抗量子密钥管理概述随着量子计算技术的快速发展&#xff0c;传统公钥密码体系&#xff08;如RSA、ECC&#xff09;面临被高效破解的风险。Java作为广泛应用于企业级系统的编程语言&#xff0c;其安全体系必须适应后量子密码&#xff08;Post-Quantum…

作者头像 李华
网站建设 2026/4/25 10:16:24

终极LÖVE游戏开发指南:如何用Lua快速打造2D游戏

终极LVE游戏开发指南&#xff1a;如何用Lua快速打造2D游戏 【免费下载链接】love LVE is an awesome 2D game framework for Lua. 项目地址: https://gitcode.com/gh_mirrors/lo/love 想要快速进入游戏开发世界却不知从何开始&#xff1f;LVE框架为你打开了一扇通往2D游…

作者头像 李华
网站建设 2026/4/23 13:26:09

Qwen3-VL-8B-Instruct:重塑多模态AI的轻量化革命

Qwen3-VL-8B-Instruct&#xff1a;重塑多模态AI的轻量化革命 【免费下载链接】Qwen3-VL-8B-Instruct 项目地址: https://ai.gitcode.com/hf_mirrors/Qwen/Qwen3-VL-8B-Instruct &#x1f680; 在AI技术日新月异的2025年&#xff0c;一个仅有80亿参数的"小巨人&quo…

作者头像 李华