一、素材:

需要模板,输入模板必须带有所有的数字,且字体与识别的银行卡号一样

二、思路步骤:

首先把模板中的数字单个分离开,再提取银行卡上的ROI,再将两者的二值图像进行模板匹配,确定出每一个数字,即实现了银行卡号识别。

1、模板

(1)读取模板图像,将其转为灰度图,并且二值化。

(2)检测出模板图像中的数字轮廓;画出数字轮廓。

(3)将模板中的数字轮廓按照 x 方向的坐标大小进行排序,匹配对应的数字,并把轮廓定义为resize统一大小。

(4)将每个数字制成一个模板

2、银行卡

(1)读取银行卡图像,转为灰度图像;

(2)定义卷积核,通过顶帽操作——原图像与开操作之间的差值图像,突出明亮的区域;

(3)利用Sobel算子进行边缘检测

(4)Sobel算子运算后的图像进行闭操作

(5)为提取出对应数字那几块区域,可以通过闭操作,连接数字,闭操作后的图像进行二值化(threshold);

(6)目标区域内部未填充完全,再通过闭操作连通区域;

(7)遍历轮廓,根据目标轮廓的特征,筛选出符合的轮廓;

(8)画出轮廓

(9)对轮廓进行筛选得出ROI(根据数字区域的W/H;以及图像大小范围)

(10)对ROI进行排序

(11)提取ROI中的每一位数字进行模板匹配,和模板中的数字进行模板匹配,选出最相近的数字图像;

3、上代码

import cv2
import  numpy as np
import imutils
from imutils import contoursfilepath = 'D:\\openCVImage\\bankCard'def cv_show(name,img):cv2.imshow(name,img)cv2.waitKey(0)cv2.destroyAllWindows()#处理模板
def temp_deal():# 读取模板图像tempImage=cv2.imread(filepath+'\\temp.png')cv_show("temp",tempImage)# 转换灰度图,颜色改变函数tempGray = cv2.cvtColor(tempImage,cv2.COLOR_BGR2GRAY)# 二值化处理,图像阈值函数,像素值超过127变成0,否则变成255  反二值化,高亮突出数字ret,tempBinary=cv2.threshold(tempGray,127,255,cv2.THRESH_BINARY_INV)#image_Binary = cv2.threshold(image_Gray, 177, 255, cv2.THRESH_BINARY_INV)[1]   # 转换为二值化图像,[1]表示返回二值化图像,[0]表示返回阈值177cv_show("tempBinary",tempBinary)# 返回轮廓信息和轮廓层数contours,hierarchy = cv2.findContours(tempBinary.copy(),cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 轮廓检测。第1个参数是二值图。第2个参数检测最外层轮廓,第3个参数保留轮廓终点坐标# 绘制轮廓drawTemp=tempImage.copy()# 复制一份原图像作为画板,不能在原图上画,不然原图会改变res=cv2.drawContours(drawTemp,contours,-1,(0,0,255),2)#"-1"是指在画板上画出所有轮廓信息,红色,线宽为2cv_show("drawTempImage",res)#模板轮廓排序#详细解释参考:使用Python和OpenCV对轮廓进行排序(从左到右,自上而下) # 原理求每一个轮廓的外接矩形也就是轮廓拟合,根据返回的左上坐标点,就能判断出轮廓的位置,再排序# boxing中存放每次计算轮廓外接矩形得到的x、y、w、h,它的shape为(10,4)。cnt存放每一个轮廓#轮廓排序核心思想为先求出每个轮廓的外接矩形框,然后通过对外接框按照x或y坐标排序进⽽来实现对轮廓的排序.refCnts = imutils.contours.sort_contours(contours, method="left-to-right")[0]    # 排序,从左到右,从上到下digits = {}#遍历每一个轮廓for(i,c) in enumerate(refCnts): #返回轮廓下标和对应的轮廓值# 计算外接矩形并且resize成合适大小(x,y,w,h) = cv2.boundingRect(c)# 轮廓拟合,中存放的是每个轮廓1 2 3 。。。。的最小矩形信息roi = tempBinary[y:y+h,x:x+w]# tempBinary中依次保存的是高和宽,即(y,x)# 将每个区域对应一个数字roi = cv2.resize(roi,(55,85))# roi区域统一大小,根据自己需求来定digits[i] = roireturn digits

