Python如何识别银行卡卡号?


Posted in Python onJune 10, 2021

一、现有资源梳理

目前有一张卡号模板图片

Python如何识别银行卡卡号?

N张测试银行卡图片,其一如下

Python如何识别银行卡卡号?

操作环境 win10-64位
代码语言 Python 3.6

二、实现方案规划

对模板操作,将十个模板和对应的数字一一对应起来

图片中通过查找轮廓,然后绘制轮廓外界矩形的方式,将每一和数字分割出来,并和对应的数字相对应。以字典的形式保存
每一个模板都是这样的形式存储。

array([[ 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255],
	 [ 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255], 
	 [ 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255], 
	 [255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255], 
	 [255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255], 
	 [255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255], 
	 [255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255], 
	 [255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255], 
	 [255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255], 
	 [255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255], 
	 [255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255], 
	 [255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255], 
	 [255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0], 
	 [255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0], 
	 [255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0], 
	 [255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0], 
	 [255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0], 
	 [255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0], 
	 [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
	 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
	 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
	 [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255]], dtype=uint8)

对测试图片操作,取得我们需要的,每个数字的像素 .

整个照片的干扰信息很多,很难直接就定位到卡号位置,需要经过一系列的变换。
定位到卡号位置后,如何将每个卡号给提取出来,进行模板匹配,识别其数字。

1.输入的图片为RGB格式,需要转换成GRAY格式,然后再将灰度形式的图片进行二值化处理。

2.对于二值化处理之后的图片进行Sobel滤波,将数字模糊,连接起来。

3.经过Sobel之后可能数字没有连接在一起,所以执行闭操作将相邻的数字连接起来,因为数字是横向的,所以闭操作的核设置为[1,1,1,1,1,1,1,1,1]

4.通过查找轮廓和轮廓外接矩形的方式定位到连续数字区域。

5.通过连续数字区域分割出每一个数字,然后将每个数字和模板进行匹配,匹配结果最高的就是最有可能的数字。

三、代码实现

工具包导入

from imutils import contours
import numpy as np
import argparse
import cv2
import myutils

路径和绘图函数及信用卡类型设定

# 模板图片
template = 'images/ocr_a_reference.png'
# 测试图片
image = 'images/credit_card_03.png'
# 指定信用卡类型
FIRST_NUMBER = {
	"3": "American Express",
	"4": "Visa",
	"5": "MasterCard",
	"6": "Discover Card"
}
# 绘图展示
def cv_show(name,img):
	cv2.imshow(name, img)
	cv2.waitKey(0)
	cv2.destroyAllWindows()

模板处理

img = cv2.imread(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)

# 计算轮廓
#cv2.findContours()函数接受的参数为二值图,即黑白的(不是灰度图),cv2.RETR_EXTERNAL只检测外轮廓,cv2.CHAIN_APPROX_SIMPLE只保留终点坐标
#返回的list中每个元素都是图像中的一个轮廓

ref_, refCnts, hierarchy = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

cv2.drawContours(img, refCnts, -1, (0, 0, 255), 3)
cv_show('img', img)
print(np.array(refCnts).shape)
refCnts = myutils.sort_contours(refCnts, method="left-to-right")[0] #排序,从左到右,从上到下
digits = {}

# 遍历每一个轮廓
for (i, c) in enumerate(refCnts):
	# 计算外接矩形并且resize成合适大小
	(x, y, w, h) = cv2.boundingRect(c)
	roi = ref[y:y + h, x:x + w]
	roi = cv2.resize(roi, (57, 88))

	# 每一个数字对应每一个模板
	digits[i] = roi
# print(digits)

测试图片处理

# 初始化卷积核
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

#读取输入图像,预处理
image = cv2.imread(image)
cv_show('image',image)
image = myutils.resize(image, width=300)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv_show('gray',gray)

#礼帽操作,突出更明亮的区域
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel) 
cv_show('tophat',tophat) 
# 
gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, #ksize=-1相当于用3*3的
	ksize=-1)


gradX = np.absolute(gradX)
(minVal, maxVal) = (np.min(gradX), np.max(gradX))
gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))
gradX = gradX.astype("uint8")

print (np.array(gradX).shape)
cv_show('gradX',gradX)

#通过闭操作(先膨胀,再腐蚀)将数字连在一起
gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel) 
cv_show('gradX',gradX)
#THRESH_OTSU会自动寻找合适的阈值,适合双峰,需把阈值参数设置为0
thresh = cv2.threshold(gradX, 0, 255,
	cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1] 
