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