计算机视觉实战(九)信用卡数字识别项目(附完整代码)
上一节计算机视觉实战(八)直方图与傅里叶变换
的完整代码,回复关键字:直方图与傅里叶变换
。上一节文末忘记说了。
项目概述
我们要做的事情就是识别如下信用卡中的数字:
大致方法流程:
- 使用模板匹配方式对模板,以及输入图像进行轮廓检测(检测外轮廓)。
- 得到当前轮廓的外接矩形。
- 将模板中的外接矩形切割出来。
- 使用矩形的长宽比之间的差异使得信用卡的数字矩形框能够被选择出来。
- 将其进一步细分,与需要识别的信用卡当中的外接矩形resize成同样的大小。
- 使用for循环依次检测。
代码解释:
导入相关的工具包
from imutils import contours
import numpy as np
import argparse
import cv2
import myutils
设置参数
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())
指定信用卡类型
FIRST_NUMBER = {"3": "American Express","4": "Visa","5": "MasterCard","6": "Discover Card"
}
设置一下绘图函数,绘图展示
def cv_show(name,img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()
读取一个模板图像,因为这里没有调用分类算法,直接用的模板。如果背景比较复杂的话,可以调用一下分类的算法对目标进行识别。我们先读取一下,之后对其进行显示。
img = cv2.imread(args["template"])
cv_show('img',img)
将其转化为灰度图,方便之后操作。调用cv2.cvtColor
函数,设置cv2.COLOR_BGR2GRAY
参数即可。显示出来结果如下图所示:
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)
因为做轮廓检测的时候输入进来的一般都是二值图像,都是为了方便轮廓检测。所以这做二值处理。
因为我们不仅需要轮廓的图像,还需要知道这个轮廓图像对应的标签是啥,所以我们需要计算轮廓,依据每个轮廓所在位置的不同将其进行划分。这里我们使用OpenCv中的cv2.findContours()
函数来进行轮廓检测。函数用法
cv2.findContours()
函数接受的参数为二值图,即黑白的(不是灰度图),cv2.RETR_EXTERNAL
只检测外轮廓,cv2.CHAIN_APPROX_SIMPLE
只保留终点坐标,返回的list
中每个元素都是图像中的一个轮廓。
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)
将其从左到右排列,从左到右,从上到下,一句坐标信息就能知道其标签信息。
refCnts = myutils.sort_contours(refCnts, method="left-to-right")[0]
digits = {}
def sort_contours(cnts, method="left-to-right"):reverse = Falsei = 0if method == "right-to-left" or method == "bottom-to-top":reverse = Trueif method == "top-to-bottom" or method == "bottom-to-top":i = 1boundingBoxes = [cv2.boundingRect(c) for c in cnts] #用一个最小的矩形,把找到的形状包起来x,y,h,w(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),key=lambda b: b[1][i], reverse=reverse))return cnts, boundingBoxes
遍历每一个轮廓
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
到这里模板就已经算完了。接下来需要对信用卡图像进行处理。
初始化卷积核:在形态学的操作过程当中,我们需要定义一些核,这个都是依据我们的实际任务而决定的。
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)
预处理一下,其结果显示如下所示:
image = myutils.resize(image, width=300)
gray = cv2.cvtColor(image, 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相当于用3*3的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_OTSU
会自动寻找合适的阈值,适合双峰,需把阈值参数设置为0。
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.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 ar > 2.5 and ar < 4.0:if (w > 40 and w < 55) and (h > 10 and h < 20):#符合的留下来locs.append((x, y, w, h))
# 将符合的轮廓从左到右排序
locs = sorted(locs, key=lambda x:x[0])
之后我们需要对目标图像的区域依次循环匹配,得到匹配分数最大的那一个。
output = []# 遍历每一个轮廓中的数字
for (i, (gX, gY, gW, gH)) in enumerate(locs):# initialize the list of group digitsgroupOutput = []# 根据坐标提取每一个组group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]cv_show('group',group)# 预处理group = cv2.threshold(group, 0, 255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]cv_show('group',group)# 计算每一组的轮廓group_,digitCnts,hierarchy = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)digitCnts = contours.sort_contours(digitCnts,method="left-to-right")[0]# 计算每一组中的每一个数值for c in digitCnts:# 找到当前数值的轮廓,resize成合适的的大小(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, (gX - 5, gY - 5),(gX + gW + 5, gY + gH + 5), (0, 0, 255), 1)cv2.putText(image, "".join(groupOutput), (gX, gY - 15),cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)# 得到结果output.extend(groupOutput)
完整代码:https://github.com/ZhiqiangHo/Opencv-Computer-Vision-Practice-Python-
我的微信公众号名称:深度学习与先进智能决策
微信公众号ID:MultiAgent1024
公众号介绍:主要研究分享深度学习、机器博弈、强化学习等相关内容!期待您的关注,欢迎一起学习交流进步!
计算机视觉实战(九)信用卡数字识别项目(附完整代码)相关推荐
- OpenCV计算机视觉实战,停车场车位识别!(完整代码)!
任务描述:识别这种停车场图的 空车位 与 被占用车位 识别流程:预处理 -> 获得车位坐标的字典 -> 训练VGG网络进行二分类 img_process 图像预处理过程 1.select_ ...
- 深度学习项目实战——手写数字识别项目
摘要 本文将介绍的有关于的paddle的实战的相关的问题,并分析相关的代码的阅读和解释.并扩展有关于的python的有关的语言.介绍了深度学习步骤: 1. 数据处理:读取数据 和 预处理操作 2. 模 ...
- 基于AlexNet卷积神经网络的手写体数字识别系统研究-附Matlab代码
⭕⭕ 目 录 ⭕⭕ ✳️ 一.引言 ✳️ 二.手写体数字识别系统 ✳️ 2.1 MNIST 数据集 ✳️ 2.2 CNN ✳️ 2.3 网络训练 ✳️ 三.手写体数字识别结果 ✳️ 四.参考文献 ✳️ ...
- 【opencv】(9) 图像识别实战:银行卡数字识别,附python完整代码和数据集
各位同学大家好,今天我和大家分享一下opencv机器视觉实战项目,识别银行卡上的数字,该方法也同样适用于车牌数字识别. 数据集免费: https://download.csdn.net/downloa ...
- 利用Tensorflow实现手写数字识别(附python代码)
手写识别的应用场景有很多,智能手机.掌上电脑的信息工具的普及,手写文字输入,机器识别感应输出:还可以用来识别银行支票,如果准确率不够高,可能会引起严重的后果.当然,手写识别也是机器学习领域的一个Hel ...
- python基于百度智能云实现批量身份证信息识别(附完整代码,可直接使用)
百度智能云配置 一.登录 登录百度智能云,找到卡证文字识别,点击立即使用 地址: https://cloud.baidu.com/product/ocr_cards 二.创建应用 创建一个应用,过程不 ...
- Matlab深度学习入门实例:基于AlexNet的红绿灯识别(附完整代码)
AlexNet于2012年出现在ImageNet的图像分类比赛中,并取得了当年冠军,从此卷积神经网络开始受到人们的强烈关注.AlexNet是深度卷积神经网络研究热潮的开端,也是研究热点从传统视觉方法过 ...
- 项目实战之信用卡数字识别
项目要求 要求输入一张信用卡图片后能够识别出卡号的位置,并且识别出卡号是多少 输出图像如下图所示 实战 ocr_match_template.py import cv2 import numpy as ...
- OpenCV计算机视觉实战(Python)_09-项目实战:信用卡数字识别( Jupyter notebook实现)
1.介绍 从一个银行卡中识别其中的银行卡号: 2. 流程 读图 , 灰度图 , 二值化 使用模板匹配方式对模板,以及输入图像进行轮廓检测(检测外轮廓). 得到当前轮廓的外接矩形. 将模板中的外接矩形切 ...
- CLUENER 细粒度命名实体识别,附完整代码
CLUENER 细粒度命名实体识别 文章目录 CLUENER 细粒度命名实体识别 一.任务说明: 二.数据集介绍: 2.1 数据集划分和数据内容 2.2 标签类别和定义: 2.3 数据分布 三.处理j ...
最新文章
- 点击一百万次(详解)——bugku
- Split-plot设计 SAS实践
- Gradle修改本地仓库的位置
- JAVA入门级教学之(break跳出)
- python end of statement_17个新手常见Python运行时错误
- 腾讯、爱奇艺修改超前点播规则:不再是支付额外50元看6集
- 落谷 P3375 【模板】KMP字符串匹配
- Linux虚拟机远程连接工具
- php集成paypal接口,PayPal接口集成之:PHP集成PayPal标准支付接口
- uint8_t范围_uint8_t / uint16_t / uint32_t /uint64_t数据类型详解
- 关于Pearson相关系数的显著性p值如何计算以及背后原因的思考
- mybatis处理多对一映射关系3- 分步查询和延迟加载
- PyCharm插件安装
- Android模拟器启动报错:gpu found. vendor id 1002 device id 0x
- 机器学习 决策树和随机森林
- 010 极限的四则运算例题
- 《数据库原理与应用》实验二
- 常见的概率公式及其推导(马尔科夫HMM系列课程拓展)
- java opengl 图片文字_如何通过opengl显示相机预览
- 火狐浏览器谷歌浏览器Edge浏览器修改默认UA(User-Agent)