《Opencv》信用卡信息识别项目
目录
一、项目介绍
二、数据材料介绍
1、模板图片(1张)
2、需要处理的信用卡图片(5张)
三、实现过程
1、导入需要用到的库
2、设置命令行参数
3、模板图像中数字的定位处理
4、信用卡图像处理
5、模板匹配
四、总结
一、项目介绍
项目的主要目标是实现信用卡号码和类型的识别。通过图像处理技术,从信用卡图像中提取出卡号,将每个数字与模板数字进行比对,从而得出信用卡号码。并根据卡号的第一位数字判断信用卡的类型。
二、数据材料介绍
1、模板图片(1张)
2、需要处理的信用卡图片(5张)
三、实现过程
1、导入需要用到的库
import numpy as np
import argparse
import cv2
import myutils
其中myutils模块为自己编写的工具模块,里面包含了对轮廓进行排序的函数以及自动变换图片大小的函数,内容如下:
"""myutil.py"""import cv2# 排序函数
def sort_contours(cnts, method='left-to-right'):# 初始化排序方向和索引reverse = Falseaxis_index = 0 # 默认按 x 轴排序(从左到右或从右到左)# 根据排序方法设置排序方向和索引if method == 'right-to-left' or method == 'bottom-to-top':reverse = True # 反向排序if method == 'top-to-bottom' or method == 'bottom-to-top':axis_index = 1 # 按 y 轴排序(从上到下或从下到上)# 计算每个轮廓的边界框bounding_boxes = [cv2.boundingRect(c) for c in cnts]# 将轮廓和边界框组合在一起combined = list(zip(cnts, bounding_boxes))# 根据边界框的坐标进行排序sorted_combined = sorted(combined, key=lambda x: x[1][axis_index], reverse=reverse)# 解包排序后的轮廓和边界框sorted_cnts = [item[0] for item in sorted_combined]sorted_bounding_boxes = [item[1] for item in sorted_combined]return sorted_cnts, sorted_bounding_boxes# 变换图片大小的函数
def resize(image, width=None, height=None, inter=cv2.INTER_AREA):dim = None(h, w) = image.shape[:2]if width is None and height is None:return imageif width is None:r = height / float(h)dim = (int(w * r), height)else:r = width / float(w)dim = (width, int(h * r))resized = cv2.resize(image, dim, interpolation=inter)#参数interpolation指定了在图像大小调整过程中如何处理像素插值的方法。cv2.INTER_AREA具体意味着使用面积插值方法。return resized
2、设置命令行参数
- --image为信用卡图片
- --template为模板图片
ap = argparse.ArgumentParser()
ap.add_argument('-i','--image',required=True,help='')
ap.add_argument('-t','--template',required=True,help='')
args = vars(ap.parse_args())# 信用卡号码开头对应信用卡的类型
FIRST_NUMBER = {"3":"American Express","4":"Visa","5":"MasterCard","6":"Discover Card"}
# 定义显示图片函数
def cv_show(name, image):cv2.imshow(name, image)cv2.waitKey(0)
3、模板图像中数字的定位处理
-
读取模板图像(包含 0-9 的数字)。
-
对模板图像进行灰度化、二值化处理。
-
使用轮廓检测提取每个数字的轮廓,并将每个数字裁剪出来,保存为模板。
"""模板图像中数字的定位处理"""
# img为模板图像
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 = cv2.findContours(ref.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[1]
cv2.drawContours(img,refCnts,-1,(0,0,255),2)
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))digits[i] = roicv_show('roi',roi)
print(len(digits))
4、信用卡图像处理
-
读取信用卡图像。
-
对信用卡图像进行灰度化、顶帽操作(去除背景)、闭操作(将数字连在一起)、自适应二值化等处理。
-
使用轮廓检测找到信用卡上的数字区域。
"""信用卡的图像处理"""
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)
# 开运算
open = cv2.morphologyEx(gray,cv2.MORPH_OPEN,rectKernel)
cv_show('open',open)
cv_show('tophat',tophat)# 找数字边框
# 闭操作,将数字连在一起
closeX = cv2.morphologyEx(tophat,cv2.MORPH_CLOSE,rectKernel)
cv_show('closeX',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 = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[1]
cnts = threshCnts
cur_img = image.copy()
cv2.drawContours(cur_img,cnts,-1,(0,0,255),3)
cv_show('img',cur_img)# 遍历轮廓,找到数字部分
locs = [] # 存放每组数字的x,y,w,h
for (i,c) in enumerate(cnts):(x,y,w,h) = cv2.boundingRect(c)ar = w/float(h)if 2.5 < ar < 4.0:if (40 < w < 55) and (10 < h < 20):locs.append((x,y,w,h))
locs = sorted(locs,key=lambda x: x[0])
5、模板匹配
-
将信用卡图像中的每个数字区域与模板中的数字进行匹配,找到最相似的数字。
-
根据匹配结果识别信用卡号码。
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)# 寻找每组数字的轮廓并根据顺序放入digitCntsdigitCnts = cv2.findContours(group.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[1]digitCnts = myutils.sort_contours(digitCnts)[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))cv_show('roi',roi)"""模板匹配,计算得分"""scores = []# 在模板中计算每一个得分for (digit,digitROI) in digits.items():# 模板匹配result = cv2.matchTemplate(roi,digitROI,cv2.TM_CCOEFF)# minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(src, mask=None)score = cv2.minMaxLoc(result)[1]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,255,0),2)output.extend(groupOutput)# 打印结果
print("信用卡类型:{}".format(FIRST_NUMBER[output[0]]))
print("信用卡号码:{}".format("".join(output)))
cv_show("Image",image)
四、总结
这个项目通过图像处理和模板匹配技术,实现了信用卡号码的自动识别。它展示了如何结合 OpenCV 和 Python 实现一个实用的图像处理应用。
相关文章:

