作者 | 李秋键

责编 | Carol

头图 | CSDN 付费下载自视觉中国

随着计算机视觉在我们生活中的应用越来越广泛,大量的字符识别和提取应用逐渐变得越来越受欢迎,同时也便利了我们的生活。像我们生活中的凭借身份码取快递、超市扫码支付的机器等等。

字符识别是模式识别的一个重要应用,首先提取待识别字符的特征;然后对提取出来的特征跟字符模板的特征匹配;最后根据准则判定该字符所属的类别。不同的训练方法,不同的特征提取, 不同的匹配规则,就相应的有不同的字符识别方法,基本上很多就是在这些地方做改进,或者是采用新的规则。但是万变不离其宗。

1、模板匹配字符识别算法。

模板匹配字符识别算法是图像识别中的经典算法之一,该算法的核心思想是:通过比较待识别字符图像的字符特征和标准模板的字符特征,计算两者之间的相似性,相似性最大的标准模板的字符即为待识别的字符。

2、神经网络字符识别算法

主要思想:通过神经网络学习大量字符样本,从而得到字符的样本特征。当对待识别的字符进行识别时,神经网络就会将待识别字符的特征和之前得到的样本特征匹配,从而识别出字符。

3、支持向量机

主要思想:同上,都是先得到样本特征,进行训练,然后再分类。SVM应该算是用的最多的分类方法,一般大多适合于二分类问题,在这里就需要使用多分类器来构造。

今天我们就简单的利用OpenCV处理通过提取轮廓和匹配等方式来实现模式匹配的字符识别。

效果图如下:

实验前的准备

首先我们使用的python版本是3.6.5所用到的库有cv2库用来图像处理;

Numpy库用来矩阵运算,这里主要用来对图像像素值相关性处理;imutils库可以轻松实现基本图像处理功能,如平移,旋转,调整大小,骨架化和显示Matplotlib图像。

程序的搭建

1、参考图像的读取和处理:

参考图像如下,因为银行卡号主要只有0~9这几个数字,为了方便识别数字,我们直接利用这张图片里的数值作为匹配样式:

所以下面我们要做的事很明显,就是要将其中每个数字隔开方便后面匹配。

代码如下:

#定义了一个字典 FIRST_NUMBER  ,它将第一个数字映射到相应的信用卡类型。
FIRST_NUMBER = {"3": "American Express","4": "Visa","5": "MasterCard","6": "Discover Card"
}
#参考数字图像,用于匹配
#灰度化及二值化
ref=cv2.imread("1.png")
ref = cv2.cvtColor(ref, cv2.COLOR_BGR2GRAY)
ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]
#查找轮廓,从左往右排序
refCnts = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
refCnts = imutils.grab_contours(refCnts)
refCnts = contours.sort_contours(refCnts, method="left-to-right")[0]
digits = {}
#对于其中每一个轮廓进行提循环,i为数字名称,c为轮廓,我们将每个数字0-9(字典键)与第30行的每个roi   图像(字典值)相关联 。
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
#初始化几个结构化内核,构造了两个这样的内核 - 一个矩形和一个正方形。我们将使用矩形的一个用于Top-hat形态运算符,将方形一个用于关闭操作。
rectKernel=cv2.getStructuringElement(cv2.MORPH_RECT,(9,3))
sqKernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))

2、获取数字位置分组:

这里需要识别的图片为:

我们需要进行的处理包括二值化和Top-hat形态操作,最后通过findContours函数框出位置。

其中代码如下:

#加载信用卡图像
image=cv2.imread("3.jpg")
image=imutils.resize(image,width=300)
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
#执行Top-hat形态操作,将结果存储为 tophat,Top-hat操作显示了深色背景下的亮区(即信用卡号)
tophat=cv2.morphologyEx(gray,cv2.MORPH_TOPHAT,rectKernel)
#计算沿x方向的渐变在计算gradX   数组中每个元素的绝对值之后 ,我们采取一些步骤将值缩放到范围[0-255](因为图像当前是浮点数据类型)。要做到这一点,我们计算 MINVAL
#   和 MAXVAL   的 gradX   (线72),然后由我们的缩放方程上显示  线73(即,最小/最大归一化)。最后一步是将gradX转换   为 uint8   ,其范围为[0-255]
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")
#执行gradX 图像的Otsu和二进制阈值,然后是另一个关闭操作,对数字分段
gradx=cv2.morphologyEx(gradx,cv2.MORPH_CLOSE,rectKernel)
thresh=cv2.threshold(gradx,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1]
thresh=cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,sqKernel)
#找到轮廓并初始化数字分组位置列表
cnts=cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts=imutils.grab_contours(cnts)

