【源码】车牌检测+QT界面+附带数据库
目录
- 1、基本介绍
- 2、基本环境
- 3、核心代码
- 3.1、车牌识别
- 3.2、车牌定位
- 3.3、车牌坐标矫正
- 4、界面展示
- 4.1、主界面
- 4.2、车牌检测
- 4.3、查询功能
- 5、演示
- 6、链接
1、基本介绍
本项目采用tensorflow,opencv,pyside6和pymql编写,pyside6用来编写UI界面,进行界面展示;tensorflow用来训练模型检测字符和车牌定位;使用opencv进行边缘检测,获取车牌区域的边缘坐标和最小外接矩形4个端点坐标,再从车牌的边缘坐标中计算出和最小外接矩形4个端点,最近的点即为平行四边形车牌的四个端点,从而实现车牌的定位和矫正;pysql主要用来实现基本的数据库读写插入功能。
2、基本环境
pyside6==6.5.0
tensorflow>=2.0.0
opencv-python==4.8.1.78
pymysql==1.0.3
3、核心代码
3.1、车牌识别
#车牌识别
def cnn_predict(cnn, Lic_img):characters = ["京", "沪", "津", "渝", "冀", "晋", "蒙", "辽", "吉", "黑", "苏", "浙", "皖", "闽", "赣", "鲁", "豫","鄂", "湘", "粤", "桂", "琼", "川", "贵", "云", "藏", "陕", "甘", "青", "宁", "新", "0", "1", "2","3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M","N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]Lic_pred = []for lic in Lic_img:lic_pred = cnn.predict(lic.reshape(1, 80, 240, 3))lic_pred = np.array(lic_pred).reshape(7, 65)if len(lic_pred[lic_pred >= 0.8]) >= 4:chars = ''for arg in np.argmax(lic_pred, axis=1): # 取每行中概率值最大的arg,将其转为字符chars += characters[arg]chars = chars[0:2] + '·' + chars[2:]Lic_pred.append((lic, chars)) # 将车牌和识别结果一并存入Lic_predreturn Lic_pred
3.2、车牌定位
#车牌定位
def unet_predict(unet, img_src_path):img_src = cv2.imdecode(np.fromfile(img_src_path, dtype=np.uint8), -1)# img_src=cv2.imread(img_src_path)if img_src.shape != (512, 512, 3):img_src = cv2.resize(img_src, dsize=(512, 512), interpolation=cv2.INTER_AREA)[:, :, :3] # dsize=(宽度,高度),[:,:,:3]是防止图片为4通道图片,后续无法reshapeimg_src = img_src.reshape(1, 512, 512, 3)img_mask = unet.predict(img_src) # 归一化除以255后进行预测img_src = img_src.reshape(512, 512, 3) # 将原图reshape为3维img_mask = img_mask.reshape(512, 512, 3) # 将预测后图片reshape为3维img_mask = img_mask / np.max(img_mask) * 255 # 归一化后乘以255img_mask[:, :, 2] = img_mask[:, :, 1] = img_mask[:, :, 0] # 三个通道保持相同img_mask = img_mask.astype(np.uint8) # 将img_mask类型转为int型return img_src, img_mask
3.3、车牌坐标矫正
def locate_and_correct(img_src, img_mask):"""该函数通过cv2对img_mask进行边缘检测,获取车牌区域的边缘坐标(存储在contours中)和最小外接矩形4个端点坐标,再从车牌的边缘坐标中计算出和最小外接矩形4个端点最近的点即为平行四边形车牌的四个端点,从而实现车牌的定位和矫正img_src: 原始图片img_mask: 通过u_net进行图像分隔得到的二值化图片,车牌区域呈现白色,背景区域为黑色定位且矫正后的车牌"""try: # contours1长度为0说明未检测到车牌contours, hierarchy = cv2.findContours(img_mask[:, :, 0], cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)except:ret, contours, hierarchy = cv2.findContours(img_mask[:, :, 0], cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)if not len(contours):# print("未检测到车牌")return [], []else:Lic_img = []img_src_copy = img_src.copy()for ii, cont in enumerate(contours):x, y, w, h = cv2.boundingRect(cont)img_cut_mask = img_mask[y:y + h, x:x + w]# contours中除了车牌区域可能会有宽或高都是1或者2这样的小噪点,# 而待选车牌区域的均值应较高,且宽和高不会非常小,因此通过以下条件进行筛选if np.mean(img_cut_mask) >= 75 and w > 15 and h > 15:rect = cv2.minAreaRect(cont) # 针对坐标点获取带方向角的最小外接矩形,中心点坐标,宽高,旋转角度box = cv2.boxPoints(rect).astype(np.int32) # 获取最小外接矩形四个顶点坐标cont = cont.reshape(-1, 2).tolist()# 由于转换矩阵的两组坐标位置需要一一对应,因此需要将最小外接矩形的坐标进行排序,最终排序为[左上,左下,右上,右下]box = sorted(box, key=lambda xy: xy[0]) # 先按照左右进行排序,分为左侧的坐标和右侧的坐标box_left, box_right = box[:2], box[2:] # 此时box的前2个是左侧的坐标,后2个是右侧的坐标box_left = sorted(box_left, key=lambda x: x[1]) # 再按照上下即y进行排序,此时box_left中为左上和左下两个端点坐标box_right = sorted(box_right, key=lambda x: x[1]) # 此时box_right中为右上和右下两个端点坐标box = np.array(box_left + box_right) # [左上,左下,右上,右下]# print(box)x0, y0 = box[0][0], box[0][1] # 这里的4个坐标即为最小外接矩形的四个坐标,接下来需获取平行(或不规则)四边形的坐标x1, y1 = box[1][0], box[1][1]x2, y2 = box[2][0], box[2][1]x3, y3 = box[3][0], box[3][1]def point_to_line_distance(X, Y):if x2 - x0:k_up = (y2 - y0) / (x2 - x0) # 斜率不为无穷大d_up = abs(k_up * X - Y + y2 - k_up * x2) / (k_up ** 2 + 1) ** 0.5else: # 斜率无穷大d_up = abs(X - x2)if x1 - x3:k_down = (y1 - y3) / (x1 - x3) # 斜率不为无穷大d_down = abs(k_down * X - Y + y1 - k_down * x1) / (k_down ** 2 + 1) ** 0.5else: # 斜率无穷大d_down = abs(X - x1)return d_up, d_downd0, d1, d2, d3 = np.inf, np.inf, np.inf, np.infl0, l1, l2, l3 = (x0, y0), (x1, y1), (x2, y2), (x3, y3)for each in cont: # 计算cont中的坐标与矩形四个坐标的距离以及到上下两条直线的距离,对距离和进行权重的添加,成功计算选出四边形的4个顶点坐标x, y = each[0], each[1]dis0 = (x - x0) ** 2 + (y - y0) ** 2dis1 = (x - x1) ** 2 + (y - y1) ** 2dis2 = (x - x2) ** 2 + (y - y2) ** 2dis3 = (x - x3) ** 2 + (y - y3) ** 2d_up, d_down = point_to_line_distance(x, y)weight = 0.975if weight * d_up + (1 - weight) * dis0 < d0: # 小于则更新d0 = weight * d_up + (1 - weight) * dis0l0 = (x, y)if weight * d_down + (1 - weight) * dis1 < d1:d1 = weight * d_down + (1 - weight) * dis1l1 = (x, y)if weight * d_up + (1 - weight) * dis2 < d2:d2 = weight * d_up + (1 - weight) * dis2l2 = (x, y)if weight * d_down + (1 - weight) * dis3 < d3:d3 = weight * d_down + (1 - weight) * dis3l3 = (x, y)p0 = np.float32([l0, l1, l2, l3]) # 左上角,左下角,右上角,右下角,p0和p1中的坐标顺序对应,以进行转换矩阵的形成p1 = np.float32([(0, 0), (0, 80), (240, 0), (240, 80)]) # 我们所需的长方形transform_mat = cv2.getPerspectiveTransform(p0, p1) # 构成转换矩阵lic = cv2.warpPerspective(img_src, transform_mat, (240, 80)) # 进行车牌矫正Lic_img.append(lic)cv2.drawContours(img_src_copy, [np.array([l0, l1, l3, l2])], -1, (0, 255, 0), 2)return img_src_copy, Lic_img
4、界面展示
4.1、主界面
主界面包括停车场容量和剩余容量显示和当前时间。
4.2、车牌检测
车牌检测与定位功能。
4.3、查询功能
按车牌查询。
所有信息记录查询
5、演示
6、链接
源码链接
相关文章:

【源码】车牌检测+QT界面+附带数据库
目录 1、基本介绍2、基本环境3、核心代码3.1、车牌识别3.2、车牌定位3.3、车牌坐标矫正 4、界面展示4.1、主界面4.2、车牌检测4.3、查询功能 5、演示6、链接 1、基本介绍 本项目采用tensorflow,opencv,pyside6和pymql编写,pyside6用来编写UI界…...

实战1-python爬取安全客新闻
一般步骤:确定网站--搭建关系--发送请求--接受响应--筛选数据--保存本地 1.拿到网站首先要查看我们要爬取的目录是否被允许 一般网站都会议/robots.txt目录,告诉你哪些地址可爬,哪些不可爬,以安全客为例子 2. 首先测试在不登录的…...

光栅化渲染:可见性问题和深度缓冲区算法
在前面第二章中,我们了解到,在投影点(屏幕空间中的点)的第三个坐标中,我们存储原始顶点 z 坐标(相机空间中点的 z 坐标): 当一个像素与多个三角形重叠时,查找三角形表面上…...

docker入门小结
docker是什么?它有什么优势? 快速获取开箱即用的程序 docker使得所有的应用传输就像我们日常通过聊天工具文件传输一样,发送方将程序传输到超级码头而接收方也只需通过超级码头进行获取即可,就像一只鲸鱼拖着货物来回运输一样。…...

LLM Agent发展演进历史(观看metagpt视频笔记)
LLM相关的6篇重要的论文,其中4篇来自谷歌,2篇来自openai。技术路径演进大致是:SSL (Self-Supervised Learning) -> SFT (Supervised FineTune) IT (Instruction Tuning) -> RLHF。 word embedding的问题:新词如何处理&…...
Linux(操作系统)面经——part2
1、请你说说进程和线程的区别 1.进程是操作系统资源分配和调度的最小单位,实现操作系统内部的并发;线程是进程的子任务,cpu可以识别、执行的最小单位,实现程序内部的并发。 2.一个进程最少有一个线程或有多个,一个线程…...
Flink系列之:WITH clause
Flink系列之:WITH clause 适用流、批提供了一种编写辅助语句以在较大查询中使用的方法。这些语句通常称为公共表表达式 (CTE),可以被视为定义仅针对一个查询而存在的临时视图。 WITH 语句的语法为: WITH <with_item_definition> [ , …...

JMeter直连数据库
JMeter直连数据库 使用场景操作步骤 使用场景 用作请求的参数化 登录时需要的用户名,密码可以从数据库中查询获取 用作结果的断言 添加购物车下订单,检查接口返回的订单号,是否与数据库中生成的订单号一致 清理垃圾数据 添加商品后ÿ…...

Linux部署MySQL5.7和8.0版本 | CentOS和Ubuntu系统详细步骤安装
一、MySQL数据库管理系统安装部署【简单】 简介 MySQL数据库管理系统(后续简称MySQL),是一款知名的数据库系统,其特点是:轻量、简单、功能丰富。 MySQL数据库可谓是软件行业的明星产品,无论是后端开发、…...
STL中set和multiset容器的用法(轻松易懂~)
目录 1. 基本概念 2. 构造和赋值 3. 大小和交换 4. 插入 和 删除 5. 统计 和 查找 6. set容器的排序 1. 基本概念 set和multiset属于关联式容器,底层结构式二叉树,所有元素都会在插入时自动排序。 如果你对容器的概念,或是二叉树不太了…...

Codeforces Round 915 (Div. 2)
Constructive Problems(Problem - A - Codeforces) 题目大意:现在有一片城市被摧毁了,需要进行重建,当一个城市水平相邻和竖直相邻的位置都至少有一个城市的时候,该城市可以被重建。所有城市排成n行m列的矩…...
C语言经典错误总结(三)
一.指针与数组理解 我们都知道定义一个数组然后对其进行各种想要的操作,但是你真的能够区分那些是对数组的操作,那些是通过指针实现的吗? 例如;arr[1]10;这个是纯粹对数组操作实现的吗? 答案肯定不是,实际上我们定义…...

Ubuntu系统入门指南:基础操作和使用
Ubuntu系统的基础操作和使用 一、引言二、安装Ubuntu系统三、Ubuntu系统的基础操作3.1、界面介绍3.2、应用程序的安装和卸载3.3、文件管理3.4、系统设置 四、Ubuntu系统的日常使用4.1、使用软件中心4.2、浏览器的使用和网络连接设置4.3、邮件客户端的配置和使用4.4、文件备份和…...

MyBatis原理解读
我们项目中多用MyBatis进行数据库的读写,开源的MyBatis-Plus框架对其进行了增强,使用上更加简单,我们之前的很多项目也是直接用的MyBatis-Plus。 数据库操作的时候,简单的单表读写,我们可以直接在方法里链式组装SQL,复杂的SQL或涉及多表联合join的,需要在xml手写SQL语句…...

Linux---文本搜索命令
1. grep命令的使用 命令说明grep文本搜索 grep命令效果图: 2. grep命令选项的使用 命令选项说明-i忽略大小写-n显示匹配行号-v显示不包含匹配文本的所有行 -i命令选项效果图: -n命令选项效果图: -v命令选项效果图: 3. grep命令结合正则表达式的使用 正则表达式说明^以指…...
Unity中Shader语义的理解
前言 以下内容主要是个人理解,如有错误,欢迎严厉批评指正。 一、语义的形式在Shader中是必要的吗? 不是必要的。 使用HLSL和CG语言来编写Shader需要语义,使用GLSL编写Shader不需要。 二、语义的意义? 语义是什么&…...
Flink系列之:Top-N
Flink系列之:Top-N 一、TOP-N二、无排名输出优化 一、TOP-N 适用于流、批Top-N 查询可以根据指定列排序后获得前 N 个最小或最大值。最小值和最大值集都被认为是Top-N查询。在需要从批表或流表中仅显示 N 个底部或 N 个顶部记录时,Top-N 查询是非常有用…...

CSS的三大特性(层叠性、继承性、优先级---------很重要)
CSS 有三个非常重要的三个特性:层叠性、继承性、优先级。 层叠性 场景:相同选择器给设置相同的样式,此时一个样式就会覆盖(层叠)另一个冲突的样式。层叠性主要解决样式冲突 的问题 原则: 样式冲突&am…...

飞天使-docker知识点10-docker总结
文章目录 docker 知识点汇总docker chatgpt解释学习路线cmd和 ENTRYPOINT 的区别harbor安装漏洞扫描 docker 知识点汇总 docker 基础用法 docker 镜像基础用法 docker 容器网络 docker 存储卷 dockerfile docker仓库 harbor docker-compose docker chatgpt解释学习路线 学习…...
旅游管理虚拟情景实训教学系统演示
首先,虚拟情景实训教学系统为旅游管理专业的学生提供了一个全新的实践平台。在传统的旅游管理教学中,学生往往只能通过理论学习来了解相关知识,而无法亲身实践。虚拟情景实训教学系统则可以通过模拟真实的旅游场景,让学生能够亲身…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...

RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上
一、软件介绍 文末提供程序和源码下载 RushDB 改变了您处理图形数据的方式 — 不需要 Schema,不需要复杂的查询,只需推送数据即可。 二、Key Features ✨ 主要特点 Instant Setup: Be productive in seconds, not days 即时设置 :在几秒钟…...