《Opencv》信用卡信息识别项目
目录 一、项目介绍 二、数据材料介绍 1、模板图片(1张) 2、需要处理的信用卡图片(5张) 三、实现过程 1、导入需要用到的库 2、设置命令行参数 3、模板图像中数字的定位处理 4、信用卡图像处理 5、模板匹配 四、总结 一…...

Matlab贝叶斯估计MCMC分析药物对不同种群生物生理指标数据评估可视化
全文链接:https://tecdat.cn/?p38756 摘要:本文着重探讨了如何利用Matlab实现贝叶斯估计。阐述了具体的实现流程,涵盖数据加载、先验常数设定、马尔可夫链蒙特卡洛(MCMC)属性指定、模型构建、运行链条以及结果查看等环…...

java 转义 反斜杠 Unexpected internal error near index 1
代码: String str"a\\c"; //出现异常,Unexpected internal error near index 1 //System.out.println(str.replaceAll("\\", "c"));//以下三种都正确 System.out.println(str.replace(\\, c)); System.out.println(str.r…...
网络安全常见的问题
1. 什么是 DDoS 攻击?如何防范? 答:DDoS 攻击是指利用大量的计算机或者其他网络设备,同时向目标网络或者服务器 发送 大量的数据流量,以致其无法正常工作,从而导致网络瘫痪或者服务器宕机的攻击行 为。 …...

在ubuntu22.04中使用bear命令追踪内核编译报错的原因分析和解决方案
1.说明 我在ubuntu22.04中使用bear命令追踪内核编译时发生如下报错: 如图,在链接名为libexec.so的动态库时发生错误 2 分析及解决过程 打印变量 LIB 发现其为空,也就是说 bear会去 /usr/bear/ 去找 libexec.so 去看一下 /usr/bear/是否存…...

【软考网工笔记】操作系统管理与配置——Windows
1-域名解析 Cache 域名解析 Cache 即 DNS 快取,DNS 快取需要应用客户机域名解析服务 DNSClient,其进程名为 svchost.exe -k NetworkService,可以输入命令:net stop dnscache 将其结束。原理是在 Windows 系统中,加入了…...

vue3 css实现文字输出带光标显示,文字输出完毕,光标消失的效果
Vue实现过程如下: <template><div ><p ref"dom_element" class"typing" :class"{over_fill: record_input_over}"></p></div> </template> <script setup> import {onMounted, ref} from…...

