互联网加竞赛 python 机器视觉 车牌识别 - opencv 深度学习 机器学习

news2024/11/26 11:57:48

1 前言

🔥 优质竞赛项目系列,今天要分享的是

🚩 基于python 机器视觉 的车牌识别系统

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

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

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

1 课题背景

车牌识别其实是个经典的机器视觉任务了,通过图像处理技术检测、定位、识别车牌上的字符,实现计算机对车牌的智能管理功能。如今在小区停车场、高速公路出入口、监控场所、自动收费站等地都有车牌识别系统的存在,车牌识别的研究也已逐步成熟。尽管该技术随处可见了,但其实在精度和识别速度上还需要进一步提升,自己动手实现一个车牌识别系统有利于学习和理解图像处理的先进技术。

本文详细介绍基于深度学习的中文车牌识别与管理系统,在介绍算法原理的同时,给出Python的实现代码以及PyQt的简单UI界面。在界面中可以选择需要识别的车牌视频、图片文件等。

2 效果演示

首先还是用动图先展示一下效果,系统主要实现的功能是对图片、视频中的车牌进行检测和识别,演示效果如下。

2.1 图片检测识别

在这里插入图片描述

2.2视频检测识别

在这里插入图片描述

3 车牌检测与识别

目前,智能交通系统中集成运用计算机视觉、物联网、人工智能等多种技术成为未来发展方向。其中,车牌识别(License Plate Recognition,
LPR)技术作为一项重要技术,从获取的图像中提取目标车辆的车牌信息,成为完善智能交通管理运行的基础。

由于本文介绍的是中文车牌,所以可以简单了解一下国内汽车拍照的特点:字符数为七个,包括汉字、字母和数字。车牌颜色组合中,其中最常见的组合为普通小型汽车蓝底白字和新能源汽车的渐变绿底黑字。

在这里插入图片描述

总结来说,车牌是一个有特点的图像区域,几种特征可以综合起来确定车牌定位,所以之前就有利用车牌与周围环境的差异的算法。目前常见的车牌定位算法有以下 4
种:基于颜色、纹理、边缘信息的车牌定位算法和基于人工神经网络的车牌定位算法。

如下图所示,常规的步骤包括图像采集、预处理、车牌定位、字符分割、字符识别、输出结果。深度学习技术成熟之后,端到端的网络模型使得这一过程变得简单起来。从思想上来说,基于深度学习的车牌识别实现思路主要包括两个部分:(1)车牌检测定位;(2)车牌字符识别。

在这里插入图片描述

其中,车牌的检测定位本质是一个特定的目标检测任务,即通过算法框选出属于车牌的位置坐标,以便将其与背景区分开来。可以认为检测出的车牌位置才是我们的感兴趣区域。好用的方法如Cascade
LBP,它是一种机器学习的方法,可以利用OpenCV训练级联分类器,依赖CPU进行计算,级联分类器的方法对于常用场景效果比较好,检测速度较快,曾经一度比较流行,但准确率一般。基于深度学习的检测算法有Mobilene-
SSD、YOLO-v5等,利用大批量的标注数据进行训练.

当ROI被检测出来,如何对这一区域中的字符进行识别,这就涉及到采取的处理方式。第一种处理方式,首先利用一系列字符分割的算法将车牌中的字符逐个分开,然后基于深度学习进行字符分类,得到识别结果;第二种,区别于第一种先分割再分类的两步走方式,利用端到端的CTC(
Connectionist Temporal Classification)网络直接进行识别。

这里我们使用网上开源的HyperLPR中文车牌识别框架,首先导入OpenCV和hyperlpr,读取一张车牌图片调用架构中的车牌识别方法获得结果,以下代码来自官方的示例:

    #导入包
    from hyperlpr import *
    #导入OpenCV库
    import cv2
    #读入图片
    image = cv2.imread("demo.jpg")
    #识别结果
    print(HyperLPR_plate_recognition(image))

以上代码运行结果如下,可以看出该方法识别了车牌的车牌字符、置信度值、车牌位置坐标、图片尺寸等结果。

在这里插入图片描述

这样的结果还不够直观,我们写一个函数将车牌的识别结果标注在图片上,首先导入相关依赖包,其代码如下:

    # 导入包
    from hyperlpr import *
    # 导入OpenCV库
    import cv2 as cv
    from PIL import Image, ImageDraw, ImageFont
    import numpy as np

