当前位置: 首页 > news >正文

OpenCV项目实战——数字识别代码及食用指南


源代码

https://gitee.com/zirui-shu/programs

进入网站下载IDidentify文件夹。

项目前瞻

本项目综合使用了python语言OpenCV框架的各个处理手段,以达到从图片银行卡中识别出卡号的目的,结果图如下:

以及输出台输出的卡号:

而在文章之后的部分,我会详细的介绍项目整个实现的流程方法,以及适用于其他情况时的代码改进建议,但不会讲解使用函数的原理,若有兴趣请自行查阅资料。

项目流程

1.数字模板的处理

进行数字识别肯定需要0~9的数字模板。在此文件中,我已经将所有模板一一保存至文件夹中,若是将此代码应用于其他识别功能,可以自行从样例图片中提取

在拿到了数字模板之后,再对模板依次进行如下操作:

1.灰度处理

将读取的模板灰度处理,降低复杂度

2.二值化

突出数字的特征,去掉多余背景的影响。

3.寻找轮廓

找到模板图片的数字,提取它们的特征并存储起来。

2.待识别图像的处理

对于读取的待识别图像,依次进行如下处理。

1.灰度化

同上文,降低复杂度

2.高斯模糊

减少图片中噪声数据的影响

3.礼帽操作

突出明亮的区域,便于卡号提取。

4.Sobel算子梯度计算

划分出边缘,便于卡号提取。

5.闭操作

连接数字相邻的区域,便于后续划分出卡号的区域。

6.寻找轮廓

找到卡号所对应的号码块,并分成一个个数字便于模板匹配。

7.模板匹配

将对应的数字找出来并存储,输出最终卡号。

代码改进

接下来,我会详细讲解在数字识别中可能出现的各个问题及可能的解决方案,便于提升项目的鲁棒性。

1.图片的选取

对于模板图片而言,最好选择正立且正好包含模板数字的图片,便于后续的特征提取及模板匹配工作;同理,待识别图片也是如此,并且最好统一大小、视角,这样才能提高准确率。如我所写的同意大小标准:

# 把图片调成长1300,宽1000image = cv2.resize(image, (1300, 1000))

2.模板轮廓并不对应

按照常理而言,我们希望的是每个模板都提取到一个轮廓,并且这个轮廓就是模板数字的轮廓。但是有些时候,模板图片的背景会影响轮廓的识别,这些噪声数据识别出来的模板会覆盖digits数组中原本需要的模板轮廓。那么,就如我在代码中所写的:

            # 过滤小面积和大面积轮廓area = cv2.contourArea(cnt)if not (100 < area):continue# 过滤异常长宽比(x, y, w, h) = cv2.boundingRect(cnt)aspect_ratio = w / float(h)if not (0.5 < aspect_ratio < 0.8):continue

对于所寻找到的轮廓图片,进行一个筛选,调整areaaspect_ratio的阈值,可以很好的帮助我们得到想要的模板轮廓。当然,对于不同的图片,需要不同的阈值,需根据实际情况调整。

3.卷积核尺寸选择

我在代码中定义了三个这样的变量:

rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25, 25))
tempKernal = cv2.getStructuringElement(cv2.MORPH_RECT, (14, 14))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (17, 17))

分别对应了三个操作的卷积核矩阵参数。对于rectKernal,这个礼帽操作的参数而言,尺寸越大那么进行操作位置位置就会更受周围因素影响,这个几乎不用改。对于tempKernalsqKernal,是闭操作的参数,先来看看操作后的图片:

其中画上红圈的就是我们要找的卡号的位置,也是我们需要注意的区域。首先观察相邻数字是否连接,即红圈部分是否连成一块了,若是没有就需要加大参数尺寸;再看数字块之间是否连接,及相邻红圈是否连接,若是连接则需减小尺寸。若是调整之后还是无法做到上图的样子,或许可以调整图片来源。

4.数字检测时混进其他板块

就如上一幅图所展示的,除了数字块还有其他的轮廓会被检测出来。这个时候就需要做一个筛选,如我所写的:

# 遍历轮廓for (i, c) in enumerate(cnts):(x, y, w, h) = cv2.boundingRect(c)ar = w / float(h)if 1.6 < ar < 3.0:if (100 < w < 200) and (50 < h < 100):locs.append((x, y, w, h))

arw、h值做一个阈值检测,过滤掉不需要的检测区域,当然阈值还是需要根据实际情况调整。

而出乎意料的是,有些区域跟检测区域具有相似外形,那么还有另外一层处理:

            if  scores[max] > 0.7:groupOutput.append(str(max))if groupOutput != []:cv2.rectangle(image, (gx - 5, gy - 5), (gx + gw + 5, gy + gh + 5), (0, 0, 255), 2)cv2.putText(image, "".join(groupOutput), (gx, gy - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)image_show(image)output.extend(groupOutput)

可以输出后续模板操作的分数,再根据匹配的分数在调整分数最小阈值,得到正确的号码。

http://www.dtcms.com/a/426791.html

相关文章:

  • Promise详细解析
  • 【从Vue3到React】Day 1: React基础概念
  • Hotfixes数据库工作原理、机制和应用流程
  • 网站建设面试表wordpress建m域名网站
  • Node.js面试题及详细答案120题(93-100) -- 错误处理与调试篇
  • pc端js动态调用提示音音频报错的问题解决
  • 网站的建设特色网站开发培训哪家好
  • C# 中的 简单工厂模式 (Simple Factory)
  • Docker linux 离线部署springcloud
  • 第 2 天:搭建 C 语言开发环境 ——VS Code/Dev-C++/Code::Blocks 安装与配置全指南
  • 基于 Celery 的分布式文件监控系统
  • CATIA二次开发(2)C#启用AOT
  • Linux 驱动开发与内核通信机制——超详细教程
  • 【langgraph】本地部署方法及实例分析
  • Linux入门指南:从零掌握基础指令
  • 做笔记的网站源码江永网站建设
  • 是时候重启了:AIGC将如何重构UI设计师的学习路径与知识体系?
  • uniapp 请求接口封装和使用
  • AIGC重构数据可视化:你是进化中的“驯兽师”还是被替代的“画图工”?
  • Apache Doris 内部数据裁剪与过滤机制的实现原理
  • 专业做网站流程小程序开发步骤大全
  • C语言基础之指针2
  • 淘客网站怎么做 知乎wordpress淘宝联盟插件
  • flink工作流程
  • openHarmony之storage_daemon:分区挂载与设备节点管理机制讲解
  • 建站怎么赚钱个人官方网站怎么建设
  • 学习笔记093——Windows系统如何定时备份远程服务器的mysql文件到本地?
  • 操作系统内核架构深度解析:从单内核、微内核到鸿蒙分布式设计
  • MySQL 架构全景解析
  • .NET MVC中实现后台商品列表功能