当前位置: 首页 > news >正文

网站服务器有哪些种类小程序免费制作

网站服务器有哪些种类,小程序免费制作,wordpress付费电台,站长工具高清无吗实战1-银行卡号识别 项目来源:opencv入门 项目目的:识别传入的银行卡照片中的卡号 难点:银行卡上会有一些干扰项,如何排除这些干扰项,并且打印正确的号码是一个问题 最终效果如上图 实现这样的功能需要以下几个步骤…

实战1-银行卡号识别

项目来源:opencv入门

项目目的:识别传入的银行卡照片中的卡号

难点:银行卡上会有一些干扰项,如何排除这些干扰项,并且打印正确的号码是一个问题

在这里插入图片描述

最终效果如上图

实现这样的功能需要以下几个步骤:

  1. 首先必须有与银行卡中卡号数字基本一样的数字模板,将模板中的数字提取出来并存储起来(0-9)
  2. 将需要检测的银行卡图片中的数字提取出来
  3. 将银行卡的数字与模板数字一一对比,最终找到一个匹配度最高的数字,并把数字标注上

整个思路很简单,但是难点就在于如何将图片处理得更加容易让计算机识别数字,所以整个项目要围绕着图片得的处理来做

第一步-提取数字模板

这是事先准备好的数字模板

在这里插入图片描述

接下来要将图片中的数字都找到,也就是找到各个数字在整个图片上的像素点坐标(轮廓)

首先得到图片的灰度图,再进行二值化处理(这一切都是为了让图片中的数字更易于识别)

# 灰度图
ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值图像
ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]#超过阈值部分取maxval ( 最大值 ),否则取0

然后会得到这样的图像
在这里插入图片描述

好了,现在图片已经很清晰了,不需要再进行其它的处理了,直接将其提取

那怎么提取呢?

可以通过cv2.findContours()找到数字的轮廓

函数 cv2.findContours() 有三个参数,第一个是输入图像,第二个是 轮廓检索模式,第三个是轮廓近似方法。返回值有三个,第一个是图像,第二个 是轮廓,第三个是(轮廓的)层析结构。轮廓(第二个返回值)是一个 Python 列表,其中存储这图像中的所有轮廓。每一个轮廓都是一个 Numpy 数组,包 含对象边界点(x,y)的坐标。

注意新版本中这个api的返回值有变化

返回两个参数contours和 hierarchy,contours就是每个数字的轮廓数组,包含边界点的坐标

其中cv2.RETR_EXTERNAL是获取外轮廓

contours, hierarchy = cv2.findContours(ref.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

接下来可以将轮廓画出来看看

会用到cv2.drawContours()函数

函数 cv2.drawContours() 可以被用来绘制轮廓。它可以根据你提供 的边界点绘制任何形状。它的第一个参数是原始图像,第二个参数是轮廓,一 个 Python 列表。第三个参数是轮廓的索引(在绘制独立轮廓是很有用,当设置 -1时绘制所有轮廓)。接下来的参数是轮廓的颜色和厚度等。

cv2.drawContours(img,contours,-1, (0, 0, 255), 3)

看下效果

在这里插入图片描述

好,现在轮廓都找到了,并且我们也有了轮廓的坐标,这个时候我们应该将每个数字的像素点位置都存起来(并不是将图片分割!,整个图片仍然没有任何变化)

好,现在有一个要注意的点,那就是我们在上面得到的contours数组并不是按图片中各个数字从左到右排列的,也就是说数组中第一个坐标可能是图片中8的坐标,那这个时候我们就必须对数组进行排序,排序顺序就是从左到右存

那排序怎么实现呢,其实就是根据x坐标从小到大排序就行了

排完序之后,contours中0下标存的就是数字0的模板,这里很好的利用了数组下标的优点

好的,排序完之后,我们就可以来存这个数字的模板了

思路是遍历contours数组,得到每个模板的坐标以及宽高,利用x+w就能得到图片的x轴范围,y+h就能得到y轴的范围,把他们存起来就得到一个数字的模板了

digits = {}
#遍历每一个轮廓
for (i,c) in enumerate(contours):#计算外接矩形并resize合适的大小(x, y, w, h) = cv2.boundingRect(c)# cv2.rectangle(img,(x,y),(x + w, y + h),(0, 0, 255), 2)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))

一个是9x3的矩阵,一个是5x5

下面对图像进行处理,老规矩,取灰度图

在这里插入图片描述

然后进行礼帽处理,目的是为了突出更明亮的区域

tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)

