深度学习二维码识别 计算机竞赛

文章目录

  • 0 前言
  • 2 二维码基础概念
    • 2.1 二维码介绍
    • 2.2 QRCode
    • 2.3 QRCode 特点
  • 3 机器视觉二维码识别技术
    • 3.1 二维码的识别流程
    • 3.2 二维码定位
    • 3.3 常用的扫描方法
  • 4 深度学习二维码识别
    • 4.1 部分关键代码
  • 5 测试结果
  • 6 最后

0 前言

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

🚩 python+opencv+深度学习实现二维码识别

该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!

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

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

🧿 更多资料, 项目分享:

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

2 二维码基础概念

2.1 二维码介绍

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

2.2 QRCode

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

2.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个字符的信息。

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

3.1 二维码的识别流程

在这里插入图片描述

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

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

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

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

3.2 二维码定位

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

在这里插入图片描述

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

在这里插入图片描述

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

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

在这里插入图片描述

3.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
两点为端点的线段称为扫描线段。将扫描线段保存下来。

在这里插入图片描述

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

  1. 在 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两点连一条直线。
在这里插入图片描述

(2) 在 Y 方向的扫描线段中找出最外侧的两条, 分别取中点, 记为 C、 D。 由 C、 D两点连一条直线。
在这里插入图片描述

(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;
}

5 测试结果

学长这里放到树莓派中,调用外部摄像头进行识别,可以看到,效果还是非常不错的

在这里插入图片描述

6 最后

🧿 更多资料, 项目分享:

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

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

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

相关文章

C++多线程编程(1):线程的创建方式

文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 文章目录 进行与线程C中如何实现多线程创建线程的多种方式无参函数lambda表达式常成员函数not常成员引用函数智能指针仿函数类的普通成员函数综合测试 进行与线程 多线程是指多个线程并发执行的过程。 进程与线程的关系&…

使用Qt实现多人聊天工作室

目录 1、项目背景 2、技术分析 3、架构设计 3、1 服务器架构 3.1.1 模块划分 3.1.2 模块之间的交互 3、2 客户端架构 3.2.1 模块划分 3.2.2 模块之间交互 4、实现过程 4、1 功能实现 4.1.1 用户登录注册功能​编辑 4.1.2 用户主界面功能 4、2 设计实现 4.2.1 登录…

传输层协议-TCP协议

目录 TCP协议格式理解可靠性序号与确认序号16位窗口大小六个标志位连接管理机制三次握手四次挥手 确认应答机制&#xff08;ACK&#xff09;超时空重传机制流量控制滑动窗口拥塞控制延迟应答捎带应答面向字节流粘包问题TCP异常情况TCP小结基于TCP应用层协议TCP/UDP对比用UDP实现…

程序的编译链接以及装载

目录 一、预处理 二、编译 三、汇编 四、链接 五、装载 一、预处理 读取c源程序&#xff0c;对其中的伪指令&#xff08;以#开头的指令&#xff09;和特殊符号进行处理&#xff0c; 伪指令主要包括以下五个方面&#xff1a; 宏定义指令&#xff0c;如#define Name Token…

如何定位el-tree中的树节点当父元素滚动时如何定位子元素

使用到的方法 Element 接口的 scrollIntoView() 方法会滚动元素的父容器&#xff0c;使被调用 scrollIntoView() 的元素对用户可见。 参数 alignToTop可选 一个布尔值&#xff1a; 如果为 true&#xff0c;元素的顶端将和其所在滚动区的可视区域的顶端对齐。相应的 scrollIntoV…

基于冠状病毒群体免疫算法优化概率神经网络PNN的分类预测 - 附代码

基于冠状病毒群体免疫算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于冠状病毒群体免疫算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于冠状病毒群体免疫优化的PNN网络5.测试结果6.参考文献7.Matlab代码 …

再高级的打工人也只是打工人!

再高级的打工人也只是打工人&#xff01; OpenAI CEO 奥特曼被罢免的事情人尽皆知「虽然&#xff0c;今天又复职了。。」&#xff0c;我们能从中学到什么呢&#xff1f; CEO 也能被裁&#xff0c;这应该是最近几年被裁名单里面&#xff0c;职级最高的一个人了吧。你再也不用担…

2023最新最全【Nacos】零基础安装教程

