竞赛 基于机器视觉的二维码识别检测 - opencv 二维码 识别检测 机器视觉

文章目录

  • 0 简介
  • 1 二维码检测
  • 2 算法实现流程
  • 3 特征提取
  • 4 特征分类
  • 5 后处理
  • 6 代码实现
  • 5 最后

0 简介

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

基于机器学习的二维码识别检测 - opencv 二维码 识别检测 机器视觉

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

🧿 更多资料, 项目分享:

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

1 二维码检测

物体检测就是对数字图像中一类特定的物体的位置进行自动检测。基本的检测框架有两种:

一种是以滑动窗口为单位对图像进行扫描,对扫描所得的每个子图像提取特征,并用学习到的分类器来分类该特征并且判断该子图像是否为所检测的特定物体。对象检测的一个问题是,对象在图片中的位置和尺度是未知的。算法被要求能够检测各种不同位置、不同大小的对象,这样的特性被称为位置无关性和尺度无关性。为了达到这样的特性,常见的方法是使用多尺度框架,即:通过缩放原始图像,产生一组大小不同的图像序列,然后在序列的每幅图像中都使用固定尺寸
W×H
的滑动窗口,检测算法将判断每次滑动窗口所截取的图像子窗口是否存在目标对象。滑动窗口解决了位置无关性;而图像序列中存在至少一幅图像,其包含的目标对象的尺度符合滑动窗口的尺度,这样一个图像金字塔序列解决了尺度无关性。

另一种则是在整幅图像上首先提取兴趣点,然后仅对提取出来的兴趣点分类。

因此学长把物体检测方法分为基于滑动窗口的物体检测和基于兴趣点的物体检测两类。

无论是哪种做法,整个过程都可以分为特征提取和特征分类这两个主要阶段。也就是说,物体检测的主要问题是使用什么样的特征和使用什么样的分类器。

物体检测的难点在于如何用有限的训练集来学习到鲁棒的、可以适用到各种情况下的分类器。这里所说的各种情况包括有:图像中物体的大小不同;光照条件的差异所引起的图像明暗的不同;物体在图像中可能存在的旋转和透视情况;同类物体间自身存在的差异。

这里学长以定位二维码 / 条形码为例,简述基于机器学习实现物体检测的大致算法流程。

2 算法实现流程

算法流程图如下图所示:

在这里插入图片描述

我们先把输入图像分成 25×25
的图像子块。把图像子块作为特征提取和特征分类这两个模块的基本处理对象,即对图像子块进行纹理特征提取,特征分类时判定当前处理的图像子块是否属于二维条形码的一部分

在这里插入图片描述

在特征提取模块中,我们使用纹理特征提取算法从原始输入图像中提取出多分辨率直方

在特征分类时,我们希望保留所有属于二维条形码的图像子块,同时去除所有属于背景的图像子块。在该模块中,我们使用了自适应 Spatialboost 算法。

下图为经过这步处理后的理想输出结果,图中被标记的小方块表示他们属于二维条形码的一部分。

在这里插入图片描述

3 特征提取

图像的纹理特征可以描述物体特有的属性,用以区别其他物体。纹理特征总体可分为空域和频域两大类。在本文算法中,我们采用的纹理特征均属于空域的纹理特征,也是局部特征,它们分别是多分辨率直方图特征、局部二值模式特征和边缘方向直方图特征。

多分辨率直方图特征具备旋转无关的特点。这种纹理特征保留了灰度直方图特征计算简单和保存方便的特点。同时它又可以描述纹理的局部信息,弥补了传统的灰度直方图特征的缺点。

局部二值模式特征是一种计算复杂度较低的局部特征,它具有明暗无关和旋转无关的特点。
边缘方向直方图特征与全局的光照变化是无关的,它可以提取出二维条形码纹理的几何特点。

4 特征分类

