这一篇将介绍如何使用Python,OpenCV从支票图像中提取OCR银行账户和路由号码(数字和符号)。
OCR银行支票比OCR信用卡更难——这主要是因为银行支票符号由多个部分组成。因此不能假设参考字体图像中的每个轮廓都映射到单个字符。
相反需要额外的逻辑来检查每个轮廓的尺寸,并确定检测到的是数字还是符号。
在找到符号的情况下,需要抓取下两个轮廓来构建边界框(因为银行支票控件字符由三个不同的部分组成)。
. 效果图
MICR E-13B字符集简单提取过程如下:原始图 VS 灰度图 VS 阈值化图 VS 简单提取效果图
可以看到符号区域虽然每个符号由3个轮廓组成,但也被展示为3个轮廓。下一步高级复杂提取则将符号区域的3个轮廓提取为一个。
MICR E-13B字符集高级复杂提取效果如下:
银行支票提取数字和符号OCR效果图如下:
银行支票提取数字和符号OCR过程图如下:
原始图 VS 灰度图 VS 黑帽图 VS Scharr梯度图 VS
矩形内核形态学闭合图 VS Octus阈值化二值化图 VS 清除边界图
- 灰度图:忽略色彩的影响
- 黑帽图:在浅色背景下查找暗区域(明亮的背景下查找暗的区域——帐号部分)
- Scharr梯度图:了解颜色分布闭合部分缝隙
- 矩形内核形态学闭合图:闭合数字字符轮廓之间的小的缝隙
- Octus阈值化二值化图:将图像分为白色前景和黑色背景,便于轮廓提取
- 清除边界图:清除掉靠近边界的任何像素,很有效
- 轮廓过滤:根据轮廓的面积和宽高比过滤掉无效的轮廓
2. 原理
2.1 MICR E-13B字体
MICR(Magnetic Ink Character Recognition 磁性墨水字符识别)是一种用于处理文档的金融行业技术。您经常会在对账单和支票的底部发现这种E-13B格式的磁性墨水。
银行支票上的数字是MICR E-13B字体,如下图包括类似font-a字体,0~9的10个数字,及后边的4个符号区,共14个字符。
- 数字:数字0-9
- ⑆ :中转银行分行分隔符
- ⑇ :金额,交易金额分隔符
- ⑈ :客户帐号分隔符
- ⑉ :破折号:数字分隔符
2.2 从MICR E-13B参考图像中提取数字和符号
将使用OpenCV轮廓和一点Python迭代器切片“魔法”来实现提取。
数字区相对容易一些,一个数字一个轮廓。然而每个符号包含3个轮廓。
3. 源码
3.1 MICR E-13B符号和数字提取
# 银行支票(从MICR字体中提取数字和符号提取) # MICR(Magnetic Ink Character Recognition 磁性墨水字符识别)是一种用于处理文档的金融行业技术。 # 经常会在对账单和支票的底部发现这种E-13B格式的磁性墨水。 # USAGE # python bank_check_ocr.py --image images/example_check.jpg --reference images/micr_chars.png # 导入必要的包 from skimage.segmentation import clear_border # pip install -U scikit-image from imutils import contours # pip install --upgrade imutils import numpy as np # pip install numpy import argparse import imutils import cv2 # 从MICR中提取数字和符号 # image: MICR E-13B字体图像(在代码下载中提供)。 # charCnts:包含参考图像中字符轮廓的列表 # minW:表示最小字符宽度的可选参数。这有助于当遇到2或3个小轮廓时,它们一起构成一个MICR字符。默认值为5像素的宽度。 # minH:最小字符高度。此参数是可选的,默认值为15像素。rational的用法与minW相同 def extract_digits_and_symbols(image, charCnts, minW=5, minH=15): # 获取字符轮廓列表的内置Python迭代器 # 并分别初始化存放ROI和位置的列表 charIter = charCnts.__iter__() rois = [] locs = [] # Python迭代器没有Java等语言中的“hasNext”方法——相反,当iterable对象中没有更多项时,Python将抛出异常。 # 因此在函数中使用try-catch块来解释此异常。 # 保持遍历字符轮廓,知道到达list末尾 w