python-opencv信用卡号码识别

python-opencv信用卡号码识别

1、效果

在这里插入图片描述

2、代码
import cv2
import numpy as np
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(c) 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



img_mode = cv2.imread("./4.png")
img_new = cv2.imread("./5.png")
img_new = cv2.resize(img_new,(500,200))
img_mode = cv2.resize(img_mode,(500,200))
img_gray_new = cv2.cvtColor(img_new,cv2.COLOR_BGR2GRAY)  #灰色
img_gray_mode = cv2.cvtColor(img_mode,cv2.COLOR_BGR2GRAY)
ret, thresh1 = cv2.threshold(img_gray_new,127,255,cv2.THRESH_BINARY) #二值化
ret2, thresh2 = cv2.threshold(img_gray_mode,127,255,cv2.THRESH_BINARY_INV)
contours, hie = cv2.findContours(thresh1.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) #检测到边界
contours_, hie_ = cv2.findContours(thresh2.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img_mode, contours_,-1,(0,0,255),2)  #画出边界
# cv2.imshow("img",img_mode)
contours_ = sort_contours(contours_,method="left-to-right")[0]
digit = []
for i in contours_:
   x,y,z,w, = cv2.boundingRect(i)
   # print(x,y,z,w)
   roi =thresh2[y:y+w, x:x+z]
   roi = cv2.resize(roi,(90,50))
   # cv2.imshow("wewew",roi)
   digit.append(roi) #将每个模板添加进去
#print(digit) #找到模板每个数字的x
rect = cv2.getStructuringElement(cv2.MORPH_RECT,(2,3))  #设置内核大小
sq = cv2.getStructuringElement(cv2.MORPH_RECT,(21,10))
top = cv2.morphologyEx(img_gray_new, cv2.MORPH_TOPHAT,rect)#顶帽操作,将大的东西去除掉
# cv2.imshow("img_top", top)
close = cv2.morphologyEx(top, cv2.MORPH_CLOSE,sq)
# cv2.imshow("img_close",close)
ret, thresh_close = cv2.threshold(close,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU) #二值化
# cv2.imshow("thresh_close", thresh_close)
cnts ,hirs = cv2.findContours(thresh_close.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
img_new_copy = img_new.copy()
cv2.drawContours(img_new_copy,cnts,-1,(0,0,225),3)
locs = []
for i in cnts:
   x,y,w,z = cv2.boundingRect(i)
   ar = w/float(z)
   if (ar<5.26 and ar >5.06):
       if(w > 80 and w < 85) and (z==16):
           locs.append((x,y,z,w))
# print(locs)
group = []
output = []
# locs = sorted(locs, key=lambda x:x[0])
locs = sorted(locs, key=lambda  x:x[0])  #四个边框的坐标
l = []
for (x,y,w,z) in locs: #将四个4个数字组合的方框中的数值提取处理
   groupOutput = []
   # print(x,y,w,z)
   g = img_gray_new[y:y+w,x:x+z+5]      # 将四个方框分割 第一个、第二个、第三个、第四个
   # cv2.imshow("img_mode",img_gray_mode)
   # cv2.imshow("g",g)
   group = cv2.threshold(g, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]      #将获取的四个数值的方框二值化
   # cv2.imshow('g_', group)
   digit_cnts ,hire = cv2.findContours(group.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)  # 找到每个方框中4个数字的边界
   k = []
   for i in digit_cnts:
       (q,w,e,r) = cv2.boundingRect(i) #找到方框
       # print(q,w,e,r)
       k.append((q,w,e,r))
   k = sorted(k, key=lambda q: q[0])
   for (q,w,e,r) in k:
       # print(q,w,e,r)
       roi = group[w:w + e, q:q + r]  # 找到每个数值边框的长宽高,前面是y后面是x
       roi = cv2.resize(roi, (90, 50))
       # cv2.imshow("rio",roi)
       scores = []
       for  digit_roi in digit:
           # cv2.imshow("ssss",digit_roi)
           result = cv2.matchTemplate(roi, digit_roi, cv2.TM_CCOEFF_NORMED) #最好匹配越大,越小越差
           (_, score, _, _) = cv2.minMaxLoc(result)
           scores.append(score)
       groupOutput.append(str(scores.index(max(scores))))
   l.append(groupOutput)


c = []
for i in l:
   for j in range(4):
       c.append(i[j])


c = "".join(c)
print("银行卡号码是:",c)
#
# imggray = np.vstack((img_gray_mode,img_gray_new))
# imgver = np.vstack((img_mode,img_new))
# imgthresh = np.vstack((thresh1,thresh2))
# print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
cv2.imshow("ssss",img_new)

# cv2.imshow("img",imgver)
# cv2.imshow("img_",imggray)
# cv2.imshow("img__",imgthresh)

cv2.waitKey(0)
2.1、图片

在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值