python+opencv+机器学习车牌识别 计算机竞赛
0 前言
🔥 优质竞赛项目系列,今天要分享的是
🚩 基于机器学习的车牌识别系统
🥇学长这里给一个题目综合评分(每项满分5分)
- 难度系数:4分
- 工作量:4分
- 创新点:3分
该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!
🧿 更多资料, 项目分享:
https://gitee.com/dancheng-senior/postgraduate
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识别字符
定义
    class SVM(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)#训练svmdef train(self, samples, responses):self.model.train(samples, cv2.ml.ROW_SAMPLE, responses)
调用方法,喂数据
    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"):if len(os.path.basename(root)) > 1:continueroot_int = ord(os.path.basename(root))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(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 = Nonefor i, color in enumerate(colors):if color in ("blue", "yello", "green"):card_img = card_imgs[i]gray_img = cv2.cvtColor(card_img, cv2.COLOR_BGR2GRAY)#黄、绿车牌字符比背景暗、与蓝车牌刚好相反,所以黄、绿车牌需要反向if color == "green" or color == "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)if len(wave_peaks) == 0:print("peak less 0:")continue#认为水平方向,最大的波峰为车牌区域wave = max(wave_peaks, key=lambda x: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) #车牌字符数应大于6if len(wave_peaks) <= 6:print("peak less 1:", len(wave_peaks))continuewave = max(wave_peaks, key=lambda x:x[1]-x[0])max_wave_dis = wave[1] - wave[0]#判断是否是左侧车牌边缘if wave_peaks[0][1] - wave_peaks[0][0] < max_wave_dis/3 and wave_peaks[0][0] == 0:wave_peaks.pop(0)#组合分离汉字cur_dis = 0for i,wave in enumerate(wave_peaks):if wave[1] - wave[0] + cur_dis > max_wave_dis * 0.6:breakelse:cur_dis += wave[1] - wave[0]if i > 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]if point[1] - point[0] < max_wave_dis/3:point_img = gray_img[:,point[0]:point[1]]if np.mean(point_img) < 255/5:wave_peaks.pop(2)if len(wave_peaks) <= 6:print("peak less 2:", len(wave_peaks))continuepart_cards = seperate_card(gray_img, wave_peaks)for i, part_card in enumerate(part_cards):#可能是固定车牌的铆钉if np.mean(part_card) < 255/5:print("a point")continuepart_card_old = part_cardw = 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])if i == 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])#判断最后一个数是否是车牌边缘,假设车牌边缘被认为是1if charactor == "1" and i == len(part_cards)-1:if part_card_old.shape[0]/part_card_old.shape[1] >= 7:#1太细,认为是边缘continuepredict_result.append(charactor)roi = card_imgcard_color = colorbreakreturn predict_result, roi, card_color#识别到的字符、定位的车牌图像、车牌颜色    
2.4 最终效果
最后算法部分可以和你想要的任何UI配置到一起:
可以这样 :
 
也可以这样:
 
甚至更加复杂一点:
 
最后
🧿 更多资料, 项目分享:
https://gitee.com/dancheng-senior/postgraduate
相关文章:
 
python+opencv+机器学习车牌识别 计算机竞赛
0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 基于机器学习的车牌识别系统 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:4分工作量:4分创新点:3分 该项目较为新颖,适…...
魔域服务端数据库说明
Magic.DB MagID: 魔法ID Mag:Magic MagName: 魔法名称 EffectType: 效果类型 Effect: 效果 Spell: 魔力(魔法值) Power: 能力,力量 MaxPower: 最大能力 DefSpell: 变化后的魔力Def:deformation DefPower: 变化后能力 DefMaxPower:…...
 
笔记本无线网卡MAC一直改动
今天在网管处把我无线网卡的MAC地址添加后,回来链接无线网却一直显示网络链接失败,以为是自己的驱动问题,去官网下载了最新的驱动结果依然无法链接。之前在家或者公共场合链接WiFi从来没有出现过类似情况。 百思不得其解之际发现自己的无线网…...
 
【Tomcat】Apache发布两个新版本Tomcat修复多个Bug
Apache 官网发布了两个最新的 Tomcat 版本包,分别是:8.5.94、9.0.81 这两个最新版本修复了多个漏洞,统计信息如下表所示。有关漏洞的详细信息,请查阅官方相关文档(见:参考)。 严重等级漏洞说明…...
 
Empowering Low-Light Image Enhancer through Customized Learnable Priors 论文阅读笔记
中科大、西安交大、南开大学发表在ICCV2023的论文,作者里有李重仪老师和中科大的Jie Huang(ECCV2022的FEC CVPR2022的ENC和CVPR2023的ERL的一作)喔,看来可能是和Jie Huang同一个课题组的,而且同样代码是开源的…...
LeetCode 2652. 倍数求和【数学,容斥原理】简单
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
ansible-playbook剧本
一,playbook组成: (1)Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行 (2)Variables:变量 (3)Templates&…...
 
