基于opencv-python模板匹配的银行卡号识别(附源码)
目录
介绍
数字模板处理
银行卡图片处理
导入数字模板
模板匹配及结果
介绍
我们有若干个银行卡图片和一个数字模板图片,如下图


我们的目的就是通过对银行卡图片进行一系列图像操作使得我们可以用这个数字模板检测出银行卡号。
数字模板处理
首先我们先对数字模板进行处理,处理的目的是将数字模板中的每个数字分割开来。
先导入需要用到的包
import cv2
import os
import numpy as np
import matplotlib.pyplot as plt
然后再定义一个修改图片尺寸的函数
#修改尺寸
def img_resize(img, hight):(h, w) = img.shape[0], img.shape[1]r = h / hightwidth = w / rimg = cv2.resize(img, (int(width), int(hight))) return img
接下来,我们读入数字模板图片并对其进行灰度化,二值化和轮廓检测
#读入总模板
img = cv2.imread('images/ocr_a_reference.png')
ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ref,thresh= cv2.threshold(ref, 127, 255, cv2.THRESH_BINARY_INV)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
由于模板比较简单,故用这些操作即可分割出来数字模板中的每个数字,我们可以看一下操作完后的结果
for i in range(len(contours)):x, y, w, h = cv2.boundingRect(contours[i])plt.subplot(3, 4, i + 1)plt.imshow(thresh[y:y + h, x:x + w], cmap=plt.cm.gray)plt.xticks([])plt.yticks([])plt.show()

接下来,我们将各个模板保存起来,以便于后期读取使用
#保存模板
if not os.path.exists('data'):os.mkdir('data')for i in range(len(contours)):x, y, w, h = cv2.boundingRect(contours[i])cv2.imwrite(os.path.join('data', str(9-i)+'.jpg'), thresh[y:y+h, x:x+w])
保存完后会生成一个data文件夹,可以看到每个数字都已经单独分割保存为单张图片了

到这里,数字模板处理就完成了
银行卡图片处理
我们是要基于模板匹配去识别具体的银行卡号,而且我们在上述操作中已经得到了每个数字的模板,所以我们现在只需要从银行卡里面切割处理每个银行卡号,就可以进行模板匹配,那么怎么切割出银行卡里的每个号码呢,这里小编尝试过直接用图像处理技术进行单个切割,但发现效果并不好。此时我们发现银行卡号共有16位,其中每4位离的都比较近,那我们可不可以先画出整体四个,然后再对四个进行单独切割呢,显然,这样做的效果是比较好的。
我们首先读入银行卡图片并修改尺寸和做灰度化处理
#灰度化
img = cv2.imread('images/credit_card_01.png')
img = img_resize(img, 200)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
plt.imshow(gray, cmap=plt.cm.gray)

然后对灰度图进行礼貌操作,用来突出银行卡中的数字
#礼貌操作
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 5))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
tophat = cv2.morphologyEx(gray,cv2.MORPH_TOPHAT,rectKernel)
plt.imshow(tophat, cmap=plt.cm.gray)

然后利用sobel算子增强图片的边缘信息,即增强数字信息
#sobel边缘检测
sobel = cv2.Sobel(tophat, cv2.CV_64F,dx=1, dy=0, ksize=3)
sobel = cv2.convertScaleAbs(sobel)
minval, maxval = np.min(sobel), np.max(sobel)
sobel = (255 * ((sobel - minval) / (maxval - minval)))
sobex = sobel.astype('uint8')
plt.imshow(sobex, cmap=plt.cm.gray)

再对图像进行膨胀和腐蚀的操作,使得每四个数字连接在一起
#膨胀腐蚀
dilate = cv2.dilate(sobel, rectKernel, 10)
erosion = cv2.erode(dilate, rectKernel, 10)
plt.imshow(erosion, cmap=plt.cm.gray)

此时发现图像上有些噪声,所以我们对图像进行二值化操作,以去除这些白点
#二值化
erosion = cv2.convertScaleAbs(erosion)
ret, thresh = cv2.threshold(erosion, 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)
plt.imshow(thresh, cmap=plt.cm.gray)

进行完二值化操作后,再进行一次膨胀腐蚀操作,加深数字区域信息
#膨胀腐蚀
dilate = cv2.dilate(thresh, sqKernel, 10)
erosion = cv2.erode(dilate, sqKernel, 10)
plt.imshow(dilate, cmap=plt.cm.gray)

现在效果就比较好了,我们就可以在此图像上画轮廓了
#画轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cur_img = img.copy()
cur_img = cv2.cvtColor(cur_img, cv2.COLOR_BGR2RGB)
cv2.drawContours(cur_img,contours,-1,(0,0,255),3)
plt.imshow(cur_img)

但是我们发现,这个轮廓不仅廓住了数字区域,还廓住了其他区域,此时我们将数字区域轮廓过滤出来,并画出来数字区域显示一下(数字是棕色的是因为此时显示的BGR图像)
#过滤轮廓
locs = []
for(i,c) in enumerate(contours):(x,y,w,h) = cv2.boundingRect(c)ar = w/float(h)if ar>2.5 and ar<4.0:if(w>40 and w<60) and (h>10 and h<20):locs.append((x,y,w,h))
print(len(locs))for i in range(len(locs)):x,y,w,h = locs[3-i]contour = img[y:y+h, x:x+w,:]plt.subplot(2, 2, i+1)plt.imshow(contour)plt.xticks([])plt.yticks([])plt.show()

