毕设成品 基于深度学习二维码检测识别系统

news2024/10/12 14:24:58

文章目录

  • 0 简介
  • 1 二维码基础概念
    • 1.1 二维码介绍
    • 1.2 QRCode
    • 1.3 QRCode 特点
  • 2 机器视觉二维码识别技术
    • 2.1 二维码的识别流程
    • 2.2 二维码定位
    • 2.3 常用的扫描方法
  • 4 深度学习二维码识别
    • 4.1 部分关键代码
  • 最后

0 简介

今天学长向大家分享一个毕业设计项目

**毕业设计 基于深度学习二维码检测识别系统 **

项目运行效果:

毕业设计 深度学习二维码检测识别

🧿 项目分享:见文末!

1 二维码基础概念

1.1 二维码介绍

二维条码/二维码(2-dimensional bar
code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的、黑白相间的、记录数据符号信息的图形;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化点。

1.2 QRCode

常见的二维码为QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar
Code条形码能存更多的信息,也能表示更多的数据类型。

1.3 QRCode 特点

1、符号规格从版本1(21×21模块)到版本40(177×177 模块),每提高一个版本,每边增加4个模块。

2、数据类型与容量(参照最大规格符号版本40-L级):

  • 数字数据:7,089个字符
  • 字母数据: 4,296个字符
  • 8位字节数据: 2,953个字符
  • 汉字数据:1,817个字符

3、数据表示方法:

  • 深色模块表示二进制"1",浅色模块表示二进制"0"。

4、纠错能力:

  • L级:约可纠错7%的数据码字
  • M级:约可纠错15%的数据码字
  • Q级:约可纠错25%的数据码字
  • H级:约可纠错30%的数据码字

5、结构链接(可选)

  • 可用1-16个QR Code码符号表示一组信息。每一符号表示100个字符的信息。

2 机器视觉二维码识别技术

2.1 二维码的识别流程

在这里插入图片描述

首先, 对采集的彩色图像进行灰度化, 以提高后继的运行速度。

其次, 去除噪声。 采用十字形中值滤波去除噪音对二码图像的干扰主要是盐粒噪声。

利用灰度直方图工具, 使用迭代法选取适当的阈值, 对二维码进行二值化处理,灰度化 去噪 二值化 寻找探测图形确定旋转角度 定位 旋转
获得数据使其变为白底黑色条码。

最后, 确定二维码的位置探测图形, 对条码进行定位, 旋转至水平后, 获得条码数据,
以便下一步进行解码。

2.2 二维码定位

QR 码有三个形状相同的位置探测图形, 在没有旋转的情况下, 这三个位置探测图形分别位于 QR 码符号的左上角、 右上角和左下角。
三个位置探测图形共同组成图像图形。

在这里插入图片描述

每个位置探测图形可以看作是由 3 个重叠的同心的正方形组成, 它们分别为 7 7 个深色模块、 5 5 个浅模块和 3*3 个深色模块。
位置探测图形的模块宽度比为 1: 1:3: 1: 1。

![在这里插入图片描述](https://img-
blog.csdnimg.cn/dd71567e55d24dea842dba7c6c344b2c.png?x-oss-
process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBARGFuQ2hlbmctc3R1ZGlv,size_8,color_FFFFFF,t_70,g_se,x_16)

这种 1: 1: 3: 1: 1 的宽度比例特征在图像的其他位置出现的可能性很小, 故可以将此作为位置探测图形的扫描特征。 基于此特征,
当一条直线上(称为扫描线) 被黑白相间地截为1: 1: 3:1: 1 时, 可以认为该直线穿过了位置探测图形。

另外, 该扫描特征不受图像倾斜的影响。 对比中的两个 QR 码符号可以发现, 无论 QR码符号是否倾斜, 都符合 1: 1: 3:1: 1 的扫描特征。

在这里插入图片描述

2.3 常用的扫描方法

1. 在 X 方向进行依次扫描。

(1) 固定 Y 坐标的取值, 在 X 方向上画一条水平直线(称为扫描线) 进行扫描。 当扫描线被黑白相间地截为 1: 1: 3: 1: 1 时,
可以认为该直线穿过了位置探测图形。 在实际判定时, 比例系数允许 0. 5 的误差, 即比例系数为1 的, 允许范围为 0. 5~1. 5, 比例系数为 3
的, 允许范围为 2. 5~3. 5。

(2) 当寻找到有直线穿过位置探测图形时, 记录下位置探测图形的外边缘相遇的第一点和最后一点 A 和 B。 由 A、 B
两点为端点的线段称为扫描线段。将扫描线段保存下来。

![在这里插入图片描述](https://img-
blog.csdnimg.cn/2ca811301e4b404caeae92e5a32c1bec.png?x-oss-
process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBARGFuQ2hlbmctc3R1ZGlv,size_9,color_FFFFFF,t_70,g_se,x_16)

用相同的方法, 完成图像中所有水平方向的扫描。

2. 在 Y 方向, 使用相同的方法, 进行垂直扫描, 同样保存扫描得到的扫描线段。

扫描线段分类扫描步骤获得的扫描线段是没有经过分类的, 也就是对于特定的一条扫描线段, 无法获知其具体对应于三个位置探测图形中的哪一个。 在计算位置探测图形中

距离邻域法的思想是: 给定一个距离阈值 dT, 当两条扫描线段的中点的距离小于 d T 时, 认为两条扫描线段在同一个邻域内, 将它们分为一类,
反之则归为不同的类别。

距离邻域法的具体步骤如下:
(1) 给定一个距离阈值 dT , d T要求满足以下条件: 位于同一个位置探测图形之中的任意两点之间的距离小于 dT ,
位于不同位置探测图形中的任意两点之间的距离大于 d T
(2) 新建一个类别, 将第 1 条扫描线段归入其中。
(3) 对于第 i 条扫描线段 l i (2≤i≤n), 做以下操作:

a) 求出 l i 的中点 C i 。