新建一个函数drawRectBox,将图像数据、识别结果、字体等参数传入,函数内部利用OpenCV和PIL库添加标注框和识别结果的字符,其代码如下:

    def drawRectBox(image, rect, addText, fontC):
        cv.rectangle(image, (int(round(rect[0])), int(round(rect[1]))),
                     (int(round(rect[2]) + 8), int(round(rect[3]) + 8)),
                     (0, 0, 255), 2)
        cv.rectangle(image, (int(rect[0] - 1), int(rect[1]) - 16), (int(rect[0] + 75), int(rect[1])), (0, 0, 255), -1, cv.LINE_AA)
        img = Image.fromarray(image)
        draw = ImageDraw.Draw(img)
        draw.text((int(rect[0] + 1), int(rect[1] - 16)), addText, (255, 255, 255), font=fontC)
        imagex = np.array(img)
        return imagex

我们首先读取图片文件,利用前面的HyperLPR_plate_recognition方法识别出车牌结果,调用以上函数获得带标注框的图片,利用OpenCV的imshow方法显示结果图片,其代码如下:

    image = cv.imread('test3.jpeg')  # 读取选择的图片
    res_all = HyperLPR_plate_recognition(image)
    fontC = ImageFont.truetype("./platech.ttf", 14, 0)
    res, confi, axes = res_all[0]
    image = drawRectBox(image, axes, res, fontC)
    cv.imshow('Stream', image)
    c = cv.waitKey(0) & 0xff

此时运行以上代码可以得到如下结果:

在这里插入图片描述

同理,识别视频中的车牌也可以做类似的操作,不过我们需要先对视频文件进行逐帧读取,然后采用以上的方式在图片中标识出车牌并显示。

这部分代码如下:

    
capture = cv.VideoCapture("./车牌检测.mp4")  # 读取视频文件
fontC = ImageFont.truetype("./platech.ttf", 14, 0)  # 字体,用于标注图片
​    

i = 1
while (True):
    ref, frame = capture.read()
    if ref:
        i = i + 1
        if i % 5 == 0:
            i = 0
            res_all = HyperLPR_plate_recognition(frame)  # 识别车牌
            if len(res_all) > 0:
                res, confi, axes = res_all[0]  # 获取结果
                frame = drawRectBox(frame, axes, res, fontC)
            cv.imshow("num", frame)  # 显示画面if cv.waitKey(1) & 0xFF == ord('q'):break  # 退出else:break

以上代码每5帧识别一次视频中的车牌,将车牌的结果标注在画面中进行实时显示,运行结果的截图如下所示:
在这里插入图片描述

车牌的识别部分代码演示完毕,对此我们完成了图片和视频的识别,然而这些还是简单的脚本呈现。为了方便更换图片、视频以及管理车牌,还需要设计文件选择功能以及系统的UI界面。这部分代码如下:

    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName("MainWindow")
            MainWindow.resize(800, 600)
            self.centralwidget = QtWidgets.QWidget(MainWindow)
            self.centralwidget.setObjectName("centralwidget")
            self.openimage = QtWidgets.QPushButton(self.centralwidget)
            self.openimage.setGeometry(QtCore.QRect(20, 40, 91, 51))
            self.openimage.setObjectName("openimage")
            self.showlabel = QtWidgets.QLabel(self.centralwidget)
            self.showlabel.setGeometry(QtCore.QRect(110, 10, 471, 441))
            self.showlabel.setObjectName("showlabel")
            self.LPRdetect = QtWidgets.QPushButton(self.centralwidget)
            self.LPRdetect.setGeometry(QtCore.QRect(20, 150, 81, 51))
            self.LPRdetect.setObjectName("LPRdetect")
            self.LPR_Rec = QtWidgets.QPushButton(self.centralwidget)
            self.LPR_Rec.setGeometry(QtCore.QRect(20, 292, 75, 31))
            self.LPR_Rec.setObjectName("LPR_Rec")
            self.lineEdit_result = QtWidgets.QLineEdit(self.centralwidget)
            self.lineEdit_result.setGeometry(QtCore.QRect(20, 400, 101, 41))
            self.lineEdit_result.setObjectName("lineEdit_result")
            self.openvideo = QtWidgets.QPushButton(self.centralwidget)
            self.openvideo.setGeometry(QtCore.QRect(20, 360, 75, 23))
            self.openvideo.setObjectName("openvideo")
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QtWidgets.QMenuBar(MainWindow)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
            self.menubar.setObjectName("menubar")
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QtWidgets.QStatusBar(MainWindow)
            self.statusbar.setObjectName("statusbar")
            MainWindow.setStatusBar(self.statusbar)
            self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.openimage.setText(_translate("MainWindow", "打开图片"))
        self.showlabel.setText(_translate("MainWindow", "TextLabel"))
        self.LPRdetect.setText(_translate("MainWindow", "车牌检测"))
        self.LPR_Rec.setText(_translate("MainWindow", "车牌识别"))
        self.openvideo.setText(_translate("MainWindow", "PushButton"))

