对于模板图片
1:先进行灰度处理,在进行二值化处理,
2:获取轮廓
3:得到轮廓中的数字
4:对轮廓中的数字进行排序
对于要识别的图片
1:先进行灰度处理,在进行二值化处理,
2:先膨胀在腐蚀,得到卡号数字矩形轮廓
3:将得到的轮廓进行裁剪原图,拿到卡号图片
4:卡号图片在与模板图片对比

import cv2
import numpy as np
import TemplatePNG as tp
import matplotlib.pyplot as plt
#在此之前 ,需要对图片进行归一化处理,即所有识别的大小应该保持一样
#此方法没考虑照片的方向性质
def cv_show(img):
    cv2.imshow('name',img)
    cv2.waitKey()
    cv2.destroyAllWindows()
#灰度图
img=cv2.imread('images/credit_card_02.png')
ref = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#二值图像
ref = cv2.threshold(ref, 127, 255, cv2.THRESH_BINARY_INV)[1]
cv_show(ref)
kernel=np.ones((3,3),np.uint8)

# 初始化卷积核
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
#需要得到轮廓信息将数字连在一起,梯度运算效果比较好=膨胀-腐蚀
closing=cv2.morphologyEx(ref,cv2.MORPH_GRADIENT,rectKernel)
closing=cv2.morphologyEx(closing,cv2.MORPH_GRADIENT,rectKernel)
#填充图片区域,先膨胀,在腐蚀
closing=cv2.morphologyEx(closing,cv2.MORPH_CLOSE,rectKernel)
cv_show(closing)

#获取原图像矩形轮廓,必须传入二值化后的图
binary, contours, hierarchy =cv2.findContours(closing, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

res = cv2.drawContours(ref.copy(), contours, -1, (0, 0, 255), 2)
cv_show(res)
#过滤掉多余的矩形轮廓
locs=[]
for (a,b) in enumerate(contours):
    (x,y,w,h) =cv2.boundingRect(b)
    scale=w/float(h)
        #获取坐标
    if scale>=2.5 and scale<4.0 :
        locs.append((x,y,w,h))
        print("数据:",(x,y,w,h))

#观察数据,实际不能这么操作,将每条y,w,h相近的坐标取出来范围上下10左右
locs2=[]
for  (x,y,w,h) in locs:
    if h>=30 and h<=40:
        locs2.append((x,y,w,h))

#按照x坐标进行排序
locs2.sort(key= lambda x:x[0],reverse=False)
#找到4个大的轮廓后,在到四个小的轮廓中找到小轮廓,并用矩形圈出来,在通过模板进行一个个匹配
print(locs2)
ResultList=[]
restmap=tp.getMap()
for (i,(gx,gy,gw,gh)) in enumerate(locs2):
    #得到小图片
    roi= ref[gy:gy + gh, gx:gx + gw]
    #变成白色字体,与模板字体一样
    roi = cv2.threshold(roi, 127, 255, cv2.THRESH_BINARY_INV)[1]
    cv_show(roi)
    #得到轮廓信息
    resList=[]
    a1, b1, c1 =cv2.findContours(roi, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    for (a,b) in enumerate(b1):
        (x,y,w,h) =cv2.boundingRect(b)
        if y>0 and y<3  and h>=23 and h<=40:
            resList.append((x,y,w,h))
        #过滤掉不需要的轮廓
    resList.sort(key=lambda x:x[0],reverse=False)
    list2=[]
    #从每个小4x4的图片找出矩形框
    for (i,(x,y,w,h)) in enumerate(resList):
        reg=roi[y:y+h,x:x+w]
        reg = cv2.resize(reg, (57, 88))

        #遍历模板通过使用cv2模板方法进行匹配,并保存分数 ,选择分数最高的一个

        num=-1;
        sou=-1;
        for k,v in restmap.items():
            result=cv2.matchTemplate(reg,v,cv2.TM_CCOEFF)
            #值越大越相关
            (_,souce,_,_)=cv2.minMaxLoc(result)
            if souce>sou:
                num=k
                sou=souce

        ResultList.append(num)
        list2.append(num)
        # 把数字画出来
        cv2.putText(img, str(num), (gx+x, gy - 15),cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)
    cv2.rectangle(img, (gx , gy ),(gx + gw , gy + gh ), (0, 0, 255), 1)

cv_show(img)
print(ResultList)

TemplatePNG.py代码

import cv2
import numpy as np
def cv_show(img):
    cv2.imshow('name',img)
    cv2.waitKey()
    cv2.destroyAllWindows()
map={}
def getMap():
    if(len(map)==10):
        return map
    #处理模板图片
    img=cv2.imread('images/ocr_a_reference.png')
    ref = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #二值图像
    ref = cv2.threshold(ref, 127, 255, cv2.THRESH_BINARY_INV)[1]


    binary, contours, hierarchy=cv2.findContours(ref,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

    locs=[]
    #过滤掉不和条件的轮廓,并按照x大小进行排序
    for (a,b) in enumerate(contours):
        (x,y,w,h) =cv2.boundingRect(b)
        #print(x,y,w,h)

        if y>16 and y<24 and w>48 and w <59 and h>82 and h<90:
            locs.append((x,y,w,h))
            print(x,y,w,h)
    #通过x坐标进行排序
    locs.sort(key= lambda x:x[0],reverse=False)
    #放到一个map中
    for (i,(x,y,w,h)) in enumerate(locs):
        #画出矩形框
        cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
        #遍历得到模板内容
        roi = ref[y:y + h, x:x + w]
        roi = cv2.resize(roi, (57, 88))
        #将模板内容和数据放到集合中
        map[i]=roi
    #print(map)
    return map

模板图片

java根据卡号识别银行 基于opencv的银行卡号识别_二值化


需要识别的图片

java根据卡号识别银行 基于opencv的银行卡号识别_java根据卡号识别银行_02


java根据卡号识别银行 基于opencv的银行卡号识别_opencv_03