一、下载Nacos1.4.1 二、单机版本安装 2.1 将下载的nacos安装包传输到服务器2.2 解压文件2.3 进入bin目录下 单机版本启动2.4 关闭nacos2.5 访问Nacos地址 IP&#xff1a;8848/nacos 三、集群版本的安装 3.1 复制nacos安装包&#xff0c;修改为nacos8849&#xff0c;nacos88…

cesium 图片旋转

cesium 图片旋转 1、实现思路 用cesium 中 ellipse 方法来加载圆型&#xff0c;改变 material 材质 用 ImageMaterialProperty 属性来加在图片&#xff0c;实时改变rotation&#xff0c;stRotation属性来实现旋转 2、源码实现 <!DOCTYPE html> <html lang"en&…

自定义业务异常处理类加入全局处理器中

自定义业务异常处理类并将其加入全局异常处理器&#xff0c;从而避免业务层直接处理异常造成代码污染&#xff0c;达到业务清晰简洁。 描述 在进行分类模块开发时&#xff0c;删除某个分类时当分类关联了菜品和套餐时&#xff0c;是不允许删除的。我们在管理端删除的时候会提示…

lectin

PSGL-1 ; selectin O-linked glycosylation | Detailed Pedia PSGL-1 has several O-glycans to extend the ligand away from the cell surface. An sLex epitope allows interactions with the receptor for leukocyte localisation. 分类 --Recognition by Animal Lectins…

【linux网络】解读FTP文件传输服务器配置,揭秘百度云下载限速原理

目录 一、FTP文件传输协议 1.1FTP工作原理 1.2两种模式介绍 1.3FTP状态码 1.4FTP的三种用户分类 二、vsftpd软件的介绍 2.1服务端介绍 2.2不同操作系统下的客户端登录操作 三、vsftpd的常见配置 3.1修改默认的命令端口 3.2限制匿名用户登录&#xff08;系统原本是默…

实验五:Java多线程程序设计

一、线程接力 编写一个应用程序&#xff0c;除了主线程外&#xff0c;还有三个线程&#xff1a;first、second和third。first负责模拟一个红色的按钮从坐标&#xff08;10&#xff0c;60&#xff09;运动到&#xff08;100&#xff0c;60&#xff09;&#xff1b;second负责模…

安顿APP3.0全新升级,引领智能穿戴健康革新,专注预警疾病风险

随着人们生活水平的提高和工作压力的增加&#xff0c;心脑血管疾病已经成为现代社会的严重问题&#xff0c;特别是心梗、脑卒中等疾病已经开始夺去年轻人的生命。 据报道&#xff0c;近年来&#xff0c;多位年轻人因心脑血管疾病突发去世&#xff0c;如42岁的知名男演员、30岁的…

【STL】:反向迭代器

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下有关反向迭代器的模拟实现&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通…

Web之JavaScript(jQuery)笔记

Web之HTML、CSS、JavaScript 三、JavaScriptJS调试变量自定义函数数据类型及转换运算符优先级内置函数数组事件DOM(Document Object Model 文档对象模型)jQuery Web之HTML笔记 Web之CSS笔记 三、JavaScript JavaScript&#xff08;简称“JS”&#xff09;是一种轻量级的面向对…

计算机组成原理-双端口RAM和多模块存储器

文章目录 存取周期总览双端口RAM多体并行存储器低地址交叉编址有多少个存储体合适&#xff08;体号&#xff09;多模块存储器&#xff08;多体存储器&#xff09;总结实际场景 存取周期 总览 双端口RAM RAM&#xff1a;用于主存或高速缓存&#xff0c;断电数据丢失 多体并行…

AI对开发者职业的影响,保持领先的7 个行动指南

在不断发展的技术领域&#xff0c;人工智能(AI)已经成为一股变革性的力量&#xff0c;重塑了行业&#xff0c;重新定义了我们解决问题的方式。对于开发人员来说&#xff0c;学习AI的决定不仅仅是为了保持相关性&#xff0c;而是在他们的职业生涯中开启一个新的可能性维度。 1.…

HR应用在线人才测评,给企业招聘带来的好处

一、什么是人才测评&#xff1f; 人才测评是指运用一系列的科学方法&#xff0c;对人的基本素质&#xff0c;专业能力&#xff0c;心理健康&#xff0c;性格进行选拔&#xff0c;评价及发展人才的一种科学方法。近十多年&#xff0c;它被广泛运用于国有大型企业的人才招聘和人…

【力扣面试经典150题】(链表)K 个一组翻转链表

题目描述 力扣原文链接 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。 你不能只…