计算机视觉-OpenCV(银行卡号识别)

银行卡号识别(模板匹配)

1、模板预处理

2、卡片图片预处理

3、模板匹配

import cv2
import numpy as np
import myutils
from imutils import contours

def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
#读取模板文件
img=cv2.imread(r"D:\pythonProject\NewProject\PIc\number.png")
#cv_show(img,'number')
#转换灰度图
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#cv_show(gray,'gray_number')
#转换为二值图
ret,ref=cv2.threshold(gray,10,255,cv2.THRESH_BINARY_INV)
#cv_show(ref,'ref')
#检测轮廓
refCnts,hierarchy=cv2.findContours(ref,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#绘制轮廓
res=cv2.drawContours(img.copy(),refCnts,-1,(0,0,255),2)
#cv_show(res,'res')
#检查绘制轮廓的数量
print(np.array(refCnts).shape)
#排序轮廓(从左到右),返回值:轮廓坐标,boundingBoxes
refCnts,boundingBoxes=contours.sort_contours(refCnts,method="left-to-right")
#print(refCnts)

digits={}
#遍历每一个轮廓
for (i,c) in enumerate(refCnts):
    #计算外接矩形
    (x,y,w,h)=cv2.boundingRect(c)
    roi=ref[y:y+h,x:x+w]
    #重设大小
    roi=cv2.resize(roi,(57,58))
    digits[i]=roi
#cv_show(digits[3],'1')
#print('------------',digits)

#输入文件处理
#初始化卷积核
rectKernel=cv2.getStructuringElement(cv2.MORPH_RECT,(9,3))
sqKernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))

#卡片图像读取
image=cv2.imread(r"D:\pythonProject\NewProject\PIc\card.png")

#cv_show(image,'image')

gray_image=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
high,width=gray_image.shape
gray_image=cv2.resize(gray_image,(int(width / 12), int(high / 12)))
#cv_show(gray_image,'gray_image')
print(gray_image.shape)

#礼帽操作(突出更明亮的区域)
tophat=cv2.morphologyEx(gray_image,cv2.MORPH_TOPHAT,rectKernel)
#cv_show(tophat,'tophat')
'''
#加转二值图
ret,ref1=cv2.threshold(tophat,10,255,cv2.THRESH_BINARY_INV)
cv_show(ref1,'ref')
'''
#Sobel算子 检测边缘,ksize=-1相当于3×3
gradX=cv2.Sobel(tophat,ddepth=cv2.CV_32F,dx=1,dy=0,ksize=-1)
#负数取绝对值,与cv2.convertScaleAbs类似
gradX=np.absolute(gradX)
#cv_show(gradX,'1')
#归一化
(minVal,maxVal)=(np.min(gradX),np.max(gradX))
gradX=(255*((gradX-minVal)/(maxVal-minVal)))
gradX=gradX.astype("uint8")
print(np.array(gradX).shape)
#cv_show(gradX,'gradX')

#闭操作,通过闭操作(先膨胀,在腐蚀)将数组按每四个一组连起
gradX=cv2.morphologyEx(gradX,cv2.MORPH_CLOSE,rectKernel)
#cv_show(gradX,'gradX')
#二值化处理:THRESH_OTSY会自动寻找合适阈值,适合双峰,需把阈值参数设成0
thresh=cv2.threshold(gradX,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1]
#cv_show(thresh,'thresh1')

#计算外轮廓
threshCnts,hierarchy=cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#画轮廓
image_res=cv2.drawContours(gray_image.copy(),threshCnts,-1,(0,0,255),2)
#cv_show(image_res,'image_res')

locs=[]
#遍历轮廓
for (i,c) in enumerate(threshCnts):
    (x,y,w,h)=cv2.boundingRect(c)
    ar = w/float(h)

    #选择合适的轮廓区域
    if ar > 3.5 and ar<4.0:
        locs.append((x,y,w,h))
        #im = cv2.drawContours(gray_image.copy(), c, -1, (0, 0, 255), 2)
        #cv_show(im, 'im')
#排序
locs=sorted(locs,key=lambda x:x[0])
output=[]

#遍历每一个轮廓中数字
for (i,(gX,gY,gW,gH)) in enumerate(locs):
    groupOutput=[]

    #根据坐标提取每一个组(根据轮廓往外稍扩一些)
    group=gray_image[gY-3:gY+gH+3,gX-3:gX+gW+3]
    #cv_show(group,'group')

    #预处理
    #二值化
    group = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
    #cv_show(group, 'group')
    #轮廓检测
    groupCnts, hierarchy = cv2.findContours(group, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    #排序
    cardCnts, boundingBoxes = contours.sort_contours(groupCnts, method="left-to-right")

    #计算每一组中的每一个数值
    for c in cardCnts:
        #找到当前数值的轮廓,resize数值大小,与模板大小一致
        (x,y,w,h)=cv2.boundingRect(c)
        roi = thresh[y:y + h, x:x + w]
        # 重设大小
        roi = cv2.resize(roi, (57, 58))
        #cv_show(roi,'roi')

        scores=[]
        #在模板中计算每一个的得分
        for (digit,digitROI) in digits.items():
            #模板匹配
            result = cv2.matchTemplate(roi, digitROI, cv2.TM_CCOEFF)
            (_,score,_,_)=cv2.minMaxLoc(result)
            scores.append(score)
        #np.argmax,返回最大值的索引值
        groupOutput.append(str(np.argmax(scores)))


        #画出来
        #cv2.rectangle(gray_image,())
    cv2.putText(gray_image,"".join(groupOutput),(gX,gY-15),cv2.FONT_HERSHEY_SIMPLEX,0.35,(0,0,255),2)
    output.extend(groupOutput)
print(output)
#cv_show(gray_image,'gray_imageend')

你可能感兴趣的:(Python机器学习,计算机视觉,opencv,python)