作者|李
编辑|卡罗尔
头部| 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' 3360' Visa ',' 5' 3360' MasterCard ',' 6' 3360' Discover Card'} #参考数字图像,用于#灰度化和二值化ref=cv2 . im read(' 1 . png ')ref=cv2 . CVT color(ref,cv2 . color _ bgr 2 gray)ref=cv2 . threshold(ref,10,255,cv2 . thresh _ binary _ inv)1 Sort ref CNTs=1cv chain _ approximate _ simple)ref CNTs=IMU tils . grab _ contours(ref CNTs)ref CNTs=contours . sort _ contours(ref CNTs,method=' left-to-right ')0 digits={ } #循环每个轮廓,I为数值名。
roi 图像(字典值)相关联 。for (i,c) in enumerate(refCnts): (x,y,w,h)=cv2.boundingRect(c) roi=ref
这里需要识别的图片为:
我们需要进行的处理包括二值化和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 ratio if ar > 2.5 and ar < 4.0: # contours can further be pruned on minimum/maximum width # and height if (w > 40 and w < 55) and (h > 10 and h < 20): # append the bounding box region of the digits group # to our locations list locs.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 digits groupOutput = <> # extract the group ROI of 4 digits from the grayscale image, # then apply thresholding to segment the digits from the # background of the credit card group = gray
源码地址:
链接:https://pan.baidu.com/s/16t7ZK4j1F6yzp2ynVQol0w
提取码:k5ra
作者简介:
李秋键,CSDN博客专家,CSDN达人课作者。硕士在读于中国矿业大学,开发有taptap竞赛获奖等等。