银行卡账号识别

 

 

main.py

import cv2
import math
import torch
import numpy as np
import scan_utils
def show(img):
    cv2.imshow('name', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()




def match(img, tmp):
    w, h = tmp.shape[ : 2]
    match_d = cv2.matchTemplate(img, tmp, 1)
    min_v, max_v, min_id, max_id = cv2.minMaxLoc(match_d)
    cv2.rectangle(img, min_id, (min_id[0] + w, min_id[1] + h), (0, 0, 255), 2)
    return img





if __name__ == '__main__':
    tmp = cv2.imread('F:/Source/images/ocr_a_reference.png')
    img = cv2.imread('F:/Source/images/credit_card_01.png')
    tmp_gray = cv2.cvtColor(tmp, cv2.COLOR_BGR2GRAY)
    _, tmp_bin = cv2.threshold(tmp_gray, 10, 255, cv2.THRESH_BINARY_INV)
    binary, contours, hie = cv2.findContours(tmp_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    tmp_copy = tmp.copy()
    contours = scan_utils.Sort(contours)
    bbox = [cv2.boundingRect(c) for c in contours]  #外界矩形函数只能处理单个轮廓,所以要一个个处理
    dic = {}  #用大括号,字典数据类型,用.items()遍历每个元素
    for (i, box) in enumerate(bbox):
        (x, y, w, h) = box  #拿出来的时候是x y w h
        dic[i] = tmp[y : y + h, x : x + w]   #注意这个y在前,x在后
        dic[i] = cv2.resize(dic[i], (57, 88))

    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    rectkernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
    sqkernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
    img_hat = cv2.morphologyEx(img_gray, cv2.MORPH_TOPHAT, rectkernel)
    img_sobelx = cv2.Sobel(img_hat, -1, 1, 0, ksize = 3)
    img_sobelx = cv2.convertScaleAbs(img_sobelx)
    img_dilate = cv2.dilate(img_sobelx, rectkernel, iterations=4)
    img_erode = cv2.erode(img_dilate, rectkernel, iterations=1)

    #阈值设置为0,后边带一个OTSU,目的是让计算机自己选一个合适的阈值,并不是0
    img_bin = cv2.threshold(img_erode, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
    img_close = cv2.morphologyEx(img_bin, cv2.MORPH_CLOSE, sqkernel)
    contours = cv2.findContours(img_close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1]
    contours = scan_utils.Sort(contours)
    img_copy = img.copy()
    bbox = [cv2.boundingRect(cnt) for cnt in contours]



    loc = []
    for box in bbox:
        (x, y, w, h) = box
        if (h >= 34 and h <= 35 and w <= 119 and w >= 117):
            loc.append(box)
            cv2.rectangle(img_copy, (x, y), (x + w, y + h), (0, 0 , 255), 2)
    for (i, (x, y, w, h)) in enumerate(loc):
        sub_img = img_copy[y - 5 : y + h + 5, x - 5 : x + w + 5]   #将边界扩大一下,别正好贴着
        sub_img_gray = cv2.cvtColor(sub_img, cv2.COLOR_BGR2GRAY)
        sub_img_bin = cv2.threshold(sub_img_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
        sub_contours = cv2.findContours(sub_img_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1]
        sub_contours = scan_utils.Sort(sub_contours)
        sub_bbox = [cv2.boundingRect(cnt) for cnt in sub_contours]
        text = ''
        for sub_box in sub_bbox:
            (sx, sy, sw, sh) = sub_box
            sub_tmp = sub_img[sy : sy + sh, sx : sx + sw]
            #show(sub_tmp)
            sub_tmp = cv2.resize(sub_tmp, (53, 88))
            scores = []
            for j, tmp_value in dic.items():
                degree  = cv2.matchTemplate(tmp_value, sub_tmp, cv2.TM_SQDIFF)
                (min_v, max_v, min_coor, max_coor) = cv2.minMaxLoc(degree) #用的是SQDIFF,则min_v相当于一个置信度
                scores.append(min_v)
            k = np.argmax(scores)
            print(k, end = "")
            text += str(k)
        print(" ", end = "")
        cv2.putText(img_copy, text, (x, y), 1, 1, (0, 0, 255), 2)
    show(img_copy)

 

scan_utils:

import cv2
import numpy as np


def cmp(x):
    return x[0][0]


def Sort(contours):
    bbox = [cv2.boundingRect(c) for c in contours]
    (_, ret) = zip(*sorted(zip(bbox, contours), key = cmp))
    return ret

 

posted @ 2021-09-14 22:10  WTSRUVF  阅读(176)  评论(0编辑  收藏  举报