基于OpenCV 的车牌识别
基于OpenCV 的车牌识别
车牌识别是一种图像处理技术,用于识别不同车辆。这项技术被广泛用于各种安全检测中。现在让我一起基于 OpenCV 编写 Python 代码来完成这一任务。
车牌识别的相关步骤
1. 车牌检测:第一步是从汽车上检测车牌所在位置。我们将使用 OpenCV 中矩形的轮廓检测来寻找车牌。如果我们知道车牌的确切尺寸,颜色和大致位置,则可以提高准确性。通常,也会将根据摄像机的位置和该特定国家 / 地区所使用的车牌类型来训练检测算法。但是图像可能并没有汽车的存在,在这种情况下我们将先进行汽车的,然后是车牌。
2. 字符分割:检测到车牌后,我们必须将其裁剪并保存为新图像。同样,这可以使用 OpenCV 来完成。
3. 字符识别:现在,我们在上一步中获得的新图像肯定可以写上一些字符(数字 / 字母)。因此,我们可以对其执行 OCR(光学字符识别)以检测数字。
1. 车牌检测
让我们以汽车的样本图像为例,首先检测该汽车上的车牌。然后,我们还将使用相同的图像进行字符分割和字符识别。如果您想直接进入代码而无需解释,则可以向下滚动至此页面的底部,提供完整的代码,或访问以下链接。https://github.com/GeekyPRAVEE/OpenCV-Projects/blob/master/LicensePlateRecoginition.ipynb
在次使用的测试图像如下所示。
图片来源链接:https : //rb.gy/lxmiuv
第 1 步: 将图像调整为所需大小,然后将其灰度。相同的代码如下
img = cv2.resize(img, (620,480) )
调整大小后,可以避免使用较大分辨率的图像而出现的以下问题,但是我们要确保在调整大小后,车号牌仍保留在框架中。在处理图像时如果不再需要处理颜色细节,那么灰度变化就必不可少,这加快了其他后续处理的速度。完成此步骤后,图像将像这样被转换
步骤 2:每张图片都会包含有用和无用的信息,在这种情况下,对于我们来说,只有牌照是有用的信息,其余的对于我们的程序几乎是无用的。这种无用的信息称为噪声。通常,使用双边滤波(模糊)会从图像中删除不需要的细节。
gray = cv2.bilateralFilter(gray, 13, 15, 15)
语法为 destination_image = cv2.bilateralFilter(source_image, diameter of pixel, sigmaColor, sigmaSpace)。我们也可以将 sigma 颜色和 sigma 空间从 15 增加到更高的值,以模糊掉更多的背景信息,但请注意不要使有用的部分模糊。输出图像如下所示可以看到该图像中的背景细节(树木和建筑物)模糊了。这样,我们可以避免程序处理这些区域。
步骤 3:下一步是我们执行边缘检测的有趣步骤。有很多方法可以做到,最简单和流行的方法是使用 OpenCV 中的 canny edge 方法。执行相同操作的行如下所示
edged = cv2.Canny(gray, 30, 200) #Perform Edge detection
语法为 destination_image = cv2.Canny(source_image,thresholdValue 1,thresholdValue 2)。阈值谷 1 和阈值 2 是最小和最大阈值。仅显示强度梯度大于最小阈值且小于最大阈值的边缘。结果图像如下所示
步骤 4:现在我们可以开始在图像上寻找轮廓
contours=cv2.findContours(edged.copy(),cv2.RETR_TREE,
一旦检测到计数器,我们就将它们从大到小进行排序,并只考虑前 10 个结果而忽略其他结果。在我们的图像中,计数器可以是具有闭合表面的任何事物,但是在所有获得的结果中,牌照号码也将存在,因为它也是闭合表面。
为了过滤获得的结果中的车牌图像,我们将遍历所有结果,并检查其具有四个侧面和闭合图形的矩形轮廓。由于车牌肯定是四边形的矩形。
for c in cnts:
找到正确的计数器后,我们将其保存在名为 screenCnt 的变量中,然后在其周围绘制一个矩形框,以确保我们已正确检测到车牌。
步骤 5:现在我们知道车牌在哪里,剩下的信息对我们来说几乎没有用。因此,我们可以对整个图片进行遮罩,除了车牌所在的地方。相同的代码如下所示
# Masking the part other than the number plate
被遮罩的新图像将如下所示
2. 字符分割
车牌识别的下一步是通过裁剪车牌并将其保存为新图像,将车牌从图像中分割出来。然后,我们可以使用此图像来检测其中的字符。下面显示了从主图像裁剪出 ROI(感兴趣区域)图像的代码
# Now crop
结果图像如下所示。通常添加到裁剪图像中,如果需要,我们还可以对其进行灰色处理和边缘化。这样做是为了改善下一步的字符识别。但是我发现即使使用原始图像也可以正常工作。
3. 字符识别
该车牌识别的最后一步是从分割的图像中实际读取车牌信息。就像前面的教程一样,我们将使用 pytesseract 包从图像读取字符。相同的代码如下
#Read the number plate
原始图像上印有数字 “CZ20FSE”,并且我们的程序检测到它在 jupyter 笔记本上打印了相同的值。
车牌识别失败案例
车牌识别的完整代码,其中包含程序和我们用来检查程序的测试图像。要记住,此方法的结果将不准确。准确度取决于图像的清晰度,方向,曝光等。为了获得更好的结果,您可以尝试同时实现机器学习算法。
这个案例中我们的程序能够正确检测车牌并进行裁剪。但是,Tesseract 库无法正确识别字符。OCR 已将其识别为 “MH13CD 0036”,而不是实际的 “ MH 13 CD 0096”。通过使用更好的方向图像或配置 Tesseract 引擎,可以纠正此类问题。
其他成功的例子
大多数时候,图像质量和方向都是正确的,程序能够识别车牌并从中读取编号。下面的快照显示了获得的成功结果。
完整代码
#@programming_fever
Github 链接 - https: //github.com/GeekyPRAVEE/OpenCV-Projects/blob/master/LicensePlateRecoginition.ipynb
相关文章:

基于OpenCV 的车牌识别
基于OpenCV 的车牌识别 车牌识别是一种图像处理技术,用于识别不同车辆。这项技术被广泛用于各种安全检测中。现在让我一起基于 OpenCV 编写 Python 代码来完成这一任务。 车牌识别的相关步骤 1. 车牌检测:第一步是从汽车上检测车牌所在位置。我们将使用…...

C#【必备技能篇】Winform跨线程更新进度条的实例
文章目录实例一:【方便理解,常用!】源码:运行效果:实例二:【重在理解代码本身】源码:运行效果:参考:实例一:【方便理解,常用!】 跨线…...

(1分钟速通面试) 矩阵分解相关内容
矩阵分解算法--总结QR分解 LU分解本篇博客总结一下QR分解和LU分解,这些都是矩阵加速的操作,在slam里面还算是比较常用的内容,这个地方在isam的部分出现过。(当然isam也是一个坑,想要出点创新成果的话 可能是不太现实的 短期来讲 哈…...
this指向
(1)在全局环境中的this——window 无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this 都指向全局对象。 "use strict"console.log(this); //windowconsole.log(thiswindow);//true (…...

安卓小游戏:小板弹球
安卓小游戏:小板弹球 前言 这个是通过自定义View实现小游戏的第三篇,是小时候玩的那种五块钱的游戏机上的,和俄罗斯方块很像,小时候觉得很有意思,就模仿了一下。 需求 这里的逻辑就是板能把球弹起来,球…...

7、单行函数
文章目录1 函数的理解1.1 什么是函数1.2 不同DBMS函数的差异1.3 MySQL的内置函数及分类2 数值函数2.1 基本函数2.2 角度与弧度互换函数2.3 三角函数2.4 指数与对数2.5 进制间的转换3 字符串函数4 日期和时间函数4.1 获取日期、时间4.2 日期与时间戳的转换4.3 获取月份、星期、星…...
华为机试题:HJ56 完全数计算(python)
文章目录博主精品专栏导航知识点详解1、input():获取控制台(任意形式)的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方法2、print() :打印输出。3、整型int() :将指定进制…...

opencv——傅里叶变换、低通与高通滤波及直方图等操作
1、傅里叶变换a、傅里叶变换原理时域分析:以时间为参照进行分析。频域分析:相当于上帝视角一样,看事物层次更高,时域的运动在频域来看就是静止的。eg:投球——时域分析:第1分钟投了3分,第2分钟投…...

【NGINX入门指北】 进阶篇
nginx 进阶篇 文章目录nginx 进阶篇一、Nginx Proxy 服务器1、代理原理2、proxy代理3、proxy缓存一、Nginx Proxy 服务器 1、代理原理 正向代理 内网客户机通过代理访问互联网,通常要设置代理服务器地址和端口。 反向代理 外网用户通过代理访问内网服务器&…...

Python中关于@修饰符、yeild关键词、next()函数的基本功能简述
关于修饰符:其实就是将修饰符下面的函数当成参数传给它上面的函数。 def a(x):print(a)adef b():print(b) 其效果等价为: def a(x):print(a)def b():print(b)a(b())有个记忆诀窍,的下面哪个函数最近,谁就是儿子,谁就…...
结合Coverity扫描Spring Boot项目进行Path Manipulation漏洞修复
本篇介绍使用Coverity 扫描基于Spring Boot 项目中的Path Manipulation 漏洞, 进而解决风险,并且可以通过扫描。 什么样的代码会被扫描有路径操纵风险? 在Spring Boot 项目中, 实验了如下的场景: 1. Control 中 file path 作为参数传递的会被扫描,单纯服务方法不会 场…...

【FFMPEG源码分析】从ffplay源码摸清ffmpeg框架(一)
ffplay入口 ffmpeg\fftools\ffplay.c int main(int argc, char **argv) {/*******************start 动态库加载/网络初始化等**************/int flags;VideoState *is;init_dynload();av_log_set_flags(AV_LOG_SKIP_REPEATED);parse_loglevel(argc, argv, options);/* regis…...
C++蓝桥杯 基础练习,高精度加法,输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。
C蓝桥杯 基础练习,高精度加法 问题描述 输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。 算法描述 由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储。对于这种问题,一般使用数组来处理。 定义一…...

MySQL面试题:SQL语句的基本语法
MySQL目录一、数据库入门1. 数据管理技术的三个阶段2. 关系型数据库与非关系型数据库3. 四大非关系型数据库a. 基于列的数据库(column-oriented)b. 键值对存储(Key-Value Stores)c. 文档存储(Document Storesÿ…...

Fluid-数据编排能力原理解析
前言本文对Fluid基础功能-数据编排能力进行原理解析。其中涉及到Fluid架构和k8s csi driver相关知识。建议先了解相关概念,为了便于理解,本文使用JuiceFS作为后端runtime引擎。原理概述Fuild数据编排能力,主要是在云原生环境中,能…...

并发线程、锁、ThreadLocal
并发编程并发编程Java内存模型(JMM)并发编程核心问题—可见性、原子性、有序性volatile关键字原子性原子类CAS(Compare-And-Swap 比较并交换)ABA问题Java中的锁乐观锁和悲观锁可重入锁读写锁分段锁自旋锁共享锁/独占锁公平锁/非公平锁偏向锁/轻量级锁/重…...

CMMI-结项管理
结项管理(ProjectClosing Management, PCM)是指在项目开发工作结束后,对项目的有形资产和无形资产进行清算;对项目进行综合评估;总结经验教训等。结项管理过程域是SPP模型的重要组成部分。本规范阐述了结项管理的规程&…...

网络通信协议是什么?
网络通信基本模式 常见的通信模式有如下2种形式:Client-Server(CS) 、 Browser/Server(BS) 实现网络编程关键的三要素 IP地址:设备在网络中的地址,是唯一的标识。 端口:应用程序在设备中唯一的标识。 协议: 数据在网络中传输的…...
阶段5:Java分布式与微服务实战
目录 第33-34周 Spring Cloud电商实战 一、Eureka-server模块开发 1、引入依赖 2、配置文件 3、启动注解 一、Eureka-server模块开发 第33-34周 Spring Cloud电商实战 一、Eureka-server模块开发 1、引入依赖 父项目依赖:cloud-mall-practice springboot的…...

我的创作纪念日
目录 机缘 收获 日常 憧憬 机缘 其实本来从大一上学期后半段(2017)就开始谢谢零星的博客,只不过当时是自己用hexo搭建了一个小网站,还整了个域名:jiayoudangdang.top,虽然这个早就过期; 后来发现了CSDNÿ…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...