3、切割字符:

接着循环遍历轮廓,同时根据每个的宽高比进行过滤,允许我们从信用卡的其他不相关区域修剪数字组位置,然后从左到右对分组进行排序,并初始化信用卡数字列表。

部分代码如下:

locs = []
#循环遍历轮廓,同时根据每个的宽高比进行过滤,允许我们从信用卡的其他不相关区域修剪数字组位置
for (i, c) in enumerate(cnts):# compute the bounding box of the contour, then use the# bounding box coordinates to derive the aspect ratio(x, y, w, h) = cv2.boundingRect(c)ar = w / float(h)# since credit cards used a fixed size fonts with 4 groups# of 4 digits, we can prune potential contours based on the# aspect ratioif ar > 2.5 and ar < 4.0:# contours can further be pruned on minimum/maximum width# and heightif (w > 40 and w < 55) and (h > 10 and h < 20):# append the bounding box region of the digits group# to our locations listlocs.append((x, y, w, h))
#从左到右对分组进行排序,并初始化信用卡数字列表
locs = sorted(locs, key=lambda x:x[0])
output = []
#遍历四个排序的分组并确定其中的数字,循环的第一个块中,我们在每一侧提取并填充组5个像素(第125行)
# ,应用阈值处理(第126和127行),并查找和排序轮廓(第129-135行)。
for (i, (gX, gY, gW, gH)) in enumerate(locs):# initialize the list of group digitsgroupOutput = []# extract the group ROI of 4 digits from the grayscale image,# then apply thresholding to segment the digits from the# background of the credit cardgroup = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]group = cv2.threshold(group, 0, 255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]# detect the contours of each individual digit in the group,# then sort the digit contours from left to rightdigitCnts = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)digitCnts = imutils.grab_contours(digitCnts)digitCnts = contours.sort_contours(digitCnts,method="left-to-right")[0]# loop over the digit contoursfor c in digitCnts:# compute the bounding box of the individual digit, extract# the digit, and resize it to have the same fixed size as# the reference OCR-A images(x, y, w, h) = cv2.boundingRect(c)roi = group[y:y + h, x:x + w]roi = cv2.resize(roi, (57, 88))# initialize a list of template matching scoresscores = []# loop over the reference digit name and digit ROIfor (digit, digitROI) in digits.items():# apply correlation-based template matching, take the# score, and update the scores listresult = cv2.matchTemplate(roi, digitROI,cv2.TM_CCOEFF)(_, score, _, _) = cv2.minMaxLoc(result)scores.append(score)# the classification for the digit ROI will be the reference# digit name with the *largest* template matching scoregroupOutput.append(str(np.argmax(scores)))# draw the digit classifications around the groupcv2.rectangle(image, (gX - 5, gY - 5),(gX + gW + 5, gY + gH + 5), (0, 0, 255), 2)cv2.putText(image, "".join(groupOutput), (gX, gY - 15),cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)# update the output digits listoutput.extend(groupOutput)
# display the output credit card information to the screen
print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
print("Credit Card #: {}".format("".join(output)))
cv2.imshow("Image", image)
cv2.waitKey(0)

到这里,我们整体的程序就搭建完成,下面为我们程序的运行结果:

源码地址:

链接:https://pan.baidu.com/s/16t7ZK4j1F6yzp2ynVQol0w

提取码:k5ra

作者简介:

李秋键,CSDN博客专家,CSDN达人课作者。硕士在读于中国矿业大学,开发有taptap竞赛获奖等等。

推荐阅读

  • 全球Python调查报告:Python 2正在消亡,PyCharm比VS Code更受欢迎

  • 来了来了!趋势预测算法大PK!

  • 10行Python代码能实现什么高端操作?

  • 无代码来了,还要程序员吗?

  • 没错,你离分布式搜索只差一个Elasticsearch入门!

  • 再见,Eclipse | 原力计划

  • 区块链共识算法总结 | 原力计划

  • 你点的每个“在看”,我都认真当成了AI

