一、前言
上一篇文章总结了银行卡号识别的大概步骤,这篇文章着重介绍模板匹配法,以及如何处理模板的详细步骤及代码实现。
二、算法流程
三、代码实现
-
项目目录
-
首先,导入相关包
from imutils import contours
import numpy as np
import argparse
import cv2
import myutils
- 添加运行参数
'''
template:表示模板
image:表示输入图像
'''
# 创建ArgumentParser()对象
ap = argparse.ArgumentParser()
# 添加参数
ap.add_argument("-i", "--image", required=True,
help="path to input image")
ap.add_argument("-t", "--template", required=True,
help="path to template OCR-A image")
# 解析参数,并将其转换为Python的字典类型
args = vars(ap.parse_args())
- 读取并处理模板图像
# 读取一个模板图像
img = cv2.imread(args["template"])
cv_show('img',img)
# 转为灰度图
ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv_show('ref',ref)
# 转为二值图像
ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]
cv_show('ref',ref)
'''
计算轮廓
cv2.findContours()函数接受的参数为二值图,即黑白的(不是灰度图),
@:param cv2.RETR_EXTERNAL只检测外轮廓
@:param cv2.CHAIN_APPROX_SIMPLE只保留终点坐标
return:返回的list中每个元素都是图像中的一个轮廓
'''
# ref_, refCnts, hierarchy = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
refCnts, hierarchy = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
'''
ref_:显示返回值ref_,其实与输入参数的ref.copy()原图没啥区别
refCnts:找到的轮廓
hierarchy:
'''
# print('ref_:'+ref_)
# print('refCnts:'+refCnts)
# print('hierarchy:'+hierarchy)
# 画出找到的轮廓
cv2.drawContours(img, refCnts, -1, (0, 0, 255), 3)
cv_show('img', img)
print (np.array(refCnts).shape)
refCnts = myutils.sort_contours(refCnts, method="left-to-right")[0] #排序,从左到右,从上到下
digits = {}
# 遍历每一个轮廓
for (i, c) in enumerate(refCnts):
# 计算外接矩形并且resize成合适大小
(x, y, w, h) = cv2.boundingRect(c)
roi = ref[y:y + h, x:x + w]
roi = cv2.resize(roi, (57, 88))
# 每一个数字对应每一个模板
digits[i] = roi