在这里插入图片描述

接下来再用 Sobel核子对图片进行卷积,目的的为了得到图像梯度,也就是边缘检测

我们现在要做的是把可能为数字的区域都找出来

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")

在这里插入图片描述

上图看上去更加模糊了,但是数字和非数字区域的明亮度变了

好的,接下来可以通过闭操作(先膨胀,再腐蚀),将数字连起来(是为了最后找到数字区域,因为卡号是4个数字连在一起的,我们把4个数字的区域找出来)

变成这样

在这里插入图片描述

再来一次阈值操作

thresh = cv2.threshold(gradX, 0, 255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

变成这样

在这里插入图片描述

矩形区域好像白色没有填满,再来一次闭操作

在这里插入图片描述

ok了,现在疑似数字的区域都很明显了吧,那下一步就是将这个区域进行排除,找到真正为银行卡号的区域,其他的区域就不要了

那怎么做呢?我们先把他们的轮廓都找出来,然后判断这些轮廓的宽度,符合银行卡号区域宽的的留下,不符合的去掉就可以了

在这里插入图片描述

# 计算轮廓
contours_, hierarchy_ = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = contours_
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))

得到卡号轮廓后,同样对其从左至右排序

好了,那接下来干嘛呢,我们刚刚得到的是四个数字组成的区域的轮廓,这个时候我们应该遍历这些区域,得到里面的四个数字的轮廓

同样也是个遍历操作

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)

会得到四个这样的组

在这里插入图片描述

然后就获取这个组的轮廓,就像第一步骤一样,将数字提取出来就可以了

#计算每一组的轮廓digitCnts, hierarchy = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# 从左到右排序digitCnts = myutils.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)# print('result',result)# 获取匹配度最高的数值(_, score, _, _) = cv2.minMaxLoc(result)scores.append(score)print("scores",scores)# 得到最合适的数字groupOutput.append(str(np.argmax(scores)))print('groupOutput',groupOutput)

完成上述步骤之后,我们的groupOutput就存放了我们识别出来的银行卡号了,我们只需要在图片上将卡号绘制出来就可以了

  # 画出来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)

最终效果如下

在这里插入图片描述


好了,以上就是此小项目的实现过程

总结:这是我学cv的第一个小实战项目,确实感觉蛮有意思的,学之前觉得这个东西很神奇,学习之后会发现其实一切都是按照逻辑一步步来的,没有那么"高大上",继续努力吧

http://www.yayakq.cn/news/435331/

相关文章:

  • 公司网站开发费用计入什么科目新网站seo外包
  • 丹东做网站公司wordpress 查看文章
  • 织梦移动网站模板哪里的郑州网站建设
  • 石家庄信息门户网站制作费用抖音企业推广费用
  • 网站快照明天更新是什么情况建筑网官网平台
  • 南京哪家网站建设好小城市做网站
  • 免费建站系统个人泉州做网站优化
  • 做网站用jsp还是html在Vs中做网站接口
  • 网站可以不备案php双语网站源码
  • 昌吉网站建设公司企业展厅设计公司大型
  • 制作网站是什么专业郑州高端网站建设团队
  • 购买域名后怎么做网站省建设厅官网
  • html5网站开发公司站长之家
  • 建站网站推荐生成短链接的工具
  • 网站空间 上传程序深圳建立网站营销
  • 北仑做网站网站与客户端的区别吗
  • 湖州市吴兴区建设局网站做阿里巴巴企业网站
  • 怎么做像小刀网一样的网站品牌建设内容
  • 论坛网站模板下载大唐集团电子商务平台
  • 腕表手表网站网上如何推广产品
  • 商丘网站优化公司wordpress更新定位插件
  • 移动网站建设公司wordpress还原回收站
  • 域名交易网站哪个好东莞企业网站哪家好
  • 洛阳做网站哪家专业公众号 wordpress
  • 网站如何做信息表网站突然不能访问
  • 做网站开发工具哪个好广西住房和城乡建设厅继续教育网
  • 深圳网站设计哪家如何做网站logo 设置平滑
  • 公司网站设计维护牧和邻宠物网站建设
  • 网站创建方法寿光网站建设报价
  • 网站关键词怎么做排名怎样用网站做淘宝客推广