b) 分别计算C i与在已存在的每一个类别中的第一条扫描线段的中点的距离d,若 d<d T , 则直接将 l i 加入相应类别中。

c) 若无法找到 l i 可以加入的类别, 则新建一个类别, 将 l i 加入其中。

(4) 将所有类别按照包含扫描线段的数目进行从大到小排序, 保存前 3 个类别(即
包含扫描线段数目最多的 3 个类别), 其余的视为误判得到的扫描线段(在位置探测图形以外的位置得到的符合扫描特征的扫描线段),
直接舍去。距离邻域法结束后得到的分好 3 个类别的扫描线段就分别对应了 3 个位置探测图形。距离邻域法的关键就是距离阈值的选取。 一般对于不同大小的 QR
码图像, 要使用不同的距离阈值。

(1) 在 X 方向的扫描线段中找出最外侧的两条, 分别取中点, 记为 A、 B。 由 A、 B两点连一条直线。
![在这里插入图片描述](https://img-
blog.csdnimg.cn/d29d87f65f7548daab27b87f6b055294.png?x-oss-
process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBARGFuQ2hlbmctc3R1ZGlv,size_7,color_FFFFFF,t_70,g_se,x_16)

(2) 在 Y 方向的扫描线段中找出最外侧的两条, 分别取中点, 记为 C、 D。 由 C、 D两点连一条直线。
![在这里插入图片描述](https://img-
blog.csdnimg.cn/8ecb2bc8a4604940a1e3e02147baed59.png?x-oss-
process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBARGFuQ2hlbmctc3R1ZGlv,size_8,color_FFFFFF,t_70,g_se,x_16)

(3) 计算直线 AB 与直线 CD 的交点 O, 即为位置探测图形中心点。

在这里插入图片描述

将 QR 码符号的左上、 右上位置探测图形的中心分别记为 A、 B。 连接 A、 B。 直线 AB 与水平线的夹角α 即为 QR 码符号的旋转角度。

在这里插入图片描述
对于该旋转角度α , 求出其正弦值 sinα 与余弦值 cosα 即可。 具体计算公式如下:
在这里插入图片描述

在这里插入图片描述

位置探测图形边长的计算是基于无旋转图像的, 在无旋转图像中, 水平扫描线段的长度即为位置探测图形的边长。

水平扫描线段 AB 的长度即为位置探测图形的边长 X。

在这里插入图片描述

对于经过旋转的 QR 码图像, 先通过插值算法生成旋正的 QR 码图像, 然后按照如上所述的方法进行位置探测图形边长的计算

4 深度学习二维码识别

基于 CNN 的二维码检测,网络结构如下

在这里插入图片描述

4.1 部分关键代码

篇幅有限,学长在这只给出部分关键代码

首先,定义一个 AlgoQrCode.h

#pragma once
#include 
#include 
using namespace cv;
using namespace std;

class AlgoQRCode
{
private:
	Ptr<wechat_qrcode::WeChatQRCode> detector;

public:
	bool initModel(string modelPath);

