银行卡号定位(python3)

银行卡号定位

本来写这个是想在代做群里挣点儿小外快的,结果人家撤销了任务。。。哭晕在厕所QAQ。
这次软件杯基于深度学习的银行卡号识别系统有个功能性模块儿是银行卡号定位,我觉得这个比赛还是蛮难的,因为当我看见他们的测试银行卡后整个人都不好了!
大赛给的测试银行卡
这是一群大学生该干的事儿嘛!!!这花里胡哨的纹路和颜色真的令人脱发哎!!!
不过为了小钱钱还是得试一试,颜色识别是肯定不行了,这数字都进化出保护色了。所以就来了一下canny边缘检测加膨胀腐蚀看能不能把那串数字搞出来。

import cv2
import numpy
# 读取图片并改变尺寸为(800x400),转灰度图
img0 = cv2.imread("1.jpg")
img0 = cv2.resize(img0, (800,400), interpolation=cv2.INTER_AREA)
img = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)
cv2.namedWindow("org")
# 给定形态学操作内核,对图像进行Canny检测和形态学操作
kernel = np.ones((3, 3), np.uint8)
newimg = cv2.Canny(img, 170, 100)
newimg = cv2.morphologyEx(newimg, cv2.MORPH_CLOSE, kernel)

cv2.imshow("org", newimg)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述
然后就成了这个鬼样子。。。也不知道有没有什么好的方法把那些纹路去掉,反正我是去不掉了,不过还好,我的任务只是卡号定位。替需要提取所有数字识别的参赛的兄弟们捏一把汗2333
不难发现银行卡号有个规律,它是很长的一串数字并且字形和对其非常严格,遂心生一计,将图片resize为固定大小(800x400),再将符合卡号字形大小的单位用最小矩形框选出来

# 提取图像内单元的最小矩形
image_contours, contours, hier = cv2.findContours(newimg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for i in range(len(contours)):
	cnt = contours[i]
	x, y, w, h = cv2.boundingRect(cnt)
	''' 选择符合字体大小的最小矩形塞进point列表里 '''
	if 50>w>10 and 50>h>10:
		point.append(add_cont(x,y,w,h))
for o in range(len(point)):
	for i in range(len(point)):
		'''出现了!核心思想2333,把起点y坐标绝对距离小于5像素的矩形框个数找出来'''
		'''(相当于找出同一排单元 PS:卡号在一行)'''
		if 0 < abs(point[o][1] - point[i][1]) < 5:
			tent += 1
		elif abs(point[o][1] - point[i][1]) == 0:
			if point[o][0] != point[i][0]:
				tent += 1
		'''如果同一行单元个数大于6则认定为卡号'''
		'''至于为啥,你看,银行卡上第二长的一排字是银行名称,其中最长中国邮政银行6个字'''
		if tent > 6:
			tent = 0
			target.append(point[o])

找到目标所在的大致范围后,我们就可以把其余的糟糕的线条和元素统统去掉

newimg[0:target[0][1]-3,0:800] = 0
newimg[target[0][1]+target[0][3]+3:400, 0:800] = 0

于是我们得到了卡号在的那一排
在这里插入图片描述
瞬间神清气爽有没有啊!虽然他还是遗传甲骨文,但是我的目标又不是识别2333。
接下来再对得到的newimg来一波最小矩形框选,这次的最小矩形就需要选小一点的规格了,力求将newimg里的所有卡号单元全部选中,因为此时的噪点只是银行卡那纤细的边缘,其余的元素都是我们要的

# 你得先把前面存最小矩形框里的元素清空
point = []
target = []
image_contours, contours, hier = cv2.findContours(newimg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 把newimg上的卡号元素框出来,能不能框全都无所谓啦,第一个和最后一个能框出来就行
for i in range(len(contours)):
	cnt = contours[i]
	x, y, w, h = cv2.boundingRect(cnt)
	if 50>w>3 and 50>h>3:
		point.append(add_cont(x,y,w,h))

接下来用起泡法(什么排序法都可以)把刚刚框选的最小框里最小的x,y坐标,最大的x坐标,宽高w,h选出来,得到最终卡号串矩形框的起始startx,finaly坐标和finalw,finalh宽高。
这时候,在原图上绘出最终矩形框,卡号就被定位啦!接下来截取出来你想怎么处理就怎么处理咯
效果图:
在这里插入图片描述

源码奉上!

import cv2
import numpy as np
from scipy import ndimage
# 添加矩形框元素
def add_cont(x, y, w ,h):
	p = []
	p.append(x)
	p.append(y)
	p.append(w)
	p.append(h)
	return p
# 起泡法排序返回最大or最小值
def bubble_sort(a, w, s):
	'''w: 要取的x,y,w,h元素,对应0,1,2,3'''
	'''s: 0取最小值, 1取最大值'''
	b = []
	temp = 0
	for i in range(len(a)):
		b.append(a[i][w])
	b.sort()
	if s:
		return b[len(b)-1]
	else:
		return b[0]

tent = 0
startx = 0
finalx = 0
finaly = 0
finalw = 0
finalh = 0
point = []
target = []
img0 = cv2.imread("1.jpg")
img0 = cv2.resize(img0, (800,400), interpolation=cv2.INTER_AREA)
img = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)
cv2.namedWindow("org")
kernel = np.ones((3, 3), np.uint8)
newimg = cv2.Canny(img, 170, 100)
newimg = cv2.morphologyEx(newimg, cv2.MORPH_CLOSE, kernel)
image_contours, contours, hier = cv2.findContours(newimg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for i in range(len(contours)):
	cnt = contours[i]
	x, y, w, h = cv2.boundingRect(cnt)
	if 50>w>10 and 50>h>10:
		point.append(add_cont(x,y,w,h))
for o in range(len(point)):
	for i in range(len(point)):
		if 0 < abs(point[o][1] - point[i][1]) < 5:
			tent += 1
		elif abs(point[o][1] - point[i][1]) == 0:
			if point[o][0] != point[i][0]:
				tent += 1
		if tent > 6:
			tent = 0
			target.append(point[o])
newimg[0:target[0][1]-3,0:800] = 0
newimg[target[0][1]+target[0][3]+3:400, 0:800] = 0
point = []
target = []
image_contours, contours, hier = cv2.findContours(newimg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for i in range(len(contours)):
	cnt = contours[i]
	x, y, w, h = cv2.boundingRect(cnt)
	if 50>w>3 and 50>h>3:
		point.append(add_cont(x,y,w,h))
finalx = bubble_sort(point, 0, 1)
startx = bubble_sort(point, 0, 0) - 3
finaly = bubble_sort(point, 1, 0) - 3
finalw = finalx + bubble_sort(point, 2, 1)
finalh = finaly + bubble_sort(point, 3, 1) + 10
print("startx = "+ str(startx))
print("starty = "+ str(finaly))
print("width = "+ str(finalw))
print("height = "+ str(finalh))
# 画出矩形框
cv2.rectangle(img0,(startx,finaly),(finalw, finalh),(0, 255, 0),2)
cv2.imshow("org", img0)
cv2.waitKey()
cv2.destroyAllWindows()

祝诸君比赛顺利哦

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值