opencv_银行卡识别

银行卡图片和模板图片

银行卡
在这里插入图片描述
模板
在这里插入图片描述
import cv2
import numpy as np
import myutils
from imutils import contours
def sort_contours(cnts, method=“left-to-right”):
reverse = False
i = 0
if method == “right-to-left” or method == “bottom-to-top”:
reverse = True
if method == “top-to-bottom” or method == “bottom-to-top”:
i = 1
boundingBoxes = [cv2.boundingRect© for c in cnts] #用一个最小的矩形,把找到的形状包起来x,y,h,w
(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),
key=lambda b: b[1][i], reverse=reverse))
return cnts, boundingBoxes

def show_img(str,img):
cv2.imshow(str,img)
cv2.waitKey(0)
cv2.destroyAllWindows()

FIRST_NUMBER = {
“3”:“American Express”,
“4”: “Visa”,
“5”: “MasterCard”,
“6”: “Discover Card”
}
if name == ‘main’:
src = cv2.imread(r’11.png’)
ref = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
ref = cv2.threshold(ref,10,255,cv2.THRESH_BINARY_INV)[1]
#计算轮廓
#cv2.findContours()函数接收黑白图,cv2.RETR_EXTERNAL只检测外轮廓
#cv2.CHAN_APPROX_SIMPLE只保留终点坐标
ref,refConts, _ = cv2.findContours(ref.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(src,refConts,-1,(0,0,255),2)
show_img(“src”,src)
在这里插入图片描述
refConts = sort_contours(refConts,method = “left_to_right”)[0]
digits = {}
for (i,c) in enumerate(refConts):
(x,y,w,h) = cv2.boundingRect©
roi = ref[y:y+h,x:x+w]
roi = cv2.resize(roi,(58,88))
digits[i] = roi
rectkernel = cv2.getStructuringElement(cv2.MORPH_RECT,(9,3))
sqkernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
#银行卡图片的预处理
img = cv2.imread(r"12.png")
width = 300
h,w = img.shape[:2]
r = width / float(w)
dim = (width, int(h * r))
img = cv2.resize(img,dim,interpolation=cv2.INTER_AREA)
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
show_img(“gray”,gray)
在这里插入图片描述
#礼帽操作,增大图片对比度
tophat = cv2.morphologyEx(gray,cv2.MORPH_TOPHAT,rectkernel)
show_img(“tophat”,tophat)
在这里插入图片描述
#算子操作
gradx = cv2.Sobel(tophat,ddepth=cv2.CV_32F,dx=1,dy=0,ksize=-1)
gradx = np.absolute(gradx)
(minval,maxval) = (np.min(gradx),np.max(gradx))
gradx = (255*((gradx-minval)/(maxval-minval)))
gradx = gradx.astype(“uint8”)
show_img(“gradx”,gradx)
在这里插入图片描述
#通过先膨胀,在腐蚀 将数字连在一起
gradx = cv2.morphologyEx(gradx,cv2.MORPH_CLOSE,rectkernel)
#thresh_otsu自动寻找阈值
threshold = cv2.threshold(gradx,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
show_img(“thre”,threshold)
在这里插入图片描述
threshold = cv2.morphologyEx(threshold,cv2.MORPH_CLOSE,sqkernel)
show_img(“close”,threshold)
在这里插入图片描述
#计算外轮廓
, threshCnts, _ = cv2.findContours(threshold.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = threshCnts
cut_img = img.copy()
cv2.drawContours(cut_img, cnts, -1, (0, 0, 255), 3)
show_img(“img”,cut_img)
lose = []
for (i,c) in enumerate(cnts):
(x,y,w,h) = cv2.boundingRect©
ar = w/float(h)
# 选择合适的区域,根据实际任务来,这里的基本都是四个数字一组
if ar > 2.5 and ar < 4.0:
if (w > 40 and w < 55) and (h > 10 and h < 20):
# 符合的留下来
lose.append((x, y, w, h))
# 将符合的轮廓从左到右排序
lose = sorted(lose, key=lambda x: x[0])
output = []
# 遍历每一个轮廓中的数字
for (i, (gX, gY, gW, gH)) in enumerate(lose):
# initialize the list of group digits
groupOutput = []
# 根据坐标提取每一个组
group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]
# 预处理
group = cv2.threshold(group, 0, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# 计算每一组的轮廓
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©
roi = group[y:y + h, x:x + w]
roi = cv2.resize(roi, (57, 88))
# 计算匹配得分
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(img, (gX - 5, gY - 5),
(gX + gW + 5, gY + gH + 5), (0, 0, 255), 1)
cv2.putText(img, “”.join(groupOutput), (gX, gY - 15),
cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)
# 得到结果
output.extend(groupOutput)
# 打印结果
cv2.imshow(“Image”, img)
cv2.waitKey(0)
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值