学长开发的算法所使用的分类器为自适应 Spatialboost 算法,这是对 Spatialboost
算法的一个改进。使用这个分类器是由二维条形码的特点以及我们算法框架的特点所决定的。由于我们把原始输入图像分为若干大小固定的图像子块,属于二维条形码的图像子块在空间上有很强的关联性,或者说这些属于二维条形码的图像子块都是紧密相邻的。同时由于图像子块的尺寸不大,它所包含的信息量相对较少,有的时候就很难把属于二维条形码的图像子块和属于背景的图像子块区分开(它们在特征空间上可能重叠)。如果我们可以利用子块在空间上的联系,把空间信息加入到分类器中,将有利于提高分类器的准确率。

适应 Spatialboost
算法可以同时利用纹理特征以及子块在空间上的联系,在训练过程中,将纹理特征和空间信息自适应的结合起来训练分类器。这样,当前处理的子块的分类结果不仅依赖于它自己的纹理特征,还和它周围子块的分类结果密切相关。当属于背景的图像子块的纹理特征很接近于属于二维条形码的图像子块时,我们还是可以依靠和它相邻的背景子块来对它做出正确的分类。

5 后处理

经过特征提取和特征分类两个模块后,我们得到了对图像子块的分类结果,但最后我们期望得到的是对二维条形码的包围盒。在我们的设置下,自适应Spatialboost
分类器对背景子块的分类相当严格,此时对属于二维条形码的图像子块会有部分漏检发生,

在这里插入图片描述

因此在后处理模块中,我们先使用一种自适应聚类算法,对分类后的结果进一步改进,来精确的覆盖整个二维条形码。特征分类后定位到的子块的大小为
25×25,我们把这些子块再划分为 10×10 的小方块。接着以得到的 10×10 的子块为种子,用子块灰度值的方差为衡量标准往外聚类,聚类时的阈值设定为:

在这里插入图片描述

其中 M 是聚类开始时作为种子的子块的个数,k 为调整系数,在本文算法中 k设置为 0.5,Var 和 Mean
分别表示子块灰度值的均值和方差。由公式(3-1)可知,每幅图像的聚类阈值是自适应的计算得来的。聚类开始时首先从种子子块出发,计算它们周围的子块的灰度值方差,如果大于聚类阈值就把它标识为属于二维条形码,重复这个过程直到周围再没有子块符合聚类条件。图
3-5
是聚类算法的部分结果,第一行的图像是特征分类后的结果,准确的定位到了一部分二维条形码,但是没有完全的覆盖整个二维条形码,不利于我们输出最后的定位包围盒。第二行为聚类后的结果,可以看到小块几乎完全覆盖了整个二维条形码,此时再把这些小块合并为一个平行四边形就很方便了。

在这里插入图片描述

聚类后定位出来的小块基本上覆盖了整个二维条形码,最后我们只需要把定位出的小包围盒合并为大包围盒,并输出最后的定位结果。整个后处理流程见图

在这里插入图片描述

6 代码实现

这里演示条形码的检测效果:
在这里插入图片描述

关键部分代码实现:


# import the necessary packages
import numpy as np
import argparse
import cv2

# construct the argument parse and parse the arguments
# ap = argparse.ArgumentParser()
# ap.add_argument("-i", "--image", required = True, help = "path to the image file")
# args = vars(ap.parse_args())# load the image and convert it to grayscale
image = cv2.imread('./images/2.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# compute the Scharr gradient magnitude representation of the images
# in both the x and y direction
gradX = cv2.Sobel(gray, ddepth = cv2.CV_32F, dx = 1, dy = 0, ksize = -1)
gradY = cv2.Sobel(gray, ddepth = cv2.CV_32F, dx = 0, dy = 1, ksize = -1)# subtract the y-gradient from the x-gradient
gradient = cv2.subtract(gradX, gradY)
gradient = cv2.convertScaleAbs(gradient)# blur and threshold the image
blurred = cv2.blur(gradient, (9, 9))
(_, thresh) = cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY)# construct a closing kernel and apply it to the thresholded image
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)# perform a series of erosions and dilations
closed = cv2.erode(closed, None, iterations = 4)
closed = cv2.dilate(closed, None, iterations = 4)# find the contours in the thresholded image, then sort the contours
# by their area, keeping only the largest one
(cnts, _) = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
c = sorted(cnts, key = cv2.contourArea, reverse = True)[0]# compute the rotated bounding box of the largest contour
rect = cv2.minAreaRect(c)
box = np.int0(cv2.boxPoints(rect))

