Python开发之基于模板匹配的信用卡数字识别功能


Posted in Python onJanuary 13, 2020

环境介绍

Python 3.6 + OpenCV 3.4.1.15

原理介绍

首先,提取出模板中每一个数字的轮廓,再对信用卡图像进行处理,提取其中的数字部分,将该部分数字与模板进行匹配,即可得到结果。

模板展示

Python开发之基于模板匹配的信用卡数字识别功能

完整代码

# !/usr/bin/env python
# —*— coding: utf-8 —*—
# @Time: 2020/1/11 14:57
# @Author: Martin
# @File: utils.py
# @Software:PyCharm
import cv2


def sort_contours(cnts, method='left-to-right'):
 reverse = False
 i = 0
 if method == 'right-to-left' or method == 'bottom-to-top':
 reverse = True
 if method == 'top-to-bottom' or method == 'bottom-to-top':
 i = 1
 boundingboxes = [cv2.boundingRect(c) for c in cnts]
 (cnts, boundingboxes) = zip(*sorted(zip(cnts, boundingboxes), key=lambda b: b[1][i], reverse=reverse))
 return cnts, boundingboxes


def resize(image, width=None, height=None, inter=cv2.INTER_AREA):
 (h, w) = image.shape[:2]
 if width is None and height is None:
 return image
 if width is None:
 r = height / float(h)
 dim = (int(w * r), height)
 else:
 r = width / float(w)
 dim = (width, int(h * r))
 resized = cv2.resize(image, dim, interpolation=inter)
 return resized
# !/usr/bin/env python
# —*— coding: utf-8 —*—
# @Time: 2020/1/11 14:57
# @Author: Martin
# @File: template_match.py
# @Software:PyCharm
"""
基于模板匹配的信用卡数字识别
"""
import cv2
import utils
import numpy as np

# 指定信用卡类型
FIRST_NUMBER = {
 '3' : 'American Express',
 '4' : 'Visa',
 '5' : 'MasterCard',
 '6' : 'Discover Card'
}


# 绘图显示
def cv_show(name, image):
 cv2.imshow(name, image)
 cv2.waitKey(0)
 cv2.destroyAllWindows()


# 读取模板图像
img = cv2.imread('./images/ocr_a_reference.png')
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)
# 计算轮廓
ref_, refCnts, hierarchy = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

cv2.drawContours(img, refCnts, -1, (0, 0, 255), 3)
cv_show('img', img)
print(np.array(refCnts).shape)
# 排序,从左到右,从上到下
refCnts = utils.sort_contours(refCnts, method='left-to-right')[0]
digits = {}
# 遍历每一个轮廓
for (i, c) in enumerate(refCnts):
 (x, y , w, h) = cv2.boundingRect(c)
 roi = ref[y:y+h, x:x+w]
 roi = cv2.resize(roi, (57, 88))
 digits[i] = roi
# 初始化卷积核
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
# 读取输入图像,预处理
img_path = input("Input the path and image name: ")
image_input = cv2.imread(img_path)
cv_show('image', image_input)
image_input = utils.resize(image_input, width=300)
gray = cv2.cvtColor(image_input, cv2.COLOR_BGR2GRAY)
cv_show('gray', gray)
# 礼帽操作,突出更明亮的区域
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)
cv_show('tophat', tophat)

gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)
gradX = np.absolute(gradX)
(minVal, maxVal) = (np.min(gradX), np.max(gradX))
gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))
gradX = gradX.astype("uint8")

print(np.array(gradX).shape)
cv_show('gradX', gradX)
# 闭操作
gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)
cv_show('gradX', gradX)
thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv_show('thresh', thresh)
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)
cv_show('thresh', thresh)
# 计算轮廓
thresh_, threshCnts, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = threshCnts
cur_img = image_input.copy()
cv2.drawContours(cur_img, cnts, -1, (0, 0, 255), 3)
cv_show('img', cur_img)
locs = []
# 遍历轮廓
for (i, c) in enumerate(cnts):
 (x, y, w, h) = cv2.boundingRect(c)
 ar = w / float(h)

 if 2.5 < ar < 4.0 and (40 < w < 55) and (10 < h < 20):
 locs.append((x, y, w, h))
