竞赛保研 python+opencv+深度学习实现二维码识别

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.mzph.cn/news/231136.shtml

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

相关文章

JWT令牌的作用和生成

JWT令牌&#xff08;JSON Web Token&#xff09;是一种用于身份验证和授权的安全令牌。它由三部分组成&#xff1a;头部、载荷和签名。 JWT令牌的作用如下&#xff1a; 身份验证&#xff1a;JWT令牌可以验证用户身份。当用户登录后&#xff0c;服务器会生成一个JWT令牌并返回…

hping3

Hping3 Hping3的介绍&#xff1a; 是一款网络的测试工具&#xff0c;一般用于网络安全员用来进行防火墙的测试等抗压测试。 Hping3的帮助面板: -h –help显示帮助 -v –version显示版本信息 -c –count 限制发包数 -i –interval nterval 指定发包间隔为多少毫秒&#…

一封来自北京软协的感谢信

日前&#xff0c;北京软件和信息服务业协会&#xff08;以下简称北软协&#xff09;向酷雷曼&#xff08;北京同创蓝天云科技有限公司&#xff09;发来感谢信&#xff0c;以表彰和感谢同创蓝天对北软协及行业的全方位支持和卓越贡献。 作为北软协理事会会员单位&#xff0c;酷雷…

js 高阶(含vue.js)

1、主动触发函数 this.$options.watch.watchOrdersFormPrice.apply(this);//主动触发watchOrdersFormPrice watch:{watchOrdersFormPrice: function(){if( !this.ordersForm.alone_sold_price && this.ordersForm.ginfo.goods_id ){var price_info this.ordersForm.…

汽车销售技巧培训应该学习哪些内容

汽车销售技巧培训应该学习哪些内容 随着汽车市场的竞争日益激烈&#xff0c;汽车销售技巧培训对于提高销售人员的销售能力和服务水平至关重要。本文将介绍汽车销售技巧培训应该学习哪些内容&#xff0c;并结合案例进行分析。 一、产品知识 作为销售人员&#xff0c;了解所销售…

Java 图片文件上传下载处理

Java 图片文件上传下载处理 下载 做这玩意给我恶心坏了 下载 直接访问上传的路径就可以下载图片了。但是我们往往会包一层接口&#xff0c;以流的方式读取 url 的内容然后返回给前端&#xff0c;这么做的优点是&#xff1a; 内网域名转外网域名&#xff0c;做业务校验并且让用…

后端相关随机题目记录(1)

目录 后端相关随机题目记录&#xff08;1&#xff09; 后端相关随机题目记录&#xff08;1&#xff09;Bean的类型以及作用域Bean的生命周期Mysql的底层数据结构RedisHttp和Https区别AOP在项目的应用 自定义注解&#xff1f;请求在spring中的一个流程Nacos与zk的区别SpringMV…

Unity中URP下的菲涅尔效果实现(个性化修改)

文章目录 前言一、我们修正一下上篇文章中&#xff0c;可能遗留的Bug1、N向量 变为 单位向量2、使颜色范围在合理区间 二、实现菲涅尔效果强弱可自定义调节三、修改菲涅尔效果颜色1、在属性面板定义颜色属性2、在常量缓冲区申明该参数3、在片元着色器中&#xff0c;用颜色和菲涅…

Python---进程

1. 进程的介绍 在Python程序中&#xff0c;想要实现多任务可以使用进程来完成&#xff0c;进程是实现多任务的一种方式。 2. 进程的概念 一个正在运行的程序或者软件就是一个进程&#xff0c;它是操作系统进行资源分配的基本单位&#xff0c;也就是说每启动一个进程&#xf…

QT for Android安卓编译环境搭建+首次编译3个大坑

1、安装 编译环境能否搭建成功&#xff0c;主要是看各个依赖软件的版本是否匹配。依赖的软件有3个&#xff1a;JDK、安卓SDK、安卓NDK。 我的qt版本是5.14.1&#xff0c;我亲测以下版本可以成功让编译安卓&#xff1a; QT5.14 JDK1.8.0 安卓SDK26.1 安卓NDK20.1 在QT-&g…

LeetCode 142. 环形链表 II

给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整…

【网络安全】-Linux操作系统—操作系统发展历史与Linux

文章目录 操作系统发展历史初期的操作系统分时操作系统个人计算机操作系统 Linux的诞生UNIX与GNU项目Linux内核的创建 Linux的特点开放源代码多样性社区支持 Linux的应用服务器和超级计算机嵌入式系统桌面系统 总结 操作系统发展历史 操作系统&#xff08;Operating System&am…

Linux之FTP 服务器

一、FTP服务器匿名账户服务器配置 1、测试是否已安装vsftp服务器&#xff1a; 2、启动vsftp服务器&#xff1a; 3、修改vsftp主配置文件&#xff0c;允许匿名登录 4、重新启动vsftpd服务,禁用防火墙 5、打开FTP服务的数据文件存放目录/var/ftp&#xff0c;复制若干文件到该目…

Java小案例-RocketMQ的11种消息类型,你知道几种?(死信消息)

前言 在RocketMQ中&#xff0c;死信消息&#xff08;Dead-Letter Message&#xff09;是指那些在正常情况下无法被消费者消费的消息。这些消息会被存储在死信队列&#xff08;Dead-Letter Queue&#xff0c;简称DLQ&#xff09;中。 死信消息的特性包括&#xff1a; 不会再被…

DC-4靶场

目录 nmap进行主机发现 尝试反弹shell&#xff1a; 进入交互式shell&#xff1a; Hydra爆破jim用户密码&#xff1a; ssh登录charles &#xff1a; 提权&#xff08;三种方法&#xff09;&#xff1a; exim4提权…

智能优化算法应用:基于社会群体算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于社会群体算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于社会群体算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.社会群体算法4.实验参数设定5.算法结果6.…

PIC单片机项目(4)——基于PIC16F877A的温度光照检测装置

1.功能设计 基于PIC16F877A单片机&#xff0c;使用DS18B20进行温度测量&#xff0c;使用光敏电阻进行光照测量&#xff0c;将测量值实时显示在LCD1602屏幕上&#xff0c;同时可以设定光照阈值和温度阈值。当温度大于阈值&#xff0c;则蜂鸣器报警&#xff0c;当光照小于阈值&am…

【源码解析】Semaphore角度聊聊AQS

案例 Semaphore&#xff0c;俗称信号量&#xff0c;它是操作系统中PV操作的原语在java的实现&#xff0c;它也是基于 AbstractQueuedSynchronizer实现的 private static ExecutorService threadPool Executors.newFixedThreadPool(4);private static Semaphore semaphore ne…

设计模式——结构型

1.装饰器模式 要素&#xff1a;装饰器&#xff0c;装饰对象 为待装饰对象中某一结构特征添加内容&#xff0c;而不是新建一个特征 /*** 装饰对象*/ public interface Shape {public void draw(); } /*** 具体装饰对象*/ public class Circle implements Shape{private String…

计算机组成原理——校验码

计算机组成原理学习笔记——校验码-CSDN博客 校验码——海明码及码距&#xff0c;码距_海明码的码距是多少-CSDN博客 1 下列关于码距与检错与纠错能力的描述中正确的是 &#xff08;ABC&#xff09; &#xff08;多选&#xff09; A. 码距为1的编码不具备任何检错能力 B. 码…