任务:
读取信用卡上数字
所给图片:

模板

思路
大体想得就是进行模板匹配,让信用卡上的数字和我们的模板图片进行匹配,中间会进行一系列的处理操作,轮廓处理,模板匹配,闭运算,等等。

代码部分

第一部分就是导入相关的东西,其中myutils是自己写的.py文件,我当时写的时候,没有下载imutils这个库,可以直接pip install imutils下载。

import numpy as np
import argparse
import cv2
import imutils
from imutils import contours
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 ORC-A image")
args=vars(ap.parse_args())
print(args)#绘图显示
def cv_show(name,img):cv2.imshow(name,img)cv2.waitKey()cv2.destroyAllWindows()

我们先处理好模板,首先要描绘模板的轮廓,轮廓处理(模板处理的条件是先转成灰度图在转成二值图像,一般我们做轮廓检测,都是处理的二值图像)

#读取一个模板图像
img=cv2.imread(args["template"])
cv_show('img',img)
#转成灰度图
ref=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv_show("ref",ref)
#转成二值图像,一般我们做轮廓检测,都是处理的二值图像
#cv2.threshold(src, thresh, maxval, type[, dst]) 四个参数分别是图像源,阈值,最大值,类型)
ref=cv2.threshold(ref,10,255,cv2.THRESH_BINARY_INV)[1]#返回第二个值
#print(ref)
cv_show("ref",ref)
#计算轮廓
#cv2.findContours(img,mode,method),mode:轮廓检索模式,method:轮廓逼近方法
#cv2.findContours()函数接受的值为二值图,cv2.RETR_EXTERNAL,代表只检测外轮廓
# cv2.CHAIN_APPROX_SIMPLE代表只保留终点坐标
#返回的list中每个元素都是图像中的一个轮廓
refCnts,hierarchy=cv2.findContours(ref.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分# 传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
# 注意需要copy,要不原图会变
cv2.drawContours(img,refCnts,-1,(0,0,255),3)#-1代表画出所有轮廓
cv_show("img",img)
print(np.array(refCnts).shape)
#对轮廓从左到右进行排序
refCnts = myutils.sort_contours(refCnts,method="left-to-right")[0]
digits = {}
#设置字典存储模板轮廓
#遍历每一个轮廓
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

下面处理我们的图片

# 形态学操作,礼帽+闭操作可以突出明亮区域,但并不是非得礼帽+闭操作#初始化卷积核
#初始化卷积核,根据实际任务指定大小,不一定非要3x3
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)
#ksize=-1相当于用3*3的,也不一定分别算x,y,再求和,这里只用x的效果更好gradx=np.absolute(gradx)#数组的值求绝对值
#归一化
#因为有的值会大于255,所以进行一下归一化
(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("grandx",gradx)#通过闭操作(先膨胀再腐蚀)将数字连在一起
gradx=cv2.morphologyEx(gradx,cv2.MORPH_CLOSE,rectKernel)
cv_show('grandx',gradx)#cv2.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)

下面就到计算轮廓,该写的标注都在代码里

#计算轮廓
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))
#将符合条件的轮廓从左到右排序
#x:x[]字母可以随意修改,排序方式按照中括号[]里面的维度进行排序,[0]按照第一维排序,[2]按照第三维排序
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)#计算每一组的轮廓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=[]#在模板计算每一个得分# digits的digit正好是数值0,1,...,9;digitROI是每个数值的特征表示for (digit, digitROI) in digits.items():# 进行模板匹配, res是结果矩阵res = cv2.matchTemplate(roi, digitROI, cv2.TM_CCOEFF)  # 此时roi是X digitROI是0 依次是1,2.. 匹配10次,看模板最高得分多少#在这里结果矩阵就一个数,因为模板长宽相同#Max_score = cv2.minMaxLoc(res)[1]  # 返回4个,取第二个最大值Maxscorescores.append(Max_score)  # 10个最大值#得到最合适的数字np.argmax(scores)#np.argmax()是numpy中获取array的某一个维度中数值最大的那个元素的索引groupOutput.append(str(np.argmax(scores)))#画出来# 左上角,右下角cv2.rectangle(image,(gx-5,gy-5),(gx+gw+5,gy+gh+5),(0,0,255),1)#putText参数:图片,添加的文字,左上角坐标,字体,字体大小,颜色,字体粗细cv2.putText(image, "".join(groupOutput), (gx, gy - 15),cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)# 2.5 得到结果output.extend(groupOutput)print("groupOutput:", groupOutput)# cv2.imshow("Output_image_"+str(i), image)# cv2.waitKey(0)
# 3.打印结果
print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
print("Credit Card #: {}".format("".join(output)))
cv2.imshow("Output_image", image)
cv2.waitKey(0)

myutils.py代码

import cv2
# 对轮廓进行排序
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 = 1# 计算外接矩形 boundingBoxes是一个元组boundingBoxes = [cv2.boundingRect(c) for c in cnts] #用一个最小的矩形,把找到的形状包起来x,y,h,w# sorted排序(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),key=lambda b: b[1][i], reverse=reverse))return cnts, boundingBoxes  # 轮廓和boundingBoxess
def resize(image, width=None, height=None, inter=cv2.INTER_AREA):dim = None(h, w) = image.shape[:2]if width is None and height is None:return imageif width is None:r = height / float(h)dim = (int(w * r), height)else:r = width / float(w)dim = (width, int(h * r))resized = cv2.resize(image, dim, interpolation=inter)return resized