4 HyperLPR库

4.1 简介

HyperLPR是一个使用深度学习针对对中文车牌识别的实现,与较为流行的开源的EasyPR相比,它的检测速度和鲁棒性和多场景的适应性都要好于目前开源的EasyPR,HyperLPR可以识别多种中文车牌包括白牌,新能源车牌,使馆车牌,教练车牌,武警车牌等。

4.2 特点

  • 基于端到端sequence模型,无需进行字符分割,识别速度更快。
  • 速度快 720p ,单核 Intel 2.2G CPU (macbook Pro 2015)平均识别时间<=90ms
  • 识别率高,仅仅针对车牌ROI在EasyPR数据集上,0-error达到 95.2%, 1-error识别率达到 97.4% (指在定位成功后的车牌识别率)
  • 轻量总代码量不超1k行。
  • 带有Android实现,其Android Demo可解决一些在一些普通业务场景(如执法记录仪)下的车牌识别任务。
  • 支持多种车牌的识别,详情见如下

4.3 HyperLPR的检测流程

  • 使用opencv的HAAR Cascade检测车牌大致位置
  • Extend检测到的大致位置的矩形区域
  • 使用类似于MSER的方式的多级二值化和RANSAC拟合车牌的上下边界
  • 使用CNN Regression回归车牌左右边界
  • 使用基于纹理场的算法进行车牌校正倾斜
  • 使用CNN滑动窗切割字符
  • 使用CNN识别字符

4.4 安装


​ pip install hyperlpr

4.5 Python 依赖

  • Keras (>2.0.0)

  • Theano(>0.9) or Tensorflow(>1.1.x)

  • Numpy (>1.10)

  • Scipy (0.19.1)

  • OpenCV(>3.0)

  • Scikit-image (0.13.0)

  • PIL

  • 使用CNN识别字符

5 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1311636.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

掌握iText:轻松处理PDF文档-高级篇-添加页眉和页脚

推荐语 本文介绍了如何使用iText编程库为PDF文档添加自定义的页眉和页脚。通过指定位置、大小、字体和颜色等属性&#xff0c;你可以将文本、图像或其他元素添加到每一页的固定位置&#xff0c;实现专业、可读的自定义页眉和页脚效果。这对于需要批量处理大量PDF文档或需要更精…

基于轻量级GhostNet模型开发构建工业生产制造场景下滚珠丝杠传动表面缺陷图像识别系统

轻量级识别模型在我们前面的博文中已经有过很多实践了&#xff0c;感兴趣的话可以自行移步阅读&#xff1a; 《移动端轻量级模型开发谁更胜一筹&#xff0c;efficientnet、mobilenetv2、mobilenetv3、ghostnet、mnasnet、shufflenetv2驾驶危险行为识别模型对比开发测试》 《基…

YOLOv5改进 | 2023卷积篇 | AKConv轻量级架构下的高效检测(既轻量又提点)

一、本文介绍 本文给大家带来的改进内容是AKConv是一种创新的变核卷积&#xff0c;它旨在解决标准卷积操作中的固有缺陷&#xff08;采样形状是固定的&#xff09;&#xff0c;AKConv的核心思想在于它为卷积核提供了任意数量的参数和任意采样形状&#xff0c;能够使用任意数量…

***Cpolar配置外网访问和Dashy

Dashy是一个开源的自托管的导航页配置服务,具有易于使用的可视化编辑器、状态检查、小工具和主题等功能。你可以将自己常用的一些网站聚合起来放在一起,形成自己的导航页。一款功能超强大,颜值爆表的可定制专属导航页工具 结合cpolar内网工具,我们实现无需部署到公网服务器…

Spring Boot 3 整合 WebSocket (STOMP协议) 和 Vue 3 实现实时通信

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

基于 Webpack5 Module Federation 的业务解耦实践

前言 本文中会提到很多目前数栈中使用的特定名词&#xff0c;统一做下解释描述 dt-common&#xff1a;每个子产品都会引入的公共包(类似 NPM 包) AppMenus&#xff1a;在子产品中快速进入到其他子产品的导航栏&#xff0c;统一维护在 dt-common 中&#xff0c;子产品从 dt-com…

【Https】工作流程

HTTPS 也是⼀个应用层协议。是在 HTTP 协议的基础上引入了⼀个加密层。 前言 由于Http是明文传输&#xff0c;因此如果有人想修改/截获数据都是非常容易&#xff0c;因此就出现了运营商劫持问题。 加密基础知识 明文密钥>密文 加密 密文密钥>明文 解密 对称加密和非对…

