银行卡卡号识别

 关于思路:

识别流程:
1.银行卡需要提取出卡号数字
2.需要与模板字体进行匹配

关于模板:
    转换成灰度图——二值转换——轮廓检测——外接矩形——将每一个数字进行切割——切割完后
与0-9数字进行匹配
图中用到的模板图片和银行卡图片皆可在网上找到。

所用的示例银行卡:

 所用模板图片:

 

import numpy as np
import cv2


def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

img=cv2.imread('2020.png')
ref=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ref=cv2.threshold(ref,10,255,cv2.THRESH_BINARY_INV)[1]
# cv_show('ref',ref)

countour=cv2.findContours(ref,cv2.RETR_EXTERNAL,
                              cv2.CHAIN_APPROX_SIMPLE)[0]
n=len(countour)
Rectbox=np.ones((n,4),dtype=int)
# print(Rectbox)

for i in range(n):
    Rectbox[i]=cv2.boundingRect(countour[i])
    # print(rect)
imgBox=sorted(Rectbox,key=lambda x:x[0])
# print(imgBox)
roi2=[]
for i in range(n):
    x,y,w,h=imgBox[i]
    ROI=ref[y:y+h,x:x+w]
    # print(ROI)
    ROI=cv2.resize(ROI,(53,83))

    roi2.append(ROI)
    thresh_val,ROI=cv2.threshold(ROI,200,255,cv2.THRESH_BINARY)
    imgBox[i]=ROI
    # cv_show('ROI',ROI)
#至此实现数字与模板字体一一对应,后续可进行银行卡字体与模板字体的比较
# 关于模板数字识别完成

rectkernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(20,3))
sqkernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))

card=cv2.imread('08.png')
ROI=cv2.resize(card,(500,300))
gray_card=cv2.cvtColor(ROI,cv2.COLOR_BGR2GRAY)
tophat=cv2.morphologyEx(gray_card,cv2.MORPH_TOPHAT,rectkernel)
# cv_show('tophat',tophat)
#
gradx=cv2.Sobel(tophat,ddepth=cv2.CV_64F,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')

gradx=cv2.morphologyEx(gradx,cv2.MORPH_CLOSE,rectkernel)
# cv_show('gradx',gradx)

thresh=cv2.threshold(gradx,0,255,
                     cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# cv_show('thresh',thresh)

counters=cv2.findContours(thresh,cv2.RETR_EXTERNAL,
                          cv2.CHAIN_APPROX_SIMPLE)[0]
cur_img=card.copy()
cv2.drawContours(ROI,counters,-1,(0,0,255),3)
# cv_show('ROI',ROI)

locs=[]

for (i,c) in enumerate(counters):
    (x,y,w,h)=cv2.boundingRect(c)
    ar=w/float(h)

    if ar>2.5 and ar<5:
        if h>20 and h<30:
            locs.append((x,y,w,h))
# print(locs)
cnm=cv2.findContours(gray_card,cv2.RETR_EXTERNAL,
                          cv2.CHAIN_APPROX_SIMPLE)[0]
locs.sort(key=lambda x:x[0])
Rectbox1=[]
ri=[]
numbox0=[]
for (i,(gx,gy,gw,gh)) in enumerate(locs):
    groudOutput=[]
    group=gray_card[gy-5:gy+gh+5,gx-10:gx+gw]
    # cv_show('group',group)
    # 目前实现数字提取,剩下与模板数字分割原理相同
    box_thresh=cv2.threshold(group,0,255,
                             cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
    # cv_show('box_thresh',box_thresh)
    cnts=cv2.findContours(box_thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[0]
    groupOutput = []
    for c in cnts:



        getnumber = []
        (x, y, w, h) = cv2.boundingRect(c)

        # points.append([x, y, w, h])
        roi = box_thresh[y:y + h, x:x + w]
        roi = cv2.resize(roi, (53, 83))
        thresh_val, roi = cv2.threshold(roi, 200, 255, cv2.THRESH_BINARY)
        # cv_show('roi', roi)
        scores = []
        for r in roi2:
            # cv_show('r',r)
            result = cv2.matchTemplate(roi, r, cv2.TM_CCOEFF)
            # print('r',result)
            # print(np.argmax(result))
            (_, score, _, _) = cv2.minMaxLoc(result)
            scores.append(score)

        # scores.reverse()
        groupOutput.insert(0,str(np.argmax(scores)))


    print('输出', groupOutput)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值