opencv学习:信用卡卡号识别

news/2024/9/18 9:52:58/ 标签: opencv, 学习, 机器学习, 算法

该代码用于从信用卡图像中自动识别和提取数字信息。该系统将识别信用卡类型,并输出信用卡上的数字序列。

1.创建命令行参数

数字模板

信用卡

# 创建命令行参数解析器
ap = argparse.ArgumentParser()
# 添加命令行参数 -i/--image,指定输入图像路径
ap.add_argument("-i", "--image", required=True, help="path to input image")
# 添加命令行参数 -t/--template,指定模板图像路径
ap.add_argument("-t", "--template", required=True, help="path to template OCR-A image")
# 解析命令行参数
args = vars(ap.parse_args())

2.指定信用卡类型

# 指定信用卡类型
FIRST_NUMBER = {"3": "American Express", "4": "Visa", "5": "MasterCard", "6": "Discover Card"}

3.将模板数字图像转换为二值图像

def cv_show(name, img):  # 绘图展示cv2.imshow(name, img)cv2.waitKey(0)# 读取模板图像
img = cv2.imread(args["template"])
ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转换为灰度图
ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]  # 二值图像

4.找到二值图像的轮廓

# 找到二值图像中的轮廓
_, refCnts, _ = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, refCnts, -1, (0, 0, 255), 3)  # 在原始图像上绘制轮廓

5.使用自定义函数对轮廓进行排序

# 使用自定义函数对轮廓进行排序
refCnts = 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))  # 缩放到指定的大小digits[i] = roi  # 每一个数字对应每一个模板

6.获取信用卡灰度图

# 读取信用卡图像
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 转换为灰度图

7.使用形态学操作来增强图像中的数字

# 使用形态学操作来增强图像中的数字
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)
closeX = cv2.morphologyEx(tophat, cv2.MORPH_CLOSE, rectKernel)
thresh = cv2.threshold(closeX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)

8.找到处理后的图像中的轮廓

# 找到处理后的图像中的轮廓
_, threshCnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = threshCnts

9.绘制轮廓

# 绘制轮廓
cur_img = image.copy()
cv2.drawContours(cur_img, cnts, -1, (0, 0, 255), 3)

10.存储所识别的排序后的数字

# 初始化一个空列表,用于存储检测到的数字的位置信息
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))# 根据x坐标对位置信息进行排序,确保从左到右识别数字
locs = sorted(locs, key=lambda x: x[0])

11.识别所有卡号的数字,并在原图上面写下卡号

# 初始化一个空列表,用于存储识别出的数字
output = []# 遍历每个数字的位置信息
for (i, (gX, gY, gW, gH)) in enumerate(locs):groupOutput = []  # 初始化一个空列表,用于存储当前数字组的输出# 提取当前数字组的图像区域group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]# 对提取的图像区域进行二值化处理group = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]# 找到当前数字组中的每个数字的轮廓group_, digitCnts, _ = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 对数字轮廓进行排序digitCnts = sort_contours(digitCnts, method="left-to-right")[0]# 遍历每个数字的轮廓for c in digitCnts:# 计算每个数字的边界矩形(x, y, w, h) = cv2.boundingRect(c)# 提取每个数字的图像区域roi = group[y:y + h, x:x + w]# 将图像区域调整为模板大小roi = cv2.resize(roi, (57, 88))# 初始化一个空列表,用于存储每个数字的匹配得分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(image, "".join(groupOutput), (gX, gY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)# 将识别出的数字添加到输出列表中output.extend(groupOutput)

12.打印信用卡类型和ID

# 打印信用卡类型和ID
print("card Type:{}".format(FIRST_NUMBER[output[0]]))
print("card ID:{}".format("".join(output)))# 显示最终结果
cv2.imshow("image", image)
cv2.waitKey(0)

13.实验结果


http://www.ppmy.cn/news/1525626.html

相关文章

饿了么基于Flink+Paimon+StarRocks的实时湖仓探索

摘要&#xff1a;本文整理自饿了么大数据架构师、Apache Flink Contributor 王沛斌老师在8月3日 Streaming Lakehouse Meetup Online&#xff08;Paimon x StarRocks&#xff0c;共话实时湖仓架构&#xff09;上的分享。主要分为以下三个内容&#xff1a; 饿了么实时数仓演进之…

python-游戏自动化(一)(实战-自动刷视频点赞)

前提准备 什么是游戏自动化&#xff1f; 游戏自动化是指通过对游戏的界面结构的解析或界面图像的处理与识别&#xff0c;再模拟人工对软件进行的各种操作&#xff0c;从而实现自动化&#xff0c;达到解放双手&#xff0c;节约时间&#xff0c;提高效率的目标。 在本教程中&am…

房产销售系统开发:SpringBoot技术要点

摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于房产销售系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了房产销售系统&#xff0c;它彻底改变了过去传统的…

RDMA应用场景及效果

GPU Direct 参考&#xff1a;网络架构如何支持超万卡的大规模 AI 训练&#xff1f;| AICon_芯片与网络_InfoQ精选文章 GPU 网络的情况已经发生了很大变化。每个 GPU 都有自己的内部互联&#xff0c;例如 NVIDIA 的 A100 或 H800&#xff0c;它们内部的 NVLink 互联可以达到 6…

【网络安全】空字节绕过:URL回调+XSS+SQL绕WAF