#处理待识别银行卡图片
def bankCard_deal(digits):# 初始化卷积核rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,3))myKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))img = cv2.imread(filepath+"\\card2.png")cv_show("img", img)img = imutils.resize(img, width=300)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 礼帽操作,突出更明亮的区域tophat=cv2.morphologyEx(gray,cv2.MORPH_TOPHAT,rectKernel)cv_show("tophat",tophat)#利用Sobel算子进行边缘检测gradX=cv2.Sobel(tophat,ddepth=cv2.CV_32F,dx=1,dy=0,ksize=-1)gradY = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=0, dy=1, ksize=-1)gradX=np.absolute(gradX)minVal = np.min(gradX)maxVal = 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("gradXclose",gradX)thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]cv_show('threshImg', thresh)# 再来一个闭操作thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, myKernel)cv_show('gradXclose2', thresh)# 计算轮廓threshCnts, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)cnts = threshCntscur_img = img.copy()cv2.drawContours(cur_img, cnts, -1, (0, 0, 255), 2)cv_show('imgCopy', cur_img)locs = []# 遍历轮廓,提取轮廓,需要尝试for (i, c) in enumerate(cnts):# 计算矩形(x, y, w, h) = cv2.boundingRect(c)ar = w / float(h)# 选择合适的区域,根据实际任务来,这里的基本都是四个数字一组# [(454, 213, 110, 29), (308, 211, 109, 31), (171, 211, 98, 31), (18, 211, 107, 31)]if 2.5 < ar < 5.0:if (40 < w < 85) and (10 < h < 20):# 符合的留下来locs.append((x, y, w, h))#res = cv2.rectangle(img.copy(), (x, y), (x + w, y + h), (0, 0, 255), 2)  # "-1"是指在画板上画出所有轮廓信息,红色,线宽为2#cv_show("imgRect", res)# 将符合的轮廓从左到右排序locs = sorted(locs, key=lambda o: o[0])output = []#四组轮廓for(i,(gx,gy,gw,gh)) in enumerate(locs ):groupOutput=[]group=gray[gy-5:gy+gh+5,gx-5:gx+gw+5]group=cv2.threshold(group,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1]cv_show("groupThreshold",group)#1234;5678;digitCnts,his=cv2.findContours(group.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)#提取轮廓内数字1,2,3,4digitCnts = imutils.contours.sort_contours(digitCnts, method="left-to-right")[0] # 对找到的轮廓进行排序  按照X轴坐标# 计算每一组中的每一个数值for c in  digitCnts:#每组数字1,2,3,4# 找到当前数值的轮廓,resize成合适的大小(x,y,w,h)=cv2.boundingRect(c)#具体数字roi = group[y:y + h, x:x + w]  # 数字在每组group中的坐标# 将每个区域对应一个数字roi = cv2.resize(roi, (22, 44))  # roi区域统一大小,根据自己需求来定print("roi",roi)scores = []for (digitKey,digitROIValue) in digits.items():#识别图的roi数字与模板里每个数字matchTemplateresult=cv2.matchTemplate(roi,digitROIValue,cv2.TM_CCOEFF_NORMED)# 返回最值及最值位置,在这里我们需要的是最小值的得分,不同的匹配度计算方法的选择不同min_val, max_val, min_loc, max_loc = cv2.minMaxLoc (result)scores.append(max_val)#最大值score = np.abs(scores)  # 有负数出现,统一成正数,相关系数都变成正数flag=Falsefor val in score:if val>0.9:flag=Truebreakif !flag:best_index = np.argmax(score)  # score最大值的下标,匹配度最高best_value = str(best_index)  # 下标就是对应的数字,在字典中,key是0对应的是值为0的图片groupOutput.append(best_value)cv2.rectangle(img,(gx-5,gy-5),(gx+gw+5,gy+gh+5),(0,0,255),1)# 在矩形框上绘图cv2.putText(img, ''.join(groupOutput), (gx, gy - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)output.append(groupOutput)cv_show('img',img)print('数字为:',output)

如有疑问,欢迎进群学习交流 856044792