cv_show('thresh',thresh)

#再来一个闭操作

thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel) #再来一个闭操作
cv_show('thresh',thresh)

# 计算轮廓

thresh_, threshCnts, hierarchy = 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])
output = []

# 遍历每一个轮廓中的数字
for (i, (gX, gY, gW, gH)) in enumerate(locs):
	# initialize the list of group digits
	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 = contours.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(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)
# (194, 300)
# Credit Card Type: MasterCard
# Credit Card #: 5412751234567890

所有代码连在一起就是完整的代码

到此这篇关于Python如何识别银行卡卡号?的文章就介绍到这了,更多相关Python识别卡号内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python使用scrapy解析js示例
Jan 23 Python
python fabric使用笔记
May 09 Python
一个月入门Python爬虫学习,轻松爬取大规模数据
Jan 03 Python
python使用pipeline批量读写redis的方法
Feb 18 Python
python变量命名的7条建议
Jul 04 Python
解决Django一个表单对应多个按钮的问题
Jul 18 Python
Python logging设置和logger解析
Aug 28 Python
Python递归及尾递归优化操作实例分析
Feb 01 Python
python缩进长度是否统一
Aug 02 Python
详解Pytorch显存动态分配规律探索
Nov 17 Python
python绕过图片滑动验证码实现爬取PTA所有题目功能 附源码
Jan 06 Python
python 进阶学习之python装饰器小结
Sep 04 Python
使用python+pygame开发消消乐游戏附完整源码
Python数据可视化之基于pyecharts实现的地理图表的绘制
python使用PySimpleGUI设置进度条及控件使用
python3+PyQt5+Qt Designer实现界面可视化
Django使用echarts进行可视化展示的实践
教你如何使用Python Tkinter库制作记事本
Jun 10 #Python
Python中常见的反爬机制及其破解方法总结
Jun 10 #Python
You might like
php模拟socket一次连接,多次发送数据的实现代码
2011/07/26 PHP
php中定时计划任务的实现原理
2013/01/08 PHP
用php来改写404错误页让你的页面更友好
2013/01/24 PHP
遭遇php的in_array低性能问题
2013/09/17 PHP
php中引用&amp;的用法分析【变量引用,函数引用,对象引用】
2016/12/12 PHP
用Jquery实现多级下拉框无刷新的联动
2010/12/22 Javascript
javascript一元操作符(递增、递减)使用示例
2013/08/07 Javascript
jQuery选择器中含有空格的使用示例及注意事项
2013/08/25 Javascript
js实现收缩菜单效果实例代码
2013/10/30 Javascript
javascript基础练习之翻转字符串与回文
2017/02/20 Javascript
angularjs利用directive实现移动端自定义软键盘的示例
2017/09/20 Javascript
JS简单获得节点元素的方法示例
2018/02/10 Javascript
react-native-video实现视频全屏播放的方法
2018/03/19 Javascript
Python中的集合介绍
2019/01/28 Python
Python中format()格式输出全解
2019/04/12 Python
如何不用安装python就能在.NET里调用Python库
2019/07/12 Python
django 使用 PIL 压缩图片的例子
2019/08/16 Python
Pandas实现dataframe和np.array的相互转换
2019/11/30 Python
浅谈python print(xx, flush = True) 全网最清晰的解释
2020/02/21 Python
django创建css文件夹的具体方法
2020/07/31 Python
基于 HTML5 WebGL 实现的垃圾分类系统
2019/10/08 HTML / CSS
Amara德国:家居饰品、设计师品牌和豪华礼品
2019/05/20 全球购物
Notino罗马尼亚网站:购买香水和化妆品
2019/07/20 全球购物
澳大利亚在线性感内衣商店:Fantasy Lingerie
2021/02/07 全球购物
总裁岗位职责
2013/12/04 职场文书
内衣营销方案
2014/03/15 职场文书
党员干部三严三实心得体会
2014/10/13 职场文书
党的群众路线批评与自我批评范文
2014/10/16 职场文书
委托公证书样本
2015/01/23 职场文书
雷峰塔导游词
2015/02/09 职场文书
小学校园广播稿
2015/08/18 职场文书
小组口号霸气押韵
2015/12/24 职场文书
解决Go gorm踩过的坑
2021/04/30 Golang
52条SQL语句教你性能优化
2021/05/25 MySQL
Python机器学习之基于Pytorch实现猫狗分类
2021/06/08 Python
关于maven依赖 ${xxx.version}报错问题
2022/01/18 Java/Android