银行卡号识别案例

代码实现:

import cv2
import numpy as np
import argparse
import myutils
'''
-i moban.png
-t card1.png
'''
ap= argparse.ArgumentParser()
ap.add_argument("-i","--image", required=True,help="path to input image")
ap.add_argument("-t","--template", required=True,help="path to template 0cR-A image")
args = vars(ap.parse_args())
FIRST_NUMBER ={ "3":"American Express","4": "Visa","5":"MasterCard","6":"Discover Card"}
def cv_show(name,img):cv2.imshow(name,img)cv2.waitKey(0)''' --------模板图像中数字的定位处理----------- '''
img = cv2.imread(args["template"])
cv_show('img',img)
ref =cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv_show('ref',ref)
ref = cv2.threshold(ref,10,255,cv2.THRESH_BINARY_INV)[1]
cv_show('ref',ref)
_,refCnts, hierarchy = cv2.findContours(ref, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img,refCnts,-1,(0,0,255),3)
cv_show('img',img)
refCnts = myutils.sort_contours(refCnts,method="left-to-right")[0]
digits = {}
for(i,c)in enumerate(refCnts):(x,y,w,h)=cv2.boundingRect(c)roi = ref[y:y + h, x:x + w]roi =cv2.resize(roi,(57,88))cv_show('ro',roi)digits[i]= roi
print(digits)
''' --------信用卡的图像处理----------- '''
image = cv2.imread(args['image'])
cv_show('image',image)
image = myutils.resize(image,width=300)
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv_show('gray',gray)
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
tophat = cv2.morphologyEx(gray,cv2.MORPH_TOPHAT,rectKernel)
cv_show('tophat',tophat)
closeX = cv2.morphologyEx(tophat,cv2.MORPH_CLOSE,rectKernel)
cv_show('gradX',closeX)
thresh = cv2.threshold(closeX,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1]
cv_show('thresh',thresh)
thresh = cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,sqKernel)
cv_show('thresh1',thresh)
_,threshCnts,h = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = threshCnts
cur_img = image.copy()
cv2.drawContours(cur_img,cnts,-1,(0,0,255),3)
cv_show('img',cur_img)
locs = []
for (i,c) in enumerate(cnts):(x,y,w,h) = cv2.boundingRect(c)ar = w/float(h)if ar>2.5 and ar<4.0:if (w>40 and w<55) and (h>10 and h<20):locs.append((x,y,w,h))
locs = sorted(locs , key=lambda x: x[0])
print(locs)
output = []
# 遍历每一个轮廓中的数字
for (i, (gX, gY, gW, gH)) in enumerate(locs):groupOutput = []group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]  # 适当加一点边界cv_show('group', group)# 预处理group = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]cv_show('group', group)# 计算每一组的轮廓group_, digitCnts, hierarchy = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)digitCnts = myutils.sort_contours(digitCnts, method="left-to-right")[0]# 计算每一组中的每一个数值for c in digitCnts:# 找到当前数值的轮廓,resize成合适的大小(x, y, w,h) = cv2.boundingRect(c)roi = group[y:y + h, x:x + w]roi = cv2.resize(roi, (57, 88))cv_show('roi', roi)'''--------使用模板匹配,计算匹配得分-----------'''scores = []# 在模板中计算每一个得分for (digit, digitROI) in digits.items():# 模板匹配result = cv2.matchTemplate(roi, digitROI, cv2.TM_CCOEFF)(_, score, _, _) = cv2.minMaxLoc(result)scores.append(score)# 得到最合适的数字groupOutput.append(str(np.argmax(scores)))# 画出来cv2.rectangle(image, (gX - 5, gY - 5), (gX + gW + 5, gY + gH + 5), (0, 0, 255), 1)# cv2.putText()是OpenCV库中的一个函数,用于在图像上添加文本。cv2.putText(image, "".join(groupOutput), (gX, gY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)output.extend(groupOutput)  # 得到结果 将一个列表的元素添加到另一个列表的末尾。
# 打印结果
print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
print("Credit Card #: {}".format("".join(output)))
cv2.imshow("Image", image)
cv2.waitKey(0)

