【源码】车牌检测+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_pred
    return 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通道图片,后续无法reshape
    img_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  # 归一化后乘以255
    img_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.5
                    else:  # 斜率无穷大
                        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.5
                    else:  # 斜率无穷大
                        d_down = abs(X - x1)
                    return d_up, d_down
                d0, d1, d2, d3 = np.inf, np.inf, np.inf, np.inf
                l0, 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) ** 2
                    dis1 = (x - x1) ** 2 + (y - y1) ** 2
                    dis2 = (x - x2) ** 2 + (y - y2) ** 2
                    dis3 = (x - x3) ** 2 + (y - y3) ** 2
                    d_up, d_down = point_to_line_distance(x, y)
                    weight = 0.975
                    if weight * d_up + (1 - weight) * dis0 < d0:  # 小于则更新
                        d0 = weight * d_up + (1 - weight) * dis0
                        l0 = (x, y)
                    if weight * d_down + (1 - weight) * dis1 < d1:
                        d1 = weight * d_down + (1 - weight) * dis1
                        l1 = (x, y)
                    if weight * d_up + (1 - weight) * dis2 < d2:
                        d2 = weight * d_up + (1 - weight) * dis2
                        l2 = (x, y)
                    if weight * d_down + (1 - weight) * dis3 < d3:
                        d3 = weight * d_down + (1 - weight) * dis3
                        l3 = (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、链接

源码链接

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java架构师-数据机构与算法实战(第一篇)

数学知识回顾 指数 指数函数是重要的基本初等函数之一。一般地&#xff0c;ya^x函数(a为常数且以a>0&#xff0c;a≠1)叫做指数函数&#xff0c;函数的定义域是 R 。注意&#xff0c;在指数函数的定义表达式中&#xff0c;在a^x前的系数必须是数1&#xff0c;自变量x必须在…

ubantu22.04.3 安装4080驱动

新电脑安装驱动网卡EX211只适配22.04的内核&#xff0c;其他系统升级内核易出问题不推荐。 安装系统为系统盘安装制作Ubuntu22.04启动盘_ubuntu下制作pe启动盘-CSDN博客&#xff0c;参考此作者&#xff0c;选择系统为22.04.3 其他版本不推荐因前面用22.04安装显卡后出现兼容性…

Power BI - 5分钟学习增加索引列

每天5分钟&#xff0c;今天介绍Power BI增加索引列。 什么是增加索引列&#xff1f; 增加索引列就是向表中添加一个具有显式位置值的新列&#xff0c;一般从0或者从1开始。 举例&#xff1a; 首先&#xff0c;导入一张【Sales】样例表(Excel数据源导入请参考每天5分钟第一天)…

【Linux】tree命令使用

tree命令 tree命令用于以树状图列出目录的内容。 语法 tree [参数] [目录] tree 命令 -Linux手册页 bash: tree: 未找到命令... 安装tree yum -y install tree如果你系统中有安装tree 但是还是执行找不到该命令的话&#xff0c;那原因就是&#xff1a;环境变量错误&#x…

Google Shopping Action

Google Shopping Action是Google推出的一项在线购物服务&#xff0c;可以帮助零售商将产品推广和销售到Google平台上的消费者中。通过Google Shopping Action&#xff0c;用户可以在谷歌搜索页面上直接购买商品&#xff0c;而不需要离开搜索结果页面。 Google Shopping Action的…

神通数据库字段空与非空

神通数据库可以在建表时指定字段非空或可空&#xff0c; -- 指定column1字段非空 CREATE TABLE SYSDBA.tmp_test1(column1 varchar(100) NOT NULL)--尝试向column1字段插入空值 INSERT INTO SYSDBA.tmp_test1(column1) VALUES(NULL) 会收到插入失败的提示&#xff1a; 而如果…

基于JavaWeb实现的勤工俭学管理系统

一、系统架构 前端&#xff1a;jsp | js | css | jquery | layui 后端&#xff1a;spring | springmvc | mybatis 环境&#xff1a;jdk1.8 | mysql 二、代码及数据库 三、功能介绍 01. web端-首页 02. web端-论坛 03. web端-个人中心 04. web端-平台公告 05. web端-平…

音视频技术开发周刊 | 323

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 Meta牵头组建开源「AI复仇者联盟」&#xff0c;AMD等盟友800亿美元力战OpenAI英伟达 超过50家科技大厂名校和机构&#xff0c;共同成立了全新的人工智能联盟。以开源为旗号…

CBTC上海新能源锂电池展览会奋战华东!2024携手共赢!

2024CBTC上海新能源锂电池技术展览会|上海锂离子电池生产设备展览会 时 间&#xff1a;2024年7月24&#xff5e;26日 地 点&#xff1a;国家会展中心&#xff08;上海虹桥&#xff09; 发展前景&#xff1a; 随着科技的不断进步&#xff0c;锂电池市场逐渐成为全球能源市场的…

@Transactional注解详细使用

Transactional注解详细使用 Transactional注解是Spring框架中用于管理事务的注解&#xff0c;它可以应用于类或方法上。使用该注解可以确保一个方法或类中的操作要么全部成功提交&#xff0c;要么全部回滚&#xff0c;从而保证数据的完整性和一致性。下面是Transactional注解的…

Gradio入门详细教程

常用的两款AI可视化交互应用比较&#xff1a; Gradio Gradio的优势在于易用性&#xff0c;代码结构相比Streamlit简单&#xff0c;只需简单定义输入和输出接口即可快速构建简单的交互页面&#xff0c;更轻松部署模型。适合场景相对简单&#xff0c;想要快速部署应用的开发者。便…

力扣二叉树--总结篇(2)

前言 总体回顾&#xff1a;11.18-12.14&#xff0c;中间有一个星期左右因为考试没有写题。37道题。 内容 这是第二阶段刷的题 从路径到构造二叉树&#xff0c;合并二叉树&#xff0c;再到二叉搜索树&#xff0c;公共祖先问题 看到二叉树&#xff0c;看到递归 都会想&#…

常见的Linux基本指令

目录 什么是Linux&#xff1f; Xshell如何远程控制云服务器 Xshell远程连接云服务器 Linux基本指令 用户管理指令 pwd指令 touch指令 mkdir指令 ls指令 cd指令 rm指令 man命令 cp指令 mv指令 cat指令 head指令 ​编辑 tail指令 ​编辑echo指令 find命令 gr…

【教程】源代码加密、防泄密软件

​ 什么是代码混淆&#xff1f; 代码混淆 是一种将应用程序二进制文件转换为功能上等价&#xff0c;但人类难于阅读和理解的行为。在编译 Dart 代码时&#xff0c;混淆会隐藏函数和类的名称&#xff0c;并用其他符号替代每个符号&#xff0c;从而使攻击者难以进行逆向工程。 …

认识产品经理以及Axure简单安装与入门

目录 一.认识产品经理 1.1.项目团队 1.2.概述 1.3.认识产品经理 1.4.产品经理工作范围 1.5.产品经理工作流程 1.6.产品经理的职责 1.7.产品经理的分类 1.8.产品经理能力要求 1.9.产品工具 1.10.产品体验报告 二.Axure简介 三.应用场景 四.安装与汉化 4.1.安装 4…

认知觉醒(七)

认知觉醒(七) 第三章 元认知——人类的终极能能力 第一节 元认知&#xff1a;成长慢&#xff0c;是因为你不会“飞” 1946年10月24日&#xff0c;一群科学家为了研究太阳的紫外线&#xff0c;在美国新墨西哥州白沙导弹试验场发射了当时世界上最先进的V2液体火箭&#xff0…

mysql 数据库 关于库的基本操作

库的操作 如果想到 mysql 客户端当中数据 系统当中的命令的话&#xff0c;直接输入的话&#xff0c;会被认为是 mysql 当中的命令。 所以&#xff0c;在mysql 当中执行系统当中的命令的话&#xff0c;要在系统命令之前带上 ststem &#xff0c;表示系统命令&#xff1a; 但是…

代码随想录二刷 | 二叉树 | 110.平衡二叉树

代码随想录二刷 &#xff5c; 二叉树 &#xff5c; 110.平衡二叉树 题目描述解题思路递归迭代 代码实现递归法迭代法 题目描述 110.平衡二叉树 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉…

奥比中光 Femto Bolt相机ROS配置

作者&#xff1a; Herman Ye Auromix 测试环境&#xff1a; Ubuntu20.04/22.04 、ROS1 Noetic/ROS2 Humble、X86 PC/Jetson Orin、Kinect DK/Femto Bolt 更新日期&#xff1a; 2023/12/12 注1&#xff1a; Auromix 是一个机器人爱好者开源组织。 注2&#xff1a; 由于笔者水平有…

FL Studio水果软件最新版本号V21.0.3.3517内置中文补丁,可以切换成中文界面。

FL Studio 21.0.3.3517 Producer Edition 全称Fruity Loops Studio 21 Producer Edition &#xff0c;就是大家熟悉的水果编曲软件&#xff0c;一个全能的音乐制作软件&#xff0c;包括编曲、录音、剪辑和混音等诸多功能&#xff0c;让你的电脑编程一个全能的录音室。FL Studio…