亚马逊云科技 re:Invent 大会 - ElastiCache Serverless模式来袭

亚马逊云科技 re:Invent 大会 - ElastiCache Serverless模式来袭 本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道。 文章目录 亚马逊云…

jenkins 运行接口自动化测试脚本,安装第三方依赖库的一些总结

之前在做接口自动化时&#xff0c;jenkins 执行 job 安装 requirements.txt 中的第三方依赖库时折腾了许久&#xff0c;网上查的解决方案均未生效&#xff0c;后来找出一条解决方法&#xff0c;做个记录&#xff0c;希望帮助到遇到同样问题的小伙伴。 我们都知道可以通过生成 …

软考机考考试第一批经验分享

由于机考的特殊性&#xff0c;考试环境与传统笔试环境有所不同。下面是与考试环境相关的总结&#xff1a; 草稿纸&#xff1a;考场提供足够数量的草稿纸&#xff0c;每位考生都会分发一张白纸作为草稿纸。在草稿纸上需要写上准考证号。如果不够用&#xff0c;可以向监考老师再次…

Android 11.0 framework关于systemUI状态栏透明背景的功能实现

1.概述 在11.0的系统rom产品定制化开发中,在对于系统原生SystemUI的状态栏背景在沉浸式状态栏的 情况下默认是会随着背景颜色的变化而改变的,在一些特定背景下状态栏的背景也是会改变的,所以由于产品开发需要 要求需要设置状态栏背景为透明的,所以就需要在Activity创建的时…

排序算法(二)-冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、基数排序

排序算法(二) 前面介绍了排序算法的时间复杂度和空间复杂数据结构与算法—排序算法&#xff08;一&#xff09;时间复杂度和空间复杂度介绍-CSDN博客&#xff0c;这次介绍各种排序算法——冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、基数排序。 文章目录 排…

web前端之正弦波浪动功能、repeat、calc

MENU 效果图htmlstylecalcrepeat 效果图 html <div class"grid"><span class"line"></span><span class"line"></span><span class"line"></span><span class"line"><…

Python采集知乎专栏文章保存成pdf

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 环境使用: Python 3.8 Pycharm wkhtmltopdf 软件 – 文末获取 模块使用: requests >>> pip install requests 数据请求 parsel >>> pip install parsel 数据解析 re >>> 内置模块 不需要安装…

linux 防火墙systemctl (个人笔记)

查看 systemctl status firewalld 开启 systemctl start firewalld 关闭 systemctl stop firewalld.service 查看所有 firewall-cmd --zonepublic --list-ports 开放端口&#xff1a;// --permanent 永久生效,没有此参数重启后失效 firewall-cmd --zonepublic --add-port9527/…

[PyTorch][chapter 7][李宏毅深度学习][深度学习简介]

前言&#xff1a; 深度学习常用的开发平台 TensorFlow torch theano caffe DSSTNE mxnet libdnn CNTK 目录&#xff1a; 1&#xff1a; 深度学习发展历史 2&#xff1a; DeepLearning 工程简介 3&#xff1a; DNN 简介 一 发展历史 二 DeepLearning 工程简介 深度学习三…

如何删除/替换3D模型的材质贴图

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 在3D设计和动画领域&#xff0c;材质是呈现真实感和逼真效果的关键因…

从广东到俄罗斯:一段跨越万里的电子消费展之旅

作为一名广东电子消费品行业的从业者&#xff0c;我们经常要奔赴全球不同国家拓展海外业务&#xff0c;而展会就是重要的平台。最近大家在热议的俄罗斯国际消费类电子电器展我参加过一届&#xff0c;跨越万里的旅程&#xff0c;让我深刻体会到了这种国际展览的魅力和挑战。 我参…

Mac部署Odoo环境-Odoo本地环境部署

Odoo本地环境部署 安装Python安装Homebrew安装依赖brew install libxmlsec1 Python运行环境Pycharm示例配置 Mac部署Odoo环境-Odoo本地环境部署 安装Python 新机&#xff0c;若系统没有预装Python&#xff0c;则安装需要版本的Python 点击查询Python官网下载 安装Homebrew 一…

实战——Mac M2 安装mat工具

线上环境出现内存飙升的情况&#xff0c;需要工具定位问题发生点就需要用到mat工具了&#xff0c;之前都是在intel芯片环境上安装的&#xff0c;现在换了m2芯片&#xff0c;导致出现了问题&#xff0c;经过一系列调研都解决了&#xff0c;特此记录下&#xff0c;以备后查 开发…