5 最后

🧿 更多资料, 项目分享:

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

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

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

相关文章

网络层 --- IP协议

目录 1. 前置性认识 2. IP协议 3. IP协议头格式 3.1. 4位版本 3.2. 4位首部长度 3.3. 8位服务类型 3.4. 16位总长度 3.5. 8位生存时间 TTL 3.6. 8位协议 3.7. 16位首部检验和 3.8. 32位源IP和32位目的IP 4. 分片问题 4.1. 为什么要分片 4.2. 分片是什么 4.2.1. …

HTTP/1.1,HTTP/2.0和HTTP/3.0 各版本协议的详解(2024-04-24)

1、HTTP介绍 HTTP 协议有多个版本,目前广泛使用的是 HTTP/1.1 和 HTTP/2,以及正在逐步推广的 HTTP/3。 HTTP/1.1:支持持久连接,允许多个请求/响应通过同一个 TCP 连接传输,减少了建立和关闭连接的消耗。 HTTP/2&#…

win10 配置OpenCV LNK2019 无法解析的外部符号 “void __cdecl cv::imshow

1 遇到问题 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误 LNK2019 无法解析的外部符号 “void __cdecl cv::imshow(class std::basic_string<char,struct std::char_traits,class std::allocator > const &,class cv::debug_build_guard::_InputArray…

MS17-010---利用“永恒之蓝”漏洞攻击 win7主机

免责声明:本文仅做技术交流与学习.... 目录 一.前置知识 1.何为永恒之蓝&#xff1f; 2.什么是SMB协议&#xff1f; 3.SMB工作原理是什么&#xff1f; 二、实验环境 三、实验步骤 nmap扫描 msf一把梭哈 shell执行命令 远程连接 一&#xff0e; 二&#xff0e; 一.前…

面向对象编程三大特征:封装、继承、多态

封装、继承、多态 1. 封装 1.1 介绍 封装(encapsulation)就是把抽象出的数据 [属性] 和对数据的操作 [方法] 封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作 [方法] ,才能对数据进行操作。 1.2 封装的理解和好处 1) 隐藏实现细节:方法(连接数据库)<…

用OpenCV先去除边框线,以提升OCR准确率

在OpenCV的魔力下&#xff0c;我们如魔法师般巧妙地抹去表格的边框线&#xff0c;让文字如诗如画地跃然纸上。 首先&#xff0c;我们挥动魔杖&#xff0c;将五彩斑斓的图像转化为单一的灰度世界&#xff0c;如同将一幅绚丽的油画化为水墨画&#xff0c;通过cv2.cvtColor()函数的…

通过AI助手实现一个nas定时任务更新阿里云域名解析

一.通过AI助手实现一个ip-domain.py的脚本 起一个Python脚本&#xff0c;ip-domain.py&#xff1b;注意已安装Python3.的运行环境&#xff1b;将下面阿里云相关配置添加&#xff0c;注意这里引用了两个包&#xff0c;requests和alibabacloud_alidns20150109&#xff1b;执行前…

如何利用有限的数据发表更多的SCI论文?——利用ArcGIS探究环境和生态因子对水体、土壤和大气污染物的影响

原文链接&#xff1a;如何利用有限的数据发表更多的SCI论文&#xff1f;——利用ArcGIS探究环境和生态因子对水体、土壤和大气污染物的影响https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247602528&idx6&snc89e862270fe54239aa4f796af07fb71&chksmfa82…

数据可视化在不同行业中有哪些应用?

数据可视化即通过图表的形式将数据的内在信息有逻辑性地呈现给用户&#xff0c;使用户更容易发现数据中蕴藏的规律&#xff0c;找出问题&#xff0c;进而做出决策&#xff1b;另一方面&#xff0c;数据可视化项目也是一张重要的名片&#xff0c;是企业数字化建设效果的呈现。本…