# 将符合的轮廓从左到右排序
locs = sorted(locs, key=lambda ix: ix[0])
output = []
# 遍历每一个轮廓中的数字
for (i, (gX, gY, gW, gH)) in enumerate(locs):
 groupOutput = []

 group = gray[gY - 5:gY + gH + 5, gX - 5: gX + gW + 5]
 cv_show('group', group)
 # 预处理
 group = cv2.threshold(group, 0, 255, cv2.THRESH_OTSU)[1]
 cv_show('group', group)
 # 计算每一组轮廓
 group_, digitCnts, hierarchy = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
 digitCnts = utils.sort_contours(digitCnts, method='left-to-right')[0]
 # 计算每一组的每个数值
 for c in digitCnts:
 (x, y, w, h) = cv2.boundingRect(c)
 roi = group[y: y + h, x: x + w]
 roi = cv2.resize(roi, (57, 88))
 cv_show('roi', roi)
 scores = []
 for (digit, digitROI) in digits.items():
 result = cv2.matchTemplate(roi, digitROI, cv2.TM_CCOEFF)
 (_, score, _, _) = cv2.minMaxLoc(result)
 scores.append(score)
 # 得到最合适的数字
 groupOutput.append(str(np.argmax(scores)))
 cv2.rectangle(image_input, (gX - 5, gY - 5), (gX + gW + 5, gY + gH + 5), (0, 0, 255), 1)
 cv2.putText(image_input, "".join(groupOutput), (gX, gY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)
 # 得到结果
 output.extend(groupOutput)
# 打印结果
print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
print("Credit Card #: {}".format("".join(output)))
cv2.imshow("Image", image_input)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果展示

Python开发之基于模板匹配的信用卡数字识别功能

Credit Card Type: Visa
Credit Card #: 4020340002345678

总结

以上所述是小编给大家介绍的Python开发之基于模板匹配的信用卡数字识别功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
python调用新浪微博API项目实践
Jul 28 Python
Python抓取百度查询结果的方法
Jul 08 Python
Python爬虫常用小技巧之设置代理IP
Sep 13 Python
selenium+python自动化测试之环境搭建
Jan 23 Python
在Pycharm中调试Django项目程序的操作方法
Jul 17 Python
django认证系统 Authentication使用详解
Jul 22 Python
python 实现矩阵按对角线打印
Nov 29 Python
Python爬虫解析网页的4种方式实例及原理解析
Dec 30 Python
python实现井字棋小游戏
Mar 04 Python
Python利用Faiss库实现ANN近邻搜索的方法详解
Aug 03 Python
python实现简单贪吃蛇游戏
Sep 29 Python
Django中ORM的基本使用教程
Dec 22 Python
python中的itertools的使用详解
Jan 13 #Python
python3读取csv文件任意行列代码实例
Jan 13 #Python
pytorch程序异常后删除占用的显存操作
Jan 13 #Python
Python跑循环时内存泄露的解决方法
Jan 13 #Python
PyTorch使用cpu加载模型运算方式
Jan 13 #Python
Python如何读取文件中图片格式
Jan 13 #Python
详解python破解zip文件密码的方法
Jan 13 #Python
You might like
PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式
2012/04/09 PHP
在PHP中设置、使用、删除Cookie的解决方法
2013/05/06 PHP
php中使用key,value,current,next和prev函数遍历数组的方法
2015/03/17 PHP
PHP rsa加密解密使用方法
2015/04/27 PHP
PHP编程开发怎么提高编程效率 提高PHP编程技术
2015/11/09 PHP
关于laravel 日志写入失败问题汇总
2019/10/17 PHP
JavaScript 乱码问题
2009/08/06 Javascript
js日期、星座的级联显示代码
2014/01/23 Javascript
javascript实现playfair和hill密码算法
2014/12/07 Javascript
AngularJS使用ngOption实现下拉列表的实例代码
2016/01/23 Javascript
原生javascript实现addClass,removeClass,hasClass函数
2016/02/25 Javascript
js canvas实现擦除动画
2016/07/16 Javascript
jquery.zclip轻量级复制失效问题
2017/01/08 Javascript
ExtJs异步无法向外传值和赋值的完美解决办法
2017/06/14 Javascript
微信JSSDK调用微信扫一扫功能的方法
2017/07/25 Javascript
Vue使用axios出现options请求方法
2019/05/30 Javascript
详解基于Wepy开发小程序插件(推荐)
2019/08/01 Javascript
Nautil 中使用双向数据绑定的实现
2019/10/02 Javascript
JavaScript常用工具函数库汇总
2020/09/17 Javascript
js将日期格式转换为YYYY-MM-DD HH:MM:SS
2020/09/18 Javascript
JavaScript 防盗链的原理以及破解方法
2020/12/29 Javascript
python字符串的方法与操作大全
2018/01/30 Python
Python自定义装饰器原理与用法实例分析
2018/07/16 Python
Pytest mark使用实例及原理解析
2020/02/22 Python
python GUI库图形界面开发之PyQt5工具栏控件QToolBar的详细使用方法与实例
2020/02/28 Python
如何基于Python代码实现高精度免费OCR工具
2020/06/18 Python
Python数据分析库pandas高级接口dt的使用详解
2020/12/11 Python
多重CSS背景动画实现方法示例
2014/04/04 HTML / CSS
美国眼镜网站:EyeBuyDirect
2017/04/13 全球购物
美国最大点评网站:Yelp
2018/02/14 全球购物
PUMA澳大利亚官方网站:德国运动品牌
2018/10/19 全球购物
英国亚马逊官方网站:Amazon.co.uk
2019/08/09 全球购物
Alexandre Birman美国官网:亚历山大·伯曼
2019/10/30 全球购物
办公室秘书岗位职责范本
2014/02/11 职场文书
老干部工作汇报材料
2014/10/28 职场文书
Windows11插耳机没反应怎么办? win11耳机没声音的多种解决办法
2021/11/21 数码科技