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处理json数据中的中文
Mar 06 Python
介绍Python的Urllib库的一些高级用法
Apr 30 Python
python文件操作相关知识点总结整理
Feb 22 Python
python处理按钮消息的实例详解
Jul 11 Python
详解用python实现基本的学生管理系统(文件存储版)(python3)
Apr 25 Python
python实现微信定时每天和女友发送消息
Apr 29 Python
关于不懂Chromedriver如何配置环境变量问题解决方法
Jun 12 Python
pandas的连接函数concat()函数的具体使用方法
Jul 09 Python
Python 装饰器原理、定义与用法详解
Dec 07 Python
如何使用selenium和requests组合实现登录页面
Feb 03 Python
Python tkinter布局与按钮间距设置方式
Mar 04 Python
浅析Django接口版本控制
Jun 26 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获取网站域名和地址的代码
2008/08/17 PHP
php 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法
2013/09/28 PHP
WordPress中is_singular()函数简介
2015/02/05 PHP
你应该知道PHP浮点数知识
2015/05/13 PHP
浅谈php中的访问修饰符private、protected、public的作用范围
2016/11/20 PHP
php异常处理捕获错误整理
2019/09/23 PHP
PHP 代码简洁之道(小结)
2019/10/16 PHP
对采用动态原型方式无法展示继承机制得思考
2009/12/04 Javascript
JS对象与JSON格式数据相互转换
2012/02/20 Javascript
基于JQuery的模拟苹果桌面Dock效果(稳定版)
2012/10/15 Javascript
JS弹出可拖拽可关闭的div层完整实例
2015/02/13 Javascript
解决jquery实现的radio重新选中的问题
2015/07/03 Javascript
jQuery Validate插件自定义验证规则的方法
2016/12/27 Javascript
vue使用vuex实现首页导航切换不同路由的方法
2019/05/08 Javascript
微信小程序导入Vant报错VM292:1 thirdScriptError的解决方法
2019/08/01 Javascript
Python中使用Beautiful Soup库的超详细教程
2015/04/30 Python
利用Python如何生成hash值示例详解
2017/12/20 Python
python求解数组中两个字符串的最小距离
2018/09/27 Python
实例详解Matlab 与 Python 的区别
2019/04/26 Python
python 对字典按照value进行排序的方法
2019/05/09 Python
python3使用腾讯企业邮箱发送邮件的实例
2019/06/28 Python
python树的同构学习笔记
2019/09/14 Python
详解Python绘图Turtle库
2019/10/12 Python
Python:type、object、class与内置类型实例
2019/12/25 Python
用gpu训练好的神经网络,用tensorflow-cpu跑出错的原因及解决方案
2021/03/03 Python
GNC健安喜官方海外旗舰店:美国著名保健品牌
2017/01/04 全球购物
Shopee新加坡:东南亚与台湾电商平台
2019/01/25 全球购物
本科生个人求职自荐信
2013/09/26 职场文书
新护士岗前培训制度
2014/02/02 职场文书
学雷锋志愿服务月活动总结
2014/03/09 职场文书
积极贯彻学习两会精神总结
2014/03/17 职场文书
红领巾广播站广播稿(3篇)
2014/09/20 职场文书
2015年世界急救日宣传活动方案
2015/05/06 职场文书
运动会宣传稿100字
2015/07/23 职场文书
Nginx 路由转发和反向代理location配置实现
2021/11/11 Servers
Pandas-DataFrame知识点汇总
2022/03/16 Python