此时没有银行卡上其他信息的干扰,我们可以很简单的使用灰度化,二值化和轮廓检测来廓住每个单独的数字
#进行最后的处理
results = []
for i in range(len(locs)):x,y,w,h = locs[3-i]img_new = img[y:y+h, x:x+w,:]gray = cv2.cvtColor(img_new, cv2.COLOR_BGR2GRAY)ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)res = img_new.copy()for j in range(len(contours)):x, y, w, h = cv2.boundingRect(contours[3-j])res = cv2.rectangle(res, (x, y), (x+w, y+h), (255, 0, 0), 1)results.append(thresh[y:y+h, x:x+w])plt.subplot(2, 2, i+1)plt.imshow(res, cmap=plt.cm.gray)plt.xticks([])plt.yticks([])plt.show()

最后我们就可以得到银行卡中的每个单独号码
#可以看一下results
for i in range(16):results[i] = cv2.resize(results[i], (10, 15))plt.subplot(2, 8, i+1)plt.imshow(results[i], cmap=plt.cm.gray)plt.xticks([])plt.yticks([])plt.show()

导入数字模板
在处理完银行卡后,我们导入我们一开始获得的数字模板,进行最后的模板匹配
#引入模板
digits = {}
for i in range(10):digits[i] = cv2.resize(cv2.imread('data/{}.jpg'.format(i)), (10, 15))digits[i] = cv2.cvtColor(digits[i], cv2.COLOR_BGR2GRAY)ref, digits[i] = cv2.threshold(digits[i], 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)for i in range(10):plt.subplot(2, 5, i+1)plt.imshow(digits[i], cmap=plt.cm.gray)plt.xticks([])plt.yticks([])plt.show()

模板匹配及结果
导入数字模板后,就可以进行模板匹配得到结果了
#模板匹配得出结果
res = ''
for i in results:scores = []for j in range(10):result = cv2.matchTemplate(i, digits[j], cv2.TM_CCOEFF) # result为一个输出矩阵(_, score, _, _) = cv2.minMaxLoc(result) # 这个方法会返回最小值,最大值,最小值位置和最大值位置scores.append(score)res = res + str(np.argmax(scores))
print(res)plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show

我们也可以看一下其他银行卡的匹配结果