未经许可,不得转载。 文章目录 空字节URL回调XSSSQL空字节 \0,也称为null字节,是一个值为零的特殊字符。在编程中,通常用来表示字符串的结束。攻击者可以利用null字节注入来绕过一些验证或过滤机制。 以下三个漏洞,空字节功不可没。 URL回调 密码重置功能,发起请求后…

如何找到UI5 Tooling-UI5命令

文章目录 UI5 Tooling第一步&#xff1a;首先找找到UI5 的官网如下&#xff1a;第二步&#xff1a;找到get started&#xff0c; 学习UI5 Demo第三步&#xff1a;开发环境--搭建安装UI5 命令行界面Global installation to have the command availableAdditional local install …

学习平台|基于java的移动学习平台系统小程序(源码+数据库+文档)

学习平台|学习平台系统|在线学习平台系统小程序 目录 基于java的移动学习平台系统小程序 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码…

基于大数据的科研热点分析与挖掘系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 科研活动的快速发展产生了大量的学术文献&#xff0c;如何从这些文献中提炼出有价值的科研热点和趋势成为了一个重要的问题。本项目旨在开发一个基于大数据的科研热点分析可视化系统&#xff0c;采…

综合型医院适合什么样的数据摆渡方式,才能服务与安全兼顾?

综合型医院&#xff0c;是提供全面医疗服务的综合型医院。综合型医院的服务对象广泛&#xff0c;包括儿童、成人、老年人等各年龄段的人群&#xff0c;以及患有各种疾病的患者。它们通过提供全面的医疗服务&#xff0c;保障人民群众的健康需求&#xff0c;是医疗卫生事业的重要…

ComfyUI安装节点过程中被降低了版本的软件包重新安装

最近在安装2个没怎么及时更新节点时&#xff0c;安装节点依赖性过程中&#xff0c;将原高版本的软件包&#xff0c;给降到了低版本&#xff0c;解决的办法就是&#xff1a;1、再次删除软件包&#xff0c;2、指定版本号重新安装回高版本软件包。

maven父子工程多模块如何管理统一的版本号?

1.为什么要统一管理&#xff1f; maven父子工程多模块&#xff0c;每个模块还都可以独立存在&#xff0c;子模块往往通常希望和父工程保持一样的版本&#xff0c;如果每个工程单独定义版本号&#xff0c;后期变更打包也非常麻烦&#xff0c;如何维护一个全局的版本号呢&#x…

【运维】自动化运维工具,使用 Ansible 进行开发环境配置管理(本地/远程,brew/scoop/yum,docker/packer/openstack)

【运维】自动化运维工具&#xff0c;使用 Ansible 进行开发环境配置管理&#xff08;本地/远程&#xff0c;brew/scoop/yum&#xff0c;docker/packer/openstack&#xff09; 文章目录 1、什么是 Ansible&#xff0c;如何安装2、使用 ansible 自动配置本地开发环境&#xff08;…

前端页面加载由模糊到清晰的实现方案

要实现图片加载时由模糊逐渐变得清晰的效果&#xff0c;可以使用 CSS 和 JavaScript 的结合。这里的思路是&#xff1a;先让图片在加载时模糊显示&#xff0c;等图片完全加载完后&#xff0c;再去掉模糊效果。 1. 使用 CSS 实现模糊效果 我们可以使用 filter: blur() 来为图片…

[数据集][目标检测]车油口挡板开关闭合检测数据集VOC+YOLO格式138张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;138 标注数量(xml文件个数)&#xff1a;138 标注数量(txt文件个数)&#xff1a;138 标注类别…

从C语言过渡到C++

&#x1f4d4;个人主页&#x1f4da;&#xff1a;秋邱-CSDN博客☀️专属专栏✨&#xff1a;C &#x1f3c5;往期回顾&#x1f3c6;&#xff1a;单链表实现&#xff1a;从理论到代码-CSDN博客&#x1f31f;其他专栏&#x1f31f;&#xff1a;C语言_秋邱的博客-CSDN博客 目录 ​…

Day 72

作业 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QLineEdit> #include <QLabel> #include <QIcon> #include <QPushButton> #include <QMovie> #include <QPainter> #include <QWidget> …

性能测试 —— linux服务器搭建JMeter+Grafana+Influxdb监控可视化平台!

前言 在当前激烈的市场竞争中&#xff0c;创新和效率成为企业发展的核心要素之一。在这种背景下&#xff0c;如何保证产品和服务的稳定性、可靠性以及高效性就显得尤为重要。 而在软件开发过程中&#xff0c;性能测试是一项不可或缺的环节&#xff0c;它可以有效的评估一个系…

Leetcode - 周赛414

目录 一&#xff0c;3280. 将日期转换为二进制表示 二&#xff0c;3281. 范围内整数的最大得分 三&#xff0c;3282. 到达数组末尾的最大得分 四&#xff0c;3283. 吃掉所有兵需要的最多移动次数 一&#xff0c;3280. 将日期转换为二进制表示 本题就是简单的字符串和整数之…

EG边缘计算网关连接中移ONENET物联网平台(MQTT协议)

上文&#xff1a;EG边缘计算网关连接阿里云物联网平台&#xff08;MQTT协议&#xff09; 需求概述 本章节主要实现一个流程&#xff1a;EG8200mini采集Modbus RTU数据&#xff0c;通过MQTT协议连接中移ONENET物联网平台 Modbus RTU采集此处不做过多赘述&#xff0c;可参考其…

在线小说|基于java的小说阅读系统小程序(源码+数据库+文档)

在线小说|小说阅读系统|小说阅读系统小程序 目录 基于java的小说阅读系统小程序 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布…