python+opencv信用卡卡号识别

import  cv2
import numpy as  np
import warnings
warnings.filterwarnings('ignore')

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
def resize(image, width=None, height=None, inter=cv2.INTER_AREA):
    dim = None
    (h, w) = image.shape[:2]
    if width is None and height is None:
        return image
    if width is None:
        r = height / float(h)
        dim = (int(w * r), height)
    else:
        r = width / float(w)
        dim = (width, int(h * r))
    resized = cv2.resize(image, dim, interpolation=inter)
    return resized




img=cv2.imread('number.png')
ref=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
_,ref=cv2.threshold(ref,10,255,cv2.THRESH_BINARY_INV)
refCnts,_=cv2.findContours(ref,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
# cv2.drawContours(img,refCnts,-1,(0,0,255),3)
refCnts = sort_contours(refCnts, method="left-to-right")[0]#排序,从左到右,从上到下
digits={}
for (i,c) in enumerate(refCnts):
    (x,y,w,h)=cv2.boundingRect(c)
    # 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))
    digits[i]=roi
# print(len(digits))


rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

img=cv2.imread('testimage.png')
img=resize(img,width=300)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

gradX=cv2.Sobel(gray,ddepth=cv2.CV_32F,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(np.uint8)
gradX=cv2.morphologyEx(gradX,cv2.MORPH_CLOSE,rectKernel)
_,thres=cv2.threshold(gradX,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)  #只要灰度大于0的都设为255
thres=cv2.morphologyEx(thres,cv2.MORPH_CLOSE,sqKernel)
threshCnts,_=cv2.findContours(thres,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
# cv2.drawContours(img,threshCnts,-1,(0,255,0),3)
cnts=threshCnts
locs=[]

for i,c in enumerate(cnts):
    x,y,w,h=cv2.boundingRect(c)
    if h>w:
        h,w=w,h
    acr=w/h
    if 2.5<acr<4.0:
        if (40<w<55) and (10<h<20):
            locs.append((x,y,w,h))
output=[]
locs = sorted(locs, key=lambda x:x[0])
for (i, (gX, gY, gW, gH)) in enumerate(locs):
    # initialize the list of group digits
    groupOutput = []

    # 根据坐标提取每一个组
    group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]
    _,group=cv2.threshold(group,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    digitCnts,_=cv2.findContours(group,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    digitCnts = sort_contours(digitCnts,
                                      method="left-to-right")[0]
    for c in digitCnts:
        x,y,w,h=cv2.boundingRect(c)
        roi=group[y:y+h,x:x+w]
        roi=cv2.resize(roi,(57,88))


        scores=[]
        for (digit, digitROI) in digits.items():
            # 模板匹配
            result = cv2.matchTemplate(roi, digitROI,
                                       cv2.TM_CCOEFF)
            (_, score, _, _) = cv2.minMaxLoc(result)
            scores.append(score)

        # 得到最合适的数字
        groupOutput.append(str(np.argmax(scores)))
    # print(groupOutput)
        # 画出来
    cv2.rectangle(img, (gX - 5, gY - 5),
                  (gX + gW + 5, gY + gH + 5), (0, 0, 255), 1)
    cv2.putText(img, "".join(groupOutput), (gX, gY - 15),
                cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)

    # 得到结果
    output.extend(groupOutput)

# 打印结果
print("Credit Card #: {}".format("".join(output)))
cv2.imshow('1',img)
cv2.waitKey()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值