ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

用模板匹配进行的银行卡数字识别

2019-09-24 15:00:08  阅读:300  来源: 互联网

标签:匹配 img 银行卡 image imshow cv2 gradx 模板 contours


实现功能:在银行卡上识别出卡号数字部分,并在其上方写下数字,如下图所示。

模板图片如下图,

原始银行卡图片,

完整代码如下,在Pycharm中编写。

imutils库需要提前下载,在cmd中用命令 pip install imutils 下载。
 1 import cv2
 2 import numpy as np
 3 import matplotlib.pyplot as plt
 4 import imutils
 5 from imutils import contours
 6 
 7 # 处理模板图片
 8 img = cv2.imread("C:\\Users\\lenovo\\Pictures\\moban.jpg")
 9 #cv2.imshow("img_moban",img)
10 img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
11 #cv2.imshow("img_moban_gray ",img_gray)
12 ret,ref = cv2.threshold(img_gray,20,255,cv2.THRESH_BINARY_INV)
13 #cv2.imshow("binary", ref)
14 image,refCnts, hierarchy = cv2.findContours(ref.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
15 contour = cv2.drawContours(img,refCnts,-1,(0,0,255),3)
16 cv2.namedWindow("img_moban_contours",cv2.WINDOW_NORMAL)
17 #cv2.imshow("img_moban_contours",contour)
18 
19 #refCnts = refCnts[0] if imutils.is_cv2() else refCnts[1]
20 refCnts = contours.sort_contours(refCnts,method = "left-to-right")[0] #from imutils import contours
21 digits = {}
22 for (i,c) in enumerate(refCnts):     # enumerate(refCnts)下标从0开始,返回值是0,第一个轮廓。1,第二个轮廓
23     (x,y,w,h) = cv2.boundingRect(c)  # x,y是矩阵左上点的坐标,w,h是矩阵的宽和高
24     roi = ref[y:y+h,x:x+w]
25     roi = cv2.resize(roi,(57,88))
26     digits[i] = roi
27 
28 
29 # 处理待检测图片
30 recKernel = cv2.getStructuringElement(cv2.MORPH_RECT,(10,3))
31 sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT,(2,2))
32 
33 image = cv2.imread("C:\\Users\\lenovo\\Pictures\\yinhangka.png")
34 image = cv2.resize(image,(250,200))
35 
36 gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
37 cv2.imshow("imagesize",gray)
38 tophat = cv2.morphologyEx(gray,cv2.MORPH_TOPHAT,recKernel) # 顶帽操作:突出明亮区域
39 cv2.imshow("imagetophat",tophat)
40 gradx = cv2.Sobel(tophat,ddepth=cv2.CV_32F,dx=1,dy=0,ksize=3)
41 gradx= np.absolute(gradx)
42 (minVal,maxVal) = (np.min(gradx),np.max(gradx))
43 gradx = (255*((gradx-minVal)/(maxVal-minVal)))
44 gradx = gradx.astype("uint8")
45 
46 gradx = cv2.morphologyEx(gradx,cv2.MORPH_CLOSE,recKernel)
47 cv2.imshow("imagegradx",gradx)
48 ret,thresh = cv2.threshold(gradx,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)
49 thresh = cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,sqKernel)
50 imageprint,Cnts,hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
51 cnts = Cnts # cnts是所有轮廓
52 curImage = image.copy()
53 contours = cv2.drawContours(curImage,cnts,-1,(0,0,255),3)
54 cv2.imshow("contours",contours)
55 locs = []    # 储存符合条件的数字模块
56 locsnum = []
57 for (i,c) in enumerate(cnts):
58     (x,y,w,h) = cv2.boundingRect(c)
59     ar = w/float(h)
60     if (ar>2.5) and (ar<4):
61         if h>10:   # 这里的条件要多试几次
62             locs.append((x,y,w,h))
63 locs = sorted(locs,key=lambda x:x[0]) #排序方式按照中括号[]里面的维度进行排序,[0]按照第一维排序,[2]按照第三维排序
64 print(len(locs))
65 output=[]
66 for (i,(gx,gy,gw,gh)) in enumerate(locs):
67     groupOutput = []
68     group = gray[gy-5:gy+gh+5,gx-5:gx+gw+5] # 在灰度图中选取roi
69     group = cv2.threshold(group,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1]
70    # cv2.imshow("group", group)
71     imageing,digitCnts,hierarchy = cv2.findContours(group.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
72     # digitCnts = contours.sort_contours(digitCnts,method = "left-to-right")[0]
73     for c in digitCnts:
74         (x,y,w,h) = cv2.boundingRect(c)
75         roi = group[y:y+h,x:x+w]
76         roi = cv2.resize(roi,(57,88))
77         scores=[]
78         for (digit, digitROI) in digits.items():  # 在模板预处理中建立了数值的字典类型,一个为索引、一个为值
79             result = cv2.matchTemplate(roi, digitROI, cv2.TM_CCOEFF)  # 匹配,返回与之匹配度最高的数值
80             (min_val, score, min_index, max_index) = cv2.minMaxLoc(result)  # 做10次匹配,取最大值(注意:取最大值还是最小值跟选取的模板匹配方法有关)
81             scores.append(score)
82         groupOutput.append(str(np.argmax(scores))) #argmax返回的是最大数的索引
83     cv2.rectangle(image, (gx - 5, gy - 5), (gx + gw + 5, gy + gh + 5), (0, 0, 255), 1) # 第一组的矩形框
84     groupOutput.reverse()
85     image = cv2.putText(image, str("".join(groupOutput)), (gx, gy - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)
86     output.extend(groupOutput)
87 # print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
88 print("Credit Card #: {}".format("".join(output))) # 将output中的字符用双引号中间的符号连接起来
89 cv2.imshow("Image", image)
90 cv2.waitKey(0)
91 cv2.destroyAllWindows()
92 # . join():    连接字符串数组。将字符串、元组、列表中的元素以指定的字符(分隔符)连接生成一个新的字符串
完整代码

 

标签:匹配,img,银行卡,image,imshow,cv2,gradx,模板,contours
来源: https://www.cnblogs.com/yangyue-kai/p/11578293.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有