	string detectQRCode(string strPath);

	bool compression(string inputFileName, string outputFileName, int quality);

	void release();
};

该头文件定义了一些方法,包含了加载模型、识别二维码、释放资源等方法,以及一个 detector 对象用于识别二维码。

然后编写对应的源文件 AlgoQrCode.cpp

bool AlgoQRCode::initModel(string modelPath) {
	string detect_prototxt = modelPath + "detect.prototxt";
	string detect_caffe_model = modelPath + "detect.caffemodel";
	string sr_prototxt = modelPath + "sr.prototxt";
	string sr_caffe_model = modelPath + "sr.caffemodel";
	try
	{
		detector = makePtr<wechat_qrcode::WeChatQRCode>(detect_prototxt, detect_caffe_model, sr_prototxt, sr_caffe_model);
	}
	catch (const std::exception& e)
	{
		cout << e.what() << endl;
		return false;
	}

	return true;
}

string AlgoQRCode::detectQRCode(string strPath)
{
	if (detector == NULL) {
		return "-1";
	}

	vector<Mat> vPoints;
	vector<cv::String> vStrDecoded;
	Mat imgInput = imread(strPath, IMREAD_GRAYSCALE);
//	vStrDecoded = detector->detectAndDecode(imgInput, vPoints);
        ....
}

bool AlgoQRCode::compression(string inputFileName, string outputFileName, int quality) {
	Mat srcImage = imread(inputFileName);

	if (srcImage.data != NULL)
	{
		vector<int>compression_params;
		compression_params.push_back(IMWRITE_JPEG_QUALITY);
		compression_params.push_back(quality);     //图像压缩参数,该参数取值范围为0-100,数值越高,图像质量越高

		bool bRet = imwrite(outputFileName, srcImage, compression_params);

		return bRet;
	}

	return false;
}

void AlgoQRCode::release() {
	detector = NULL;
}

在这里插入图片描述

最后

项目运行效果:

毕业设计 深度学习二维码检测识别

🧿 项目分享:见文末!

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

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

相关文章