其中有一张银行卡号的识别好像因为环境等因素出了点问题,其他的识别都是没问题的,大体来说结果还算可以
源码及文件请查看:https://github.com/jvyou/Bank-card-number-identification
效果演示请查看:https://www.bilibili.com/video/BV1hK421C7Bk/?spm_id_from=333.999.0.0&vd_source=ea64b940c4e46744da2aa737dca8e183
相关文章:
基于opencv-python模板匹配的银行卡号识别(附源码)
目录 介绍 数字模板处理 银行卡图片处理 导入数字模板 模板匹配及结果 介绍 我们有若干个银行卡图片和一个数字模板图片,如下图 我们的目的就是通过对银行卡图片进行一系列图像操作使得我们可以用这个数字模板检测出银行卡号。 数字模板处理 首先我们先对数…...
JAVA设计模式之建造者模式详解
建造者模式 1 建造者模式介绍 建造者模式 (builder pattern), 也被称为生成器模式 , 是一种创建型设计模式. 定义: 将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。 **建造者模式要解决的问题 ** 建造者模式可以将部件和其组装过程分开…...
ElasticSearch查询语句用法
查询用法包括:match、match_phrase、multi_match、query_string、term 1.match 1.1 不同字段权重 如果需要为不同字段设置不同权重,可以考虑使用bool查询的should子句来组合多个match查询,并为每个match查询设置不同的权重 {"query&…...
美国服务器如何
美国服务器在被选择名单里排名很高,那么美国服务器如何,美国服务器 适用于哪些场景,认可度高吗?接下来小编为您整理发布美国服务器如何的详细情况。 美国服务器通常以其高性能、高可靠性和安全性而受到认可,它们适用于多种业务场…...
远程主机可能不符合glibc和libstdc++ VS Code服务器的先决条件
报错信息 VSCode无法连接远程服务器,终端一直提醒: [22:46:01.906] > Waiting for server log... [22:46:01.936] > Waiting for server log... [22:46:01.951] > [22:46:01.967] > Waiting for server log... [22:46:01.982] > [22:…...
【python基础】sys.argv[]的使用方法
文章目录 前言一、sys.argv是什么?二、实例 前言 本文主要讲解sys.argv[]的使用方法。 一、sys.argv是什么? sys.arg[]的作用就是存储在运行python脚本时候从外部往被运行的py文件里面传递的参数,是一个列表对象。利用好这个属性可以极大的增…...
Element-Ui el-date-picker日期传值异常问题解决办法
首先,只要非常简单的组件引入写法: 然后myDate在data()中是字符串类型 myDate: ‘’ 然后增加一个方法在提交表单到后台的时候,用来转化日期对应到myDate成字符串类型,并且对应到java类 function checkType(value) {if (typeo…...
GO语言集成开发 JetBrains GoLand 2023 中文
JetBrains GoLand 2023是一款专为Go语言开发者打造的集成开发环境(IDE)。它基于IntelliJ IDEA平台,提供了丰富的功能和工具,旨在提高开发效率和质量。GoLand 2023具备强大的Go语言支持,包括语法高亮、自动补全、代码提…...
详细关于如何解决mfc140.dll丢失的步骤,有效修复mfc140.dll文件丢失的问题。
mfc140.dll文件是Microsoft Visual Studio 2015程序集之一,它包含用于支持多种功能的代码和库。当这个mfc140.dll文件丢失时,可能会导致相关程序运行出错甚至无法运行。很多用户可能会遇到mfc140.dll丢失的问题,但是这并不是不可解决的困难。…...
聚簇索引、非聚簇索引、回表、索引下推、覆盖索引
聚簇索引(主键索引) 非叶子节点上存储的是索引值,叶子节点上存储的是整行记录。 非聚簇索引(非主键索引、二级索引) 非叶子节点上存储的都是索引值,叶子节点上存储的是主键的值。非聚簇索引需要回表&…...
ES实战-book笔记1
#索引一个文档,-XPUT手动创建索引, curl -XPUT localhost:9200/get-together/_doc/1?pretty -H Content-Type: application/json -d {"name": "Elasticsearch Denver","organizer": "Lee" } #返回结果 {"_index" : "g…...
高防服务器出租的优势及特点
高防服务器出租是指租用具备高防御能力的服务器,用于应对网络攻击、保护网站和数据安全。那么为什么会选择高防服务器出租,小编为您整理发布高防服务器出租的优势及特点。 高防服务器通常具备以下特点: 1. 高性能硬件配置:高防服务…...
NTLM||LM算法lsasswinlogon进程
来填坑了,这篇blog我们就来讲一下mimikatz能抓到开机的密码的原理 1.lsass&&winlogon 不知道大家有没有好奇过,我们每次开机输入密码之后,电脑又怎么知道我们是否输入正确呢? :这就要的得益于我们的两个进程…...
transformer剪枝论文汇总
文章目录 NN Pruning摘要实验 大模型剪枝LLM-PrunerSparseGPT LTPVTPWidth & Depth PruningPatch SlimmingDynamicViTSPViTDynamicBERTViT SlimmingFastFormersNViTUVCPost-training pruning NN Pruning 《Block Pruning For Faster Transformers》 《为更快的transformer…...
使用 Ant Design 的 Upload 组件实现图片
文章目录 使用 Ant Design 的 Upload 组件实现图片Upload组件itemRender自定义上传列表项的渲染方式修改图片名上传图片上传链接中添加 Bearer Token 的请求头onPreview{handlePreview}上传成功后,如何隐藏上传列表 使用 Ant Design 的 Upload 组件实现图片 Upload…...
【知识图谱--第二讲知识图谱的表示】
知识图谱的表示 知识表示Knowledge Representation 知识表示方法知识图谱的符号表示基于图的知识表示与建模简单图建模-最简单的无向图有向标记图OWL与Ontology 知识图谱的向量表示 知识表示 Knowledge Representation 知识表示(KR)就是用易于计算机处…...
C语言---计算n的阶乘
阶乘的概念:一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,且0的阶乘为1,自然数n的阶乘写作n! 。 任何大于等于1 的自然数n 阶乘表示方法: n!123…(n-1)n 或 n!n(n-1)! 0!1 …...
材料非线性Matlab有限元编程:初应力法与初应变法
导读:本文主要围绕材料非线性问题的有限元Matlab编程求解进行介绍,重点围绕牛顿-拉普森法(切线刚度法)、初应力法、初应变法等三种非线性迭代方法的算法原理展开讲解,最后利用Matlab对材料非线性问题有限元迭代求解算法进行实现,展示了实现求解的核心代码。这些内容都将收…...
QT+OSG/osgEarth编译之八十二:osgdb_obj+Qt编译(一套代码、一套框架,跨平台编译,版本:OSG-3.6.5插件库osgdb_obj)
文章目录 一、osgdb_obj介绍二、文件分析三、pro文件四、编译实践一、osgdb_obj介绍 OBJ格式是一种标准的3D模型文件格式,它以纯文本形式存储关于3D模型的信息。这种格式最初由Wavefront Technologies为其高级可视化系统开发,后来被广泛应用于3D软件之间的数据交换。OBJ格式…...
[office] excel求乘积的公式和方法 #媒体#笔记#经验分享
excel求乘积的公式和方法 本文首先给出两个常规的excel求乘积的链接,然后再例举了一个文字和数字在同一单元格里面的excel求乘积的公式写法。 excel求乘积的方法分为两种,第一种是直接用四则运算的*来求乘积,另外一种就是使用PRODUCT乘积函数…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
