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

《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、模板图片&#xff08;1张&#xff09; 2、需要处理的信用卡图片&#xff08;5张&#xff09; 三、实现过程 1、导入需要用到的库 2、设置命令行参数 3、模板图像中数字的定位处理 4、信用卡图像处理 5、模板匹配 四、总结 一…...

Matlab贝叶斯估计MCMC分析药物对不同种群生物生理指标数据评估可视化

全文链接&#xff1a;https://tecdat.cn/?p38756 摘要&#xff1a;本文着重探讨了如何利用Matlab实现贝叶斯估计。阐述了具体的实现流程&#xff0c;涵盖数据加载、先验常数设定、马尔可夫链蒙特卡洛&#xff08;MCMC&#xff09;属性指定、模型构建、运行链条以及结果查看等环…...

java 转义 反斜杠 Unexpected internal error near index 1

代码&#xff1a; String str"a\\c"; //出现异常&#xff0c;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 攻击&#xff1f;如何防范&#xff1f; 答&#xff1a;DDoS 攻击是指利用大量的计算机或者其他网络设备&#xff0c;同时向目标网络或者服务器 发送 大量的数据流量&#xff0c;以致其无法正常工作&#xff0c;从而导致网络瘫痪或者服务器宕机的攻击行 为。 …...

在ubuntu22.04中使用bear命令追踪内核编译报错的原因分析和解决方案

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

【软考网工笔记】操作系统管理与配置——Windows

1-域名解析 Cache 域名解析 Cache 即 DNS 快取&#xff0c;DNS 快取需要应用客户机域名解析服务 DNSClient&#xff0c;其进程名为 svchost.exe -k NetworkService&#xff0c;可以输入命令&#xff1a;net stop dnscache 将其结束。原理是在 Windows 系统中&#xff0c;加入了…...

vue3 css实现文字输出带光标显示,文字输出完毕,光标消失的效果

Vue实现过程如下&#xff1a; <template><div ><p ref"dom_element" class"typing" :class"{over_fill: record_input_over}"></p></div> </template> <script setup> import {onMounted, ref} from…...

什么情况会导致JVM退出?

大家好&#xff0c;我是锋哥。今天分享关于【什么情况会导致JVM退出?】面试题。希望对大家有帮助&#xff1b; 什么情况会导致JVM退出? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 JVM&#xff08;Java Virtual Machine&#xff09;在不同情况下可能会退出&am…...

CentOS7修改Docker默认存储路径

当你使用Docker时&#xff0c;Docker的默认配置是将镜像、容器和卷存储在系统/var/lib/docker/目录下&#xff0c;如果docker镜像安装的太多会导致磁盘不够&#xff0c;你可以尝试以下方法来释放空间&#xff1a; 清理无用的镜像和容器&#xff1a;使用docker命令删除不再使用…...

OpenCV相机标定与3D重建(46)将三维空间中的点投影到二维图像平面上函数projectPoints()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 将3D点投影到图像平面上。 cv::projectPoints 是 OpenCV 库中的一个函数&#xff0c;用于将三维空间中的点投影到二维图像平面上。这个过程涉及到…...

基于Elasticsearch8的向量检索实现相似图形搜索

Elasticsearch8版本增加了KNN向量检索&#xff0c;可以基于此功能实现以图搜图功能。 1、首先创建索引&#xff0c;es提供了类型为dense_vector的字段&#xff0c;用于存储向量&#xff0c;其中dims是向量维度&#xff0c;可以不配置&#xff0c;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, // 重要&#xff1a;告诉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

在前端开发的世界中&#xff0c;CSS 是构建网页样式的基础。然而&#xff0c;随着项目规模的增大&#xff0c;纯 CSS 的编写和维护往往会变得复杂而繁琐。为了解决这些痛点&#xff0c;Sass&#xff08;Syntactically Awesome Style Sheets&#xff09;应运而生。Sass 是一种 C…...

VulnHub-Acid(1/100)

参考链接&#xff1a; ​​​​​​​【VulnHub】Acid靶场复盘-CSDN博客 靶场渗透&#xff08;二&#xff09;——Acid渗透_ambassador 靶场渗透-CSDN博客 网络安全从0到0.5之Acid靶机实战渗透测试 | CN-SEC 中文网 Vulnhub靶场渗透练习(四) Acid - 紅人 - 博客园 红日团队…...

MATLAB语言的正则表达式

MATLAB 中的正则表达式使用指南 引言 在数据处理和文本分析中&#xff0c;正则表达式是一种强大而灵活的工具。MATLAB 作为一种广泛应用于科学计算和数据分析的编程语言&#xff0c;提供了对正则表达式的支持&#xff0c;使得用户可以方便地进行字符串匹配与处理。本文将深入…...

通过 route 或 ip route 管理Linux主机路由

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

MYSQL--------SQL 注入简介MySQL SQL Mode 简介

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

第6章——HTTP首部

第六章——HTTP首部 HTTP报文结构 ​ 都必有报文首部 HTTP请求报文 HTTP响应报文 HTTP首部字段 ###传递重要信息 首部字段结构 ​ 首部字段名&#xff1a;字段值&#xff08;&#xff0c;字段值&#xff0c;字段值&#xff09; 首部字段类型 ​ 通用首部字段 请求首部字…...

多行输入模式(dquote> 提示符)double quote(双引号)

文章目录 1、引号不匹配具体原因解决办法如何避免此问题 2、double quote&#xff08;双引号&#xff09;出现原因解决办法预防措施 ~/Downloads/productqualification-develop git:[main] git commit -m "漏添加到暂存区的代码“ dgqdgqdeMac-mini productqualification-…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链&#xff08;Filter Chain&#xff09;&#xff0c;核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤&#xff1a; 用户提交登录请求拦…...