【最新华为OD机试E卷-支持在线评测】第K个排列(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

【MySQL 保姆级教学】在Linux(CentoS 7)中安装MySQL(1)

目录 1. 卸载linux&#xff08;Centos7&#xff09; 中不要的环境2. 获取MySQL官方yum源2.1 获取yum源前先查看自己 linux&#xff08;Centos&#xff09;的版本2.2 获取官方yum源 3. 安装xftp和连接4. 开放连接端口5. 上传文件到Centos76. 安装MySQL6.1 顺利安装6.2 查询是否安…

Terminus ssh key 登陆

生成key 一、添加 KEY 配置 电脑: Terminus > Preferences&#xff0c;或 ⌘,。选择左侧 Keychain 标签。 手机: Terminus > Keychain 电脑: 点击右侧上方的 NEW KEY 按钮, 手机: 点加号 电脑: 在最右侧弹出的页面中填写 Label 和 Private key&#xff0c;Private ke…

电脑怎么录屏?探索屏幕捕捉的奥秘,新手也能成为录屏高手!

在数字时代&#xff0c;无论是制作教学视频、分享游戏精彩瞬间还是展示软件操作流程&#xff0c;屏幕录制都成了一项必不可少的技能。然而&#xff0c;对于许多初次接触录屏的新手来说&#xff0c;如何开始这一过程似乎充满了挑战。本文将为你揭开录屏的神秘面纱&#xff0c;带…

golang-基础知识(流程控制)

1 条件判断if和switch 所有的编程语言都有这个if&#xff0c;表示如果满足条件就做某事&#xff0c;不满足就做另一件事&#xff0c;go中的if判断和其它语言的区别主要有以下两点 1. go里面if条件判断不需要括号 2. go的条件判断语句中允许声明一个变量&#xff0c;这个变量…

MySQL8.0环境部署+Navicat17激活教程

安装MySQL 下载MySQL MySQL官网下载当前最新版本&#xff0c;当前是8.0.39。 选择No thanks, just start my download等待下载即可。 安装MySQL 下载完成后&#xff0c;双击安装进入安装引导页面。选择Custom自定义安装。 选择MySQL Server 8.0.39 - X64安装。 点击Execute执…

基于BeautyEye开发Java程序用户界面

文章目录 I idea引入jar包添加本地jar包maven方式引入本地包方式1:将第三方JAR包安装到本地仓库maven方式引入本地包方式2:引用本地路径将本地jar包打进war包Maven内置变量说明II BeautyEye Swing外观实现方案案例III 知识扩展Swing常用的顶级容器BeautyEye SwingI idea引入j…

在python中如何判断回文串(二)?

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

一次性解决vue3引入@jiaminghi/data-view需要手动修改node_modules下文件

修改文件1&#xff1a;node_modules\jiaminghi\data-view\lib\components\decoration6\src\main.vue 修改文件2&#xff1a; node_modules\jiaminghi\data-view\lib\components\decoration3\src\main.vue 修改前&#xff1a; 修改后&#xff1a; 通过打补丁的方式对引用库进行…

SpringBoot购物推荐网站:从零到一的构建过程

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…

如何使用ipopt进行非线性约束求目标函数最小值(NLP非线性规划)内点法(Interior point method)

非线性规划,一般用matlab调用cplex和gurobi了,但这两个一般用于线性规划和二次规划 线性规划LP,二次规划(quadratic programming),如果要求更一般的非线性规划IPOT是个很好的选择,求解器很多,根据情况自己选择 非线性 具体的,这篇文章介绍的很清楚了https://blog.csd…

Javascript笔试题目(一)

1.JS查找文章中出现频率最高的单词? 要在JavaScript中查找文章中出现频率最高的单词&#xff0c;你可以按照以下步骤进行操作&#xff1a; 将文章转换为小写&#xff1a;这可以确保单词的比较是大小写不敏感的。移除标点符号&#xff1a;标点符号会干扰单词的计数。将文章拆…

SpringBoot环境下的电商推荐网站开发全攻略

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…

题目:1297. 子串的最大出现次数

> Problem: 1297. 子串的最大出现次数 题目&#xff1a;1297. 子串的最大出现次数 题目描述 给定一个字符串 s&#xff0c;要求找到满足以下条件的任意子串的出现次数&#xff0c;并返回该子串的最大出现次数&#xff1a; 子串中不同字母的数目必须小于等于 maxLetters。…

使用3080ti配置安装blip2

使用3080ti运行blip2的案例 本机环境&#xff08;大家主要看GPU&#xff0c;ubuntu版本和cuda版本即可&#xff09;&#xff1a;安装流程我最后安装的所有包的信息&#xff08;python 3.9 &#xff09;以供参考&#xff08;environment.yml&#xff09;&#xff1a; 本机环境&a…

Git:LF will be replaced by CRLF、pytest PermissionError以及Git应用中的一些问题解决及一些使用技巧

一、Git:LF will be replaced by CRLF和pytest: --cov NTERNALERROR PermissionError 1. git warning: LF will be replaced by CRLF in ***file 偶然git add在进行代码提交的时候碰到警告warning: LF will be replaced by CRLF in ***file&#xff0c;原因是编辑的代码内容中…

java抽象类和接口-cnblog

java抽象类和接口 1 抽象类 在解决实际问题时,一般将父类作为抽象类&#xff0c;子类继承父类&#xff0c;并且实例化对象 在一个类中&#xff0c;只要有有一个方法是抽象的&#xff0c;类就是抽象的 抽象类被继承后需要实现所有的抽象方法&#xff0c;抽象类的关键词是abst…

entity,pojo,vo,dto 详解

在Java项目中&#xff0c;包名通常用于组织代码&#xff0c;使其更加清晰和易于维护。entity、pojo、vo和dto是常见的包名&#xff0c;它们各自有不同的含义和用途。下面将详细解释这些包名的含义&#xff0c;并提供一个示例&#xff0c;帮助你更好地理解它们在项目中的应用。 …

第二届 龙信杯 电子数据取证竞赛部分Writeup

大佬文章&#xff1a; 龙信杯复现&#xff08;23、24&#xff09; | BthclsBlog 手机部分 资料&#xff1a;2024年第二届龙信杯 WP_2024龙信杯wp-CSDN博客 1.分析手机检材&#xff0c;请问此手机共通过adb连接过几个设备&#xff1f;[标准格式&#xff1a;3] 2 /data/a…

基于Java SpringBoot和Vue校园新闻论坛管理系统设计

摘要 本系统采用Java Spring Boot作为后端框架&#xff0c;前端使用Vue.js构建用户界面&#xff0c;旨在为校园新闻论坛提供一个高效、易用且功能全面的管理平台。通过整合SpringBoot的快速开发优势与Vue的响应式设计&#xff0c;实现了一个包含用户注册登录、新闻发布审核、评…