这段代码实现了基于模板匹配的信用卡数字识别,核心流程分为「模板图像预处理」「信用卡图像预处理」「轮廓检测与分组」「数字模板匹配与识别」四个阶段,以下是详细解析:

1. 初始化与参数解析

  • 参数解析:通过 argparse 解析命令行参数,-i 指定信用卡输入图像路径,-t 指定数字模板图像(包含 0-9 数字的参考图)。
  • 信用卡品牌映射FIRST_NUMBER 字典通过卡号首数字映射信用卡品牌(如 Visa 以 4 开头)。
  • 辅助函数cv_show 用于调试时显示图像并等待按键。

2. 模板图像预处理(制备数字模板)

目的是从模板图像中提取 0-9 的标准数字模板,供后续匹配使用:

  1. 读入与灰度转换:读取模板图像并转为灰度图。
  2. 反相二值化cv2.threshold(..., THRESH_BINARY_INV) 将数字转为白色、背景转为黑色,便于轮廓检测。
  3. 轮廓检测与排序
    • cv2.findContours 提取所有外部轮廓(每个数字对应一个轮廓)。
    • myutils.sort_contours(自定义函数)按从左到右排序轮廓,确保数字顺序与视觉一致。
  4. 提取数字 ROI 并标准化:遍历每个轮廓,提取数字区域(ROI),并缩放到统一尺寸 (57, 88),存储到 digits 字典(键为索引,值为数字模板)。

3. 信用卡图像预处理(增强数字区域)

目的是从信用卡图像中突出数字区域,便于后续轮廓检测:

  1. 读入与尺寸调整:读取信用卡图像,按比例缩放到宽度 300(方便统一处理)。
  2. 灰度转换:转为灰度图,消除颜色干扰。
  3. 形态学操作(增强数字)
    • 顶帽操作(TOPHAT):用长方形结构核 rectKernel 突出比背景亮的区域(即数字区域)。
    • 闭运算(CLOSE):先膨胀后腐蚀,用 rectKernel 连接水平方向的数字,使 “4 位一组的数字” 形成整体区域;再用正方形核 sqKernel 连接数字内部间隙,让轮廓更完整。
  4. 二值化(OTSU 自适应阈值)cv2.threshold(..., THRESH_BINARY | THRESH_OTSU) 自动确定阈值,将图像转为黑白二值图(数字为白,背景为黑)。

4. 轮廓筛选与数字分组