竞赛选题 深度学习LSTM新冠数据预测
文章目录 0 前言1 课题简介2 预测算法2.1 Logistic回归模型2.2 基于动力学SEIR模型改进的SEITR模型2.3 LSTM神经网络模型 3 预测效果3.1 Logistic回归模型3.2 SEITR模型3.3 LSTM神经网络模型 4 结论5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 …...
 
机械设计师应该在工作中培养哪些良好习惯?
图纸规范 1、一定要按照制图标准设计图纸!图纸上任何一条直线(无论是点划线、粗实线、细实线等等)、数值、公差、图标等,都必须有理有据,不能想当然。图纸是产品生产的基础,无论是生产、加工、装配&#x…...
 
小程序新增功能页面
需求背景: 小程序主页面有个报名板块,我打算替换主页面报名板块菜单,迁移到我的页面里面, 替换成资讯栏目,我喜欢分享最新技术,开源课题,IT资讯,本想做成论坛的效果,由于时间问题,先替换添加板块 替换后效果: 模块功能: 添加、修改、删除、查看 文件目录:// 添…...
LeetCode每日一题——2652. Sum Multiples
文章目录 一、题目二、题解 一、题目 Given a positive integer n, find the sum of all integers in the range [1, n] inclusive that are divisible by 3, 5, or 7. Return an integer denoting the sum of all numbers in the given range satisfying the constraint. E…...
Python问答题(更新中)
1. 列表(list)和元组(tuple)有什么区别? 列表是可变的,创建后可以对其进行修改;元组是不可变的,元组一旦创建,就不能对其进行更改。列表表示的是顺序。它们是有序序列&a…...
 
服务器中了locked勒索病毒怎么办,勒索病毒解密,数据恢复
最近一段时间内,相信很多使用金蝶或用友的办公软件的企业,有很多都经历了locked勒索病毒的攻击,导致企业服务器被加密无法正常使用,严重影响了企业的正常工作。通过云天数据恢复中心的解密恢复发现,在今年locked勒索病…...
 
游游的字母串 (环形数组两点之间的位置)
题目链接:登录—专业IT笔试面试备考平台_牛客网 题目: 样例: 输入 yab 输出 3 思路: 暴力枚举,全部变成对应的26个字母字符需要的操作步数,取最少的一个操作步数, 这里的操作步数࿰…...
 
Flink的ResourceManager详解(一)
ResourceManager 总结 一、概述 1、ResourceManager 管理 Flink 集群中的计算资源,计算资源主要来自 TaskManager 组件。 2、如果集群采用 Native【本地模式】部署,则 ResourceManager 会动态地向集群资源管理器申请 Container 并启动TaskManager&…...
Tornado 可以使用 nginx 提供负载均衡
Tornado和nginx都是网络服务器的重要组成部分,但它们在职能和使用场景上存在显著的差异。 Tornado可以独立运行,而不需要依赖nginx等其他Web服务器。这是因为Tornado本身就是一个完整的Web服务器,可以独立处理HTTP请求并返回响应数据。 ngi…...
 
Golang 面向对象编程 多态
基本介绍 变量(实例)具有多种形态。面向对象的第三大特征,在Go语言,多态特征是通过接口实现的(接口能够体现多态的特征)。可以按照统一的接口来调用不同的实现。这时接口变量就呈现不同的形态。 在前面的Usb接口案例,u…...
 
WLAN 无线案例(华为AC控制器配置模板)
实验说明: 无线用户VLAN 30 192.168.30.0/24 AP和AC用VLAN 20 192.168.20.0/24 有线网段 VLAN 10 192.168.10.0/24 步骤一:全网互通 sw1: sysname sw1 # vlan batch 10 20 30 # dhcp enable # ip pool 20 gateway-list 192.168.20.1…...
 
精美的早安问候语,暖心祝福,开心每一天
1、 美好的祝福,成了清晨的主题。相互问候,是一天的开始。让我们伴着不老的岁月,永远开心快乐。早晨好! 2、 心宽似海,百福皆来,世事看淡,内心安然。随缘即福,随遇而安࿰…...
 
嵌入式养成计划-41----C++ auto--lambda表达式--C++中的数据类型转换--C++标准模板库(STL)--list--C++文件操作
九十九、auto 99.1 概念 C11引入了自动类型推导,和Python不一样,C中的自动类型推导,需要auto关键字来引导比如 :auto a 1.2; 会被编译器自动识别为 a 为 double 类型 99.2 作用 auto修饰变量,可以自动推导变量的数…...
 
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
 
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
 
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
 
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
 
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
 
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
 
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
 
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
 
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