Spring基于AspectJ实现验签切点

文章目录 引言I AspectJ 依赖II 验签切点2.1 匹配方法执行的连接点2.2 设置带有CustomAnnotation注解的方法为切点III 案例:验签2.1 用法2.2 定义注解2.3 定义切面和切点引言 需求:验签 实现:基于AspectJ实现验签切点 I AspectJ 依赖 AspectJ 是一个基于 Java 语言的 AOP …

《HelloGitHub》第 97 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 Python、…

分布式存储 Ceph 的演进经验

从 2004 年到今天&#xff0c;Ceph 的存储后端一直都在演变&#xff0c;从最开始基于 B 树的 EBOFS 演变到今天的 BlueStore&#xff0c;存储后端已经变得非常成熟&#xff0c;新的存储系统不仅能够提供良好的性能&#xff0c;还有着优异的兼容性。我们在这篇文章中将要简单介绍…

服务器数据恢复—Storwize V3700存储数据恢复案例

服务器存储数据恢复环境&#xff1a; 某品牌Storwize V3700存储&#xff0c;10块硬盘组建了2组Mdisk加入到一个存储池中&#xff0c;一共创建了1个通用卷来存放数据&#xff0c;主要数据为oracle数据库。 服务器存储故障&#xff1a; 其中一组Mdisk中两块磁盘出现故障离线&…

使用selenium时出现element click intercepted报错的解决办法

win10&#xff0c;python3.8.10。 selenium版本如下&#xff08;用pip38 show selenium查看&#xff09;&#xff1a; 在定位中&#xff0c;定位了一个按钮&#xff08;特点&#xff1a;button下还有span然后才是文本&#xff09;&#xff0c;代码如下&#xff1a; from sele…

枚举(enum)/共用体(union)/结构体(struct)---详解

前言 C语言包含内置类型和自定义类型。 其实C语言中有内置类型&#xff0c;包含&#xff1a;char,short,int,long,long long,float,double,long double ,这些是C语言本身支持的现成的类型。 但仅仅只有内置类型是远远不够的&#xff0c;在描述一个复杂对象是无法使用内置类型来…

Linux工具篇 之 vim概念 操作 及基础指令讲解

学校不大 创造神话 讲桌两旁 陨落的王 临时抱佛脚 佛踹我一脚 书山有路勤为径 游戏玩的很起劲 想要计算机学的好&#xff0c;我的博客列表是个宝 –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀–❀–❀–❀…

前端学习笔记3

列表、表格与表单​ 列表就是信息资源的一种展示形式。它可以使信息结构化和条理化,并以列表的样式显示出来,以便浏览者能更快捷地获得相应的信息。 3.0 代码访问地址 https://gitee.com/qiangge95243611/java118/tree/master/web/day03 3.1 列表 ​ 列表大致可以分为3类…

怎么给字符串字段加索引?

怎么给字符串字段加索引&#xff1f; 现在&#xff0c;几乎所有的系统都支持邮箱登录&#xff0c;如何在邮箱这样的字段上建立合理的索引&#xff0c;是我们今天要讨论的问题。 假设&#xff0c;你现在维护一个支持邮箱登录的系统&#xff0c;用户表是这么定义的&#xff1a; …

如何实现直播声卡反向给手机充电功能呢?

在数字化时代的浪潮中&#xff0c;声卡作为多媒体系统的核心组件&#xff0c;扮演着声波与数字信号相互转换的关键角色。它不仅能够将来自各类音源的原始声音信号转换为数字信号&#xff0c;进而输出到各类声响设备&#xff0c;更能够通过音乐设备数字接口(MIDI)发出合成乐器的…

STM32点灯大师(点了一颗LED灯,轮询法)

配置操作&#xff1a; 一、使用CubeMX配置到大致的操作 1.1 选择芯片 1.2 选择引脚&#xff08;根据电路图&#xff09; 1.3 配置gpio口 1.4 配置系统 1.5文件项目操作 最后就是点击 二、点击CubeMX生成的代码&#xff0c;并且修改代码 2.1 看看效果 2.2 写代码