附代码 | OpenCV实现银行卡号识别,字符识别算法你知多少?相关推荐

  1. android opencv 银行卡识别,NDK 开发之使用 OpenCV 实现银行卡号识别

    前言 在日常的开发中,我们有时会遇到添加银行卡的需求,这时候,产品可能会让你仿一下支付宝之类的相机扫描识别银行卡号.很多时候,做这样的需求会去找找稳定的第三方,本文通过 OpenCV 结合识别的需求带 ...

  2. python人脸识别教程_50行Python代码+OpenCV实现人脸识别!史上最详细的教程!

    环境拓扑: 操作系统:windows7 python版本:2.7.14 opencv版本:3.x 环境配置: 1.安装python(额...这个当我没说) 2.安装Opencv 这个从官网下载就OK啦 ...

  3. 动物识别系统代码python_人工智能-动物识别专家系统算法Python + Pyqt 实现

    #-*- coding: utf-8 -*- #Form implementation generated from reading ui file '动物识别专家系统.ui'# #Created b ...

  4. 遗传算法_粒子群算法优化支持向量机分类预测-附代码

    遗传算法/粒子群算法优化支持向量机分类预测-附代码 文章目录 遗传算法/粒子群算法优化支持向量机分类预测-附代码 1. 支持向量机简介与参数优化的原理 1.1 支持向量机SVM简介 1.2 优化参数的 ...

  5. 基于粒子群算法优化的Elman神经网络数据预测-附代码

    基于粒子群算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于粒子群算法优化的Elman神经网络数据预测 - 附代码 1.Elman 神经网络结构 2.Elman 神经用络学习过程 3.电 ...

  6. opencv图像处理之K-means聚类算法

    opencv图像处理之K-means聚类算法 opencv图像处理之K-means聚类算法 kmeans算法过程与简单的理解 基于Opencv的c++代码 opencv图像处理之K-means聚类算法 ...

  7. 银行卡号识别python_银行卡号识别 基于 OpenCV 光学字符识别(OCR)

    银行卡号识别 基于 OpenCV 光学字符识别(OCR) 今天的博客文章是我们最近关于光学字符识别(OCR)和计算机视觉的系列的延续. 在之前的博客文章中,我们学习了如何安装Tesseract二进制文 ...

  8. OpenCV均值漂移meanshift algorithm算法的实例(附完整代码)

    OpenCV均值漂移meanshift algorithm算法的实例 OpenCV均值漂移meanshift algorithm算法的实例 OpenCV均值漂移meanshift algorithm算 ...

  9. OpenCV场景文本识别的实例(附完整代码)

    OpenCV场景文本识别的实例 OpenCV场景文本识别的实例 OpenCV场景文本识别的实例 #include <iostream> #include <fstream>#i ...

最新文章

  1. 零基础自学用Python 3开发网络爬虫(一)
  2. 要懂得利用和筛选友情链接
  3. 关于linux内存管理
  4. linux进程服务,Linux服务及进程
  5. 网络:http请求之几种常见技术
  6. LinkedList阅读
  7. 从相册获取图片,并获取裁剪后图片(系统自带)
  8. 三星 SGH-G810 多普达 P800 多普达 Touch Diamond(S900) 多普达 P860 多普达 Touch(T3238) 对比...
  9. 再学 GDI+[22]: TGPLinearGradientBrush - 之一: TLinearGradientMode
  10. php广告屏如何同步,户外LED大屏广告如何投放才能更吸引人?
  11. 【Flask】ORM关系以及一对多
  12. DEDECMS之二 如何修改模板页
  13. bwlabel和bwconncomp区别
  14. PKU 1273 Drainage Ditches
  15. SecureCRT下载和破解
  16. flask url_for()和redirect的区别
  17. iphone粘贴关联_如何将电话号码粘贴到iPhone的电话应用程序中
  18. 微信小程序云开发 操作数据库-简单数据的查询
  19. python可以替代office吗_哪些办公软件可以完美替代 Microsoft Office?
  20. 用户日活月活怎么统计 - Redis HyperLogLog 详解

热门文章

  1. 云联壹云融合云管理平台的 10 大应用场景
  2. 如何彻底删除Mac磁盘中的文件
  3. oracle数据库报错09275,【求助】oracle 数据库导入出错怎么解决?
  4. 南京理工计算机科学与技术怎样,南京理工大学计算机科学与技术学院
  5. mysql查询并计算单价,sql语句查询今年单价总金额
  6. Java毕业设计——> JSP+Servlet+C3P0+Mysql实现的网上蛋糕店
  7. ubuntu18镜像源修改为清华镜像源
  8. 银行借ApplePay反攻 七方利益分润未解
  9. CRM(01 线索)
  10. 姚老板讲机器学习之SVM算法