什么情况会导致JVM退出?
大家好,我是锋哥。今天分享关于【什么情况会导致JVM退出?】面试题。希望对大家有帮助; 什么情况会导致JVM退出? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 JVM(Java Virtual Machine)在不同情况下可能会退出&am…...
CentOS7修改Docker默认存储路径
当你使用Docker时,Docker的默认配置是将镜像、容器和卷存储在系统/var/lib/docker/目录下,如果docker镜像安装的太多会导致磁盘不够,你可以尝试以下方法来释放空间: 清理无用的镜像和容器:使用docker命令删除不再使用…...
OpenCV相机标定与3D重建(46)将三维空间中的点投影到二维图像平面上函数projectPoints()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 将3D点投影到图像平面上。 cv::projectPoints 是 OpenCV 库中的一个函数,用于将三维空间中的点投影到二维图像平面上。这个过程涉及到…...

基于Elasticsearch8的向量检索实现相似图形搜索
Elasticsearch8版本增加了KNN向量检索,可以基于此功能实现以图搜图功能。 1、首先创建索引,es提供了类型为dense_vector的字段,用于存储向量,其中dims是向量维度,可以不配置,es会根据第一条插入的向量维度…...
springboot+vue使用easyExcel实现导出功能
vue部分 // 导出计算数据exportDataHandle(id) {this.$http({url: this.$http.adornUrl(/xxx/xxx/exportCalDataExcel),method: post,data: this.$http.adornData({id: id}),responseType: blob, // 重要:告诉axios我们希望接收二进制数据}).then(({data}) > {c…...

ffmpeg-avio实战:打开本地文件或者网络直播流dome
使用ffmpeg打开打开本地文件或者网络直播流的一个小dome。流程产靠ffmpeg4.x系列的解码流程-CSDN博客 #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavformat/avio.h> #include <libavutil/file.h> #include &l…...
css预处理器sass
在前端开发的世界中,CSS 是构建网页样式的基础。然而,随着项目规模的增大,纯 CSS 的编写和维护往往会变得复杂而繁琐。为了解决这些痛点,Sass(Syntactically Awesome Style Sheets)应运而生。Sass 是一种 C…...

VulnHub-Acid(1/100)
参考链接: 【VulnHub】Acid靶场复盘-CSDN博客 靶场渗透(二)——Acid渗透_ambassador 靶场渗透-CSDN博客 网络安全从0到0.5之Acid靶机实战渗透测试 | CN-SEC 中文网 Vulnhub靶场渗透练习(四) Acid - 紅人 - 博客园 红日团队…...
MATLAB语言的正则表达式
MATLAB 中的正则表达式使用指南 引言 在数据处理和文本分析中,正则表达式是一种强大而灵活的工具。MATLAB 作为一种广泛应用于科学计算和数据分析的编程语言,提供了对正则表达式的支持,使得用户可以方便地进行字符串匹配与处理。本文将深入…...

通过 route 或 ip route 管理Linux主机路由
目录 一:route 使用说明1、查看路由信息2、删除指定路由3、增加指定路由 二:ip route 使用说明1、查看主机路由2、新增主机路由3、删除主机路由 通过route 或者ip route修改Linux主机路由后属于临时生效,系统重启后就恢复默认值了,…...

MYSQL--------SQL 注入简介MySQL SQL Mode 简介
SQL 注入简介 定义:SQL 注入是一种常见的安全漏洞,攻击者通过在输入中插入恶意的 SQL 语句,利用应用程序中未正确处理的输入数据,来改变 SQL 查询的逻辑,从而执行非预期的操作,如绕过身份验证、获取未授权…...

第6章——HTTP首部
第六章——HTTP首部 HTTP报文结构 都必有报文首部 HTTP请求报文 HTTP响应报文 HTTP首部字段 ###传递重要信息 首部字段结构 首部字段名:字段值(,字段值,字段值) 首部字段类型 通用首部字段 请求首部字…...

多行输入模式(dquote> 提示符)double quote(双引号)
文章目录 1、引号不匹配具体原因解决办法如何避免此问题 2、double quote(双引号)出现原因解决办法预防措施 ~/Downloads/productqualification-develop git:[main] git commit -m "漏添加到暂存区的代码“ dgqdgqdeMac-mini productqualification-…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...

【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...

Android写一个捕获全局异常的工具类
项目开发和实际运行过程中难免会遇到异常发生,系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler,它是Thread的子类(就是package java.lang;里线程的Thread)。本文将利用它将设备信息、报错信息以及错误的发生时间都…...