目的是从预处理后的图像中,筛选出 ** 信用卡数字组(通常 4 位一组)** 的轮廓:

  • 遍历所有轮廓,通过宽高比(ar宽 / 高的数值范围筛选符合 “数字组特征” 的轮廓(如信用卡数字组宽高比约 2.5-4,宽度 40-55,高度 10-20,需根据实际图像调整)。
  • 按轮廓的 x 坐标排序,确保从左到右处理数字组。

5. 数字模板匹配与识别

对每个筛选出的数字组,逐数字进行模板匹配:

  1. 提取数字组 ROI:扩展数字组的边界(gY -5 等),避免数字被截断。
  2. 数字组二值化:对提取的区域再次二值化,与模板格式一致。
  3. 单数字轮廓检测与排序:提取数字组内的单个数字轮廓,按从左到右排序。
  4. 模板匹配
    • 对每个单数字 ROI,缩放到模板尺寸 (57, 88)
    • 用 cv2.matchTemplate(方法为 TM_CCOEFF)与 digits 中所有数字模板匹配,计算 “匹配得分”。
    • 选择得分最高的模板,其索引对应数字(如索引 0 对应模板中最左侧数字)。
  5. 结果绘制与存储:在原图上绘制数字组的矩形框,并将识别出的数字用 cv2.putText 显示;同时将数字存入 output 列表,最终拼接为完整卡号。

6. 信用卡品牌与卡号输出

  • 从 output 中取首数字,通过 FIRST_NUMBER 字典判断信用卡品牌。
  • 打印品牌与完整卡号,并显示最终图像。

关键注意事项

  • 参数适配:形态学核的尺寸、轮廓筛选的宽高比 / 范围,需根据图像分辨率、数字大小调整。
  • 模板质量:模板图像的清晰度、数字完整性,直接影响匹配准确率。
  • 排序依赖myutils.sort_contours(自定义轮廓排序函数)是确保 “数字顺序正确” 的关键。
  • 匹配方法TM_CCOEFF 适合黑白模板匹配,因它对亮度差异不敏感,更关注形状相关性。

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

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

相关文章

云管平台上线只是开始:从“建好”到“用好”的运营、推广与深化指南

项目上线的喜悦转瞬即逝,随之而来的是一个更为现实和复杂的阶段:运营。云管平台(CMP)的成功,不再仅仅取决于其技术架构的先进性,更在于它能否融入组织的肌理,为不同角色持续创造价值。本文将从管理者、平台团队、开发者、运维和财务五个核心角色的视角,深入探讨平台上线…

distributed.client.Client 用户可调用函数分析

distributed.client.Client 用户可调用函数分析 1. 核心计算函数 任务提交和执行submit(func, *args, keyNone, workersNone, resourcesNone, retriesNone, priority0, fifo_timeout60s, allow_other_workersFalse, actorFalse, actorsFalse, pureNone, **kwargs) 提交单个函数…

数字图像处理——信用卡识别

在数字支付时代&#xff0c;信用卡处理自动化技术日益重要。本文介绍如何利用Python和OpenCV实现信用卡数字的自动识别&#xff0c;结合图像处理与模式识别技术&#xff0c;具有显著实用价值。系统概述与工作原理信用卡数字识别系统包含两大核心模块&#xff1a;模板数字预处理…

嵌入式ARM64 基于RK3588原生SDK添加用户配置选项./build lunch debian

1 背景 在我们正常拿到SDK后会有一些配置选项&#xff0c;在使用./build.sh lunch之后会输出一些defautconfig让我们选择&#xff0c;瑞芯微的原厂sdk会提供一些主板的配置选项&#xff0c;但是我们的如果是一块新的主板就需要添加自己的配置选项&#xff0c;本文就讨论如何来添…

专为石油和天然气检测而开发的基于无人机的OGI相机

专为石油和天然气检测而开发的基于无人机的OGI相机基于无人机的 OGI 相机:&#xff08;Optical Gas Imaging&#xff0c;光学气体成像&#xff09;其实是近几年油气、电力、化工等行业里非常热门的应用方向。什么是 OGI 相机OGI&#xff08;Optical Gas Imaging&#xff09;&am…

iPhone17全系优缺点分析,加持远程控制让你的手机更好用!

知名数码厂商苹果&#xff0c;不久前已官宣将于北京时间9月10日凌晨1点开启发布会&#xff0c;主打对于iPhone 17系列产品介绍&#xff0c;并且和以往不同的是&#xff0c;今年会在购物平台上开启线上直播&#xff0c;还是很有新意的。9.13全平台渠道将开启预售模式&#xff0c…

人工智能-python-深度学习-神经网络VGG(详解)

LeNet 系列之后 —— VGG&#xff08;详解&#xff09;&#xff1a;从原理到 PyTorch 实现 文章目录LeNet 系列之后 —— **VGG&#xff08;详解&#xff09;**&#xff1a;从原理到 PyTorch 实现1. VGG 的发展历史与意义&#xff08;一句话&#xff0b;背景&#xff09;2. VGG…

光伏运维迎来云端革命!AcrelCloud-1200如何破解分布式光伏四大痛点?

在国家“双碳”目标推动下&#xff0c;分布式光伏正迎来爆发式增长&#x1f31e;。甘肃、吉林、云南等多地政策接连落地&#xff0c;整县推进屋顶光伏试点如火如荼&#xff01;然而&#xff0c;快速发展的背后&#xff0c;你是否也遇到过这些“光伏运维之痛”&#xff1f;✨【痛…

将 maven 集成到 idea 后出现 向项目创建模块时出错:null 的问题

1.出现的问题今天想将maven继承到idea出现了一下问题&#xff1a;用生成器里面的也会报错&#xff0c;找了找帖子并没有哪位大佬出现类似错误&#xff0c;于是我解决完想分享一下&#xff0c;如果有不对&#xff0c;请指正。2.解决办法很可能是java 的 版本 与 maven 版本有问题…

类似于 Progress Telerik Fiddler Classic 的 免费 或 开源 HTTP/HTTPS 抓包与调试工具推荐

以下是一些 类似于 Progress Telerik Fiddler Classic 的 免费 或 开源 HTTP/HTTPS 抓包与调试工具推荐&#xff1a;免费 / 开源替代工具推荐 1. Wireshark 免费且开源的网络协议分析工具&#xff0c;支持 Windows、macOS、Linux 等平台。可捕获并深入分析网络流量&#xff0c;…

7.0 热电偶的工作原理

在工业生产过程中&#xff0c;温度是需要测量和控制的重要参数之一。在温度测量中&#xff0c;热电偶的应用极为广泛&#xff0c;它具有结构简单、制造方便、测量范围广、精度高、惯性小和输出信号便于远传等许多优点。另外&#xff0c;由于热电偶是一种无源传感器&#xff0c;…

commons-lang3

概述 提供了许多帮助程序实用程序&#xff0c;特别是字符串操作方法&#xff0c;基本数值方法&#xff0c;对象反射&#xff0c;并发&#xff0c;创建和序列化以及系统属性。maven依赖<dependency><groupId>org.apache.commons</groupId><artifactId>c…

vue-amap组件呈现的效果图如何截图

我们用amap呈现了几个图层后&#xff0c;用户觉得效果很好&#xff0c;想点个按钮直接将这个画面截图下来。 首先我们用Canvas的toDataURL方法可以直接获取图像数据&#xff0c;但是实践发现截图后是空白的。 原因在警告中&#xff1a; 地图的WebGL context 的preserveDrawin…

杰理烧录ERROR: Data error after erasing, address = 0x430000

把CONFIG_BOARD_DEV_KIT关闭&#xff0c;打开CONFIG_BOARD_DEVELOP

超越自动化:为什么说供应链的终局是“AI + 人类专家”的混合智能?

摘要&#xff1a;当前&#xff0c;围绕AI赋能供应链的讨论&#xff0c;大多聚焦于“自动化”带来的降本增效。然而&#xff0c;这仅仅是第一层。当我们的系统面对“黑天鹅”事件时&#xff0c;一个过度依赖自动化的“脆弱”系统可能会瞬间崩溃。本文旨在深入探讨供应链演进的下…

Spine文件导入Unity流程

1、转为Json文件导出 2、对文件进行处理 3、添加Spine的Package包 一、Spine文件导出设置 1、选择Json文件 2、选择导出所在路径 3、点击打包设置 更改图集扩展名 二、文件导出后的设置 1、修改Json的Spine版本 这里必须是3.8 三、下载Unity支持包 1、链接 spine-unit…

Docker Compose healthcheck介绍(监控容器中服务的实际健康状态)数据库健康检查pg_isready

文章目录**功能概述****核心参数详解****配置示例****1. 基础用法****2. 使用数据库健康检查****3. 结合 depends_on 控制启动顺序****高级用法****1. 自定义健康检查脚本****2. 多种健康检查类型**- **HTTP 检查**&#xff1a;- **TCP 端口检查**&#xff1a;- **Redis 检查**…

算法之双指针

在算法设计中&#xff0c;双指针是一种高效优化工具&#xff0c;主要用于线性数据结构&#xff08;如数组&#xff08;数组划分和数组分块常用&#xff09;、链表、字符串&#xff09;&#xff0c;通过控制两个指针的移动轨迹&#xff0c;将原本需要 O (n) 时间复杂度的问题优化…

幂等性、顺序性保障以及消息积压

幂等性 概念 在应用程序中&#xff0c;幂等性就是指对一个系统进行重复调用&#xff08;相同参数&#xff09;&#xff0c;不论请求多少次&#xff0c;这些请求对系统的影响都是相同的效果. 比如数据库的select操作.不同时间两次查询的结果可能不同&#xff0c;但是这个操作…

算法训练营DAY58 第十一章:图论part08

拓扑排序精讲 卡码网&#xff1a;117. 软件构建(opens new window) 题目描述&#xff1a; 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件依赖于其他文件的内容&#xff0c;这意味着如果文件 A 依…