1.项目背景
1.1 项目介绍
这个一个opencv的经典应用,所以用它来熟悉之前的一些操作。
1.2 项目目的
通过此程序可以识别出银行卡图片中包括的银行卡卡号。
2.项目介绍
此项目主要分为两部分:模板图片处理,银行卡图片处理。
模板图片:
银行卡图片示例:
2.1 模板图片处理
由于模板图片如上图所示,是把十个数字放在一个图片里面,因此需要利用轮廓检测方法把它们分开成为10个模板。如下图:
步骤:
- 读入图片
- 化为 灰度图,再化为二值图
- 对二值图轮廓检测,得到轮廓数据
- 对所有轮廓按照x轴的方向排序
- 根据4得到的轮廓数据,把数字分为10个,利用外接矩形得到每个数字的边界
- 设置成统一大小(和要匹配的银行卡图片大小相同),存储每个数字成为一个模板
#设置参数 --》这个是通过设置参数,知道去哪里找到路径,
# 然后通过这个路径找到模板图片和银行卡图片 cv2.imread(args["template"])
# 也可以自己用cv2.imread(路径)读入模板图片
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")
args=vars(ap.parse_args())#显示图像
def cv_show(img,name="image"):cv2.imshow(name,img)cv2.waitKey(0)cv2.destroyWindow(name)template=cv2.imread(args["template"])
# cv_show(template)
#化为灰度图
ref_template=cv2.cvtColor(template,cv2.COLOR_BGR2GRAY)
# cv_show(ref_template)
#化为二值图
ref_template=cv2.threshold(ref_template,10,255,cv2.THRESH_BINARY_INV)[1]
# cv_show(ref_template)#轮廓检测
##findContours 只接受二值图 RETR_EXTERNAL 只检测外轮廓 CHAIN_APPROX_SIMPLE 只保留终点坐标
refCnts,hierarchy=cv2.findContours(ref_template.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(template,refCnts,-1,(0,0,255),3)
# cv_show(template)
# print(np.array(refCnts).shape)
#轮廓排序
refCnts=contours.sort_contours(refCnts,method="left-to-right")[0]
# print(refCnts)digits={}
for (i,c) in enumerate(refCnts):#计算外接矩形(x,y,w,h)=cv2.boundingRect(c)roi=ref_template[y:y+h,x:x+w]#resize成合适大小roi=cv2.resize(roi,(57,88))# cv_show(roi)#每个数字对应一个模板digits[i]=roi
2.2 银行卡图片处理
银行卡图片因为有太多的与识别无关的东西,因此比模板图片处理稍微复杂一点。
基本思想是:
把16个数字分为4组,分别让每一组的每个数字和2.1得到的10个模板进行模板匹配,计算他们的匹配度,然后找到最高匹配度作为识别结果
如图所示:
步骤:
- 读入图片
- 灰度图片处理
- 顶帽操作:突出明亮区域
- 计算梯度:使轮廓更加清晰
- 闭操作:由于我们是4个数字一起处理,所以通过闭操作把4个数字连在一起
- 二值化处理
- 二值化后再次闭操作:使得数字清晰
- 轮廓检测
- 由于图片不止有银行卡号,所以需要想方法除去不要的轮廓。只留下红色
- 利用9提取到的四个轮廓,开始对四个轮廓里面包含的四个数字依次处理
- 利用轮廓提取到一个轮廓,二值化后进行轮廓检测(此时检测出四个轮廓,即四个数字)
- 分隔出每个数字,然后重置成模板一样的大小。依次和10个模板计算匹配,得到一个最高分。
#初始化卷积核
rectKernel=cv2.getStructuringElement(cv2.MORPH_RECT,(9,3))
sqKernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))#读取输入图像
image=cv2.imread(args["image"])
# cv_show(image)
image=imutils.resize(image,width=300)
image_gray