python-openCV识别银行卡号,车牌同理,代码直接可用相关推荐

  1. Python OpenCV Tesseract实现车牌的检测与识别

    python+opencv+TESSERT-OCR实现车牌的检测与识别_啥都不会的小王的博客-CSDN博客python+opencv+TESSERT-OCR实现车牌的检测与识别开学花了十天时间0基础搞 ...

  2. Python+OpenCV 识别银行卡卡号

    Python+OpenCV 识别银行卡卡号 今天尝试一下用python+OpenCV,使用模板匹配的方式做个简单地识别银行卡卡号(大部分参考网上的,自己改了一部分,代码写的有点不太好,但是思路很清晰, ...

  3. Python OpenCV识别行人入口进出人数统计

     程序示例精选 Python OpenCV识别行人入口进出人数统计 如需安装运行环境或远程调试,见文章底部微信名片,由专业技术人员远程协助! 前言 这篇博客针对<Python OpenCV识别行 ...

  4. 简单的python画图代码_python opencv如何实现简易画图板 python opencv实现简易画图板代码...

    python opencv如何实现简易画图板?本篇文章小编给大家分享一下python opencv实现简易画图板代码,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 代码如下 ...

  5. 【python ++ opencv + pytorch 】车牌提取、分割、识别

    话不多说,先看最后成果图(如果想要全部工程,文章最后我会把github链接放上): 可以看到最终的识别车牌号码是:苏G99999. 其实前年冬天偶然想着用c++来做一个小项目,然后就用 c++ ope ...

  6. 【python + opencv + pytorch】车牌提取、分割、识别 pro版

    老规矩,先看最后成果图(如果想要全部工程,文章最后我会把github链接放上) 1.分割车牌 2.分割字符 3.识别字符 最终识别的车牌号码是:浙F99999 整个车牌识别分五步: 1.一个分割车牌的 ...

  7. 使用Python+OpenCV+GAN实现车牌图像增强

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自|AI算法与图像处理 在好莱坞的犯罪电影中,我们经常看到侦 ...

  8. python opencv识别点个数_python+OpenCV 特征点检测

    1.Harris角点检测 Harris角点检测算法是一个极为简单的角点检测算法,该算法在1988年就被发明了,算法的主要思想是如果像素周围显示存在多于一个方向的边,我们认为该点为兴趣点.基本原理是根据 ...

  9. 部分代码_(python openCV)用71行代码实现获取人脸部分并存储功能

    前言: 今天为大家带来的内容是,(python openCV)用71行代码实现获取人脸部分并存储功能!希望能够帮助到大家,代码较多,部分是用图片方式呈现出来,为了有更好的观赏性和收藏便利. 提示: 本 ...

  10. python图片识别-Python+Opencv识别两张相似图片

    在网上看到python做图像识别的相关文章后,真心感觉python的功能实在太强大,因此将这些文章总结一下,建立一下自己的知识体系. 当然了,图像识别这个话题作为计算机科学的一个分支,不可能就在本文简 ...

最新文章

  1. 【青少年编程竞赛交流】01月份微信图文索引
  2. GoogleNet是怎么理解图像的?谷歌大神教你读懂「神经特征可视化」
  3. [老老实实学WCF] 第二篇 配置WCF
  4. 为什么Domain controller上的time synchronization非常重要?
  5. 为什么parsefloat加出来还是字符串_为什么酒店的包子做的这么好吃?里面加了什么说出来你可能不信...
  6. bzoj 4552: [Tjoi2016Heoi2016]排序
  7. setNeedsDisplay看我就懂!
  8. 2014年考研英语二作文PartB图表题
  9. 网站维护页面_营销型企业网站有哪些功能?
  10. cortex a7 a53_西昊人体工学椅A7开箱测评
  11. pcie inbound、outbound及EP、RC间的互相訪问
  12. 【协同任务】基于matlab多无人机协同任务【含Matlab源码 1273期】
  13. 【AI PC端算法优化】七,RGB和YUV图像颜色空间互转SSE优化
  14. 并联串联混合的电压和电流_串联谐振和并联谐振的区别
  15. Visual Studio Code——做嵌入式C/C++开发常用的编辑器软件安装及基本使用总结
  16. 2020最新WordPress网站优化教程
  17. 无线通信与编码_MATLAB实现OFDM载波频偏估计_含仿真代码
  18. 使用img标签能使用background-size:conver一样的效果
  19. springboot+基于微信小程序的心理测评与活动管理的设计与实现 毕业设计-附源码191752
  20. 2021全球与中国光纤熔接机市场现状及未来发展趋势

热门文章

  1. 【原】flash图片批量上传处理专用php类。
  2. id 与 name 的区别
  3. Android 之流媒体播放器,广播侧下方这么简单。
  4. vue动态渲染图片,引用路径需要注意的地方
  5. 语音识别一、语音识别介绍
  6. Python入门到精通
  7. php 自动关键词,基于Php实现自动获取关键词的分析
  8. SDCMS131批量安装设置助手
  9. gradle打包流程(一)--- 整体把控
  10. 小米2013校园招聘笔试题