最后展示


参考视频
https://www.bilibili.com/video/BV1oJ411D71z?p=9

项目实战之信用卡数字提取相关推荐

  1. 项目实战之信用卡数字识别

    项目要求 要求输入一张信用卡图片后能够识别出卡号的位置,并且识别出卡号是多少 输出图像如下图所示 实战 ocr_match_template.py import cv2 import numpy as ...

  2. 金融风控项目实战-银行信用卡流失预测模型_基于ANN神经网络_金融培训_论文科研_毕业设计

    业务背景 根据央行公布的数据显示,全国性银行信用卡和借贷合一卡的发卡量增速从2017年同比增速26.35%的高点逐年下降,截至2020年同比增速降至4.26%.银行信用卡发卡增速明显放缓的背景下,预防 ...

  3. OpenCV计算机视觉实战(Python)_09-项目实战:信用卡数字识别( Jupyter notebook实现)

    1.介绍 从一个银行卡中识别其中的银行卡号: 2. 流程 读图 , 灰度图 , 二值化 使用模板匹配方式对模板,以及输入图像进行轮廓检测(检测外轮廓). 得到当前轮廓的外接矩形. 将模板中的外接矩形切 ...

  4. python写一个游戏多少代码-Python项目实战之猜数字游戏(含实现代码)

    猜数字游戏,旨在提高初学者对 Python 变量类型以及循环结构的使用. 此游戏的游戏规则如下:程序随机内置一个位于一定范围内的数字作为猜测的结果,由用户猜测此数字.用户每猜测一次,由系统提示猜测结果 ...

  5. 深度学习项目实战——手写数字识别项目

    摘要 本文将介绍的有关于的paddle的实战的相关的问题,并分析相关的代码的阅读和解释.并扩展有关于的python的有关的语言.介绍了深度学习步骤: 1. 数据处理:读取数据 和 预处理操作 2. 模 ...

  6. Opencv项目实战之信用卡识别

    任务要求 学了这么久opencv,不做个实战项目怎么行(手动狗头)

  7. react 项目实战(六)提取布局组件

    重复代码是混乱的根源!,本篇文章我们来继续消灭重复代码. 目标 细心的同学应该能发现:每一个Page组件(/src/pages下的组件)的render方法都拥有相似的jsx结构,比如: render ...

  8. Opencv项目实战-信用卡数字识别

    Opencv项目实战:信用卡数字识别 导入库,定义展示函数 import cv2 import numpy as np from imutils import contours import myut ...

  9. Python项目实战:数据可视化与股票数据分析-关东升-专题视频课程

    Python项目实战:数据可视化与股票数据分析-333人已学习 课程介绍         本视频内容包括使用Matplotlib绘制图表.MySQL数据库.Python访问数据库和Lambda表达式. ...

最新文章

  1. 第十章 基本数据结构——栈和队列
  2. java中tomcat检测_eclipse+tomcat测试JSP
  3. 局域网实现VLAN实例
  4. android.hardware.camera2使用指南
  5. 十大滤波算法程序大全
  6. 8.var目录下的文件和目录详解
  7. YBTOJ洛谷P2387: 魔法森林(LCT)
  8. 【信号】函数kill、raise、abort、alarm
  9. 卸载idea_IDEA 不为人知的 5 个骚技巧!真香!
  10. Zookeeper的内存数据和持久化
  11. 如何将先验知识注入推荐模型
  12. 今天和朋友去参观一家做电商创业公司
  13. 数据库系统教程第三版施伯乐
  14. [Pytorch系列-33]:数据集 - torchvision与CIFAR10/CIFAR100详解
  15. as常用固定搭配_500个英语语法固定搭配
  16. SUBMAIL API如何帮助您构建企业云通信平台?
  17. 什么是VB.NET?
  18. Docker Windows桌面版安装 Windows家庭版伪装成专业版系统
  19. 在ubuntu中运行sudo apt-get update报错The following signatures couldn‘t be verified because the public key
  20. 耶鲁大学宣布推翻了进化论?科学界发文,“进化随机性”或被证伪

热门文章

  1. 英文疗伤好歌——【世界杯主题曲《You Raise Me Up 》】中文《你激励了我》
  2. 用 Python 替代Excel 表格,轻而易举实现办公自动化
  3. 如何基于Java实现一套特色民宿平台系统?
  4. 带有验证码的爆破(包含Burp suite工具爆破)
  5. 基于Stm32的4G模块实现内网透传通信(代码后附)
  6. 类似matlab安卓,【Android 杂货派】理科生神器 Matlab、联通网络解锁助手、高颜值的糖果色任务列表等上新...
  7. 印度男人居然喜欢遭到“棒打”?
  8. Python计算狄利克雷分布(Dirichlet Distribution)密度估计
  9. 常见背景音(不定期更新)
  10. Cadence添加工艺库 | 虚拟机与宿主机共享文件