目录

  • 1.项目数据及源码
  • 2.环境配置
    • 2.1.导入工具包
    • 2.2.设置参数
  • 3.模板处理
    • 3.1.转二值图像
    • 3.2.计算轮廓
  • 4.数据处理
    • 4.1.初始化卷积核,图像预处理
    • 4.2.顶帽操作
    • 4.3.Sobel算子进行高通滤波
    • 4.4.闭操作,二值化
    • 4.5.计算轮廓
    • 4.5.过滤轮廓
  • 5.模板匹配
    • 5.1.模板匹配
    • 5.2.打印结果

1.项目数据及源码

可在github下载:

https://github.com/chenshunpeng/Credit-card-digital-identification

2.环境配置

2.1.导入工具包

# imutils是在OPenCV基础上的一个封装,达到更为简结的调用OPenCV接口的目的
from imutils import contours
# 主要用于对多维数组执行计算,极大地简化了向量和矩阵的操作处理
import numpy as np
# argparse 是 python 用于解析命令行参数和选项的标准模块
import argparse
# OpenCV2(OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库)
import cv2
# 导入myutils.py文件里面的方法
import myutils

2.2.设置参数

关于argparse的使用可看:

Python, argparse, and command line arguments(推荐)

python之parser.add_argument()用法——命令行选项、参数和子命令解析器

首先以参数形式设置输入图像和模板的位置,这里参数指定了默认值,因此需要将 required=True 改成 required=False,否则会报错(借鉴:解决报错:设置了默认参数,仍报错:error: the following arguments are required:)

# argparse 模块是 Python 内置的一个用于命令项选项与参数解析的模块,
# argparse 模块可以让人轻松编写用户友好的命令行接口。
# 通过在程序中定义好我们需要的参数,然后 argparse 将会从 sys.argv 解析出这些参数。
# argparse 模块还会自动生成帮助和使用手册,并在用户给程序传入无效参数时报出错误信息。ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image",default='./images/credit_card_03.png', required=False,help="path to input image")
ap.add_argument("-t", "--template",default='./images/ocr_a_reference.png', required=False,help="path to template OCR-A image")
args = vars(ap.parse_args())

3.模板处理

3.1.转二值图像

cv2.threshold()方法可看:CV2简单阈值函数:cv2.threshold()

# 绘图展示
def cv_show(name,img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()# 读取一个模板图像(因为BGR,所以每个像素都是[255 255 255])
img = cv2.imread(args["template"])
cv_show('img',img)
# 转换为灰度图(BGR 到 GRAY)
ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv_show('ref',ref)
# 二值图像(选项为cv2.THRESH_BINARY_INV)
ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]cv_show('ref',ref)
  • 灰度图:在RGB模型中,如果R=G=B时,则彩色表示一种灰度颜色,其中R=G=B的值叫灰度值,因此,灰度图像每个像素只需一个字节存放灰度值(又称强度值、亮度值),灰度范围为0-255。一般常用的是加权平均法来获取每个像素点的灰度值。
  • 二值图:图像的二值图,就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果。
  • 彩色图象:多光谱图象的一种特殊情况,对应于人类视觉的三基色即红、绿、蓝三个波段,是对人眼的光谱量化性质的近似。

可以看到灰度图和二值图占空间较小,是彩色图象(BGR)的三分之一

单步调试(方法可看 :传送门):


原图:

二值图像如下:

3.2.计算轮廓

之后计算这10个数的轮廓,因为这10个轮廓的排列顺序并不一定是按照这个0-9的轮廓对应着来的,我们需要根据每个轮廓左上角的坐标值,先从小到大排序,这样就可以保证在匹配时顺序是对应的(比如 “354” 对应的的确是template中第4,6,5个数字)

# 计算轮廓
#cv2.findContours()函数接受的参数为二值图,即黑白的(不是灰度图),cv2.RETR_EXTERNAL只检测外轮廓,cv2.CHAIN_APPROX_SIMPLE只保留终点坐标
#返回的list中每个元素都是图像中的一个轮廓# ref_, refCnts, hierarchy = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
refCnts, hierarchy = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# -1表示绘制所有轮廓,后面是画笔颜色,画笔大小
# refCnts返回绘制了轮廓的图像
cv2.drawContours(img,refCnts,-1,(0,0,255),3)
cv_show('img',img)
print (np.array(refCnts).shape)
refCnts = myutils.sort_contours(refCnts, method="left-to-right")[0] #排序,从左到右,从上到下
digits = {}

排序前refCnts

排序后refCnts


排序函数sort_contours

boundingBoxes有4个返回值(x,y,h,w),其中凭借 x 即可判断出数字的前后位置关系

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 = 1boundingBoxes = [cv2.boundingRect(c) for c in cnts] #用一个最小的矩形,把找到的形状包起来x,y,h,w(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes), key=lambda b: b[1][i], reverse=reverse))return cnts, boundingBoxes

结果:

之后对应每个数字,resize成合适大小,放入digits数组中制作成模板

# 遍历每一个轮廓
for (i, c) in enumerate(refCnts):# 计算外接矩形并且resize成合适大小(x, y, w, h) = cv2.boundingRect(c)roi = ref[y:y + h, x:x + w]roi = cv2.resize(roi, (57, 88))# 每一个数字对应每一个模板digits[i] = roi

digits数组最后结果:

4.数据处理

4.1.初始化卷积核,图像预处理

首先初始化卷积核,读取输入图像,预处理

# 初始化卷积核
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)

rectKernel:

sqKernel:

图像:

调整大小,转灰度图后:

4.2.顶帽操作

一些形态学操作可看

图像形态学操作之顶帽操作(TopHat)与黑帽操作(BlackHat)

【OPENCV3.3+PYTHON3.6】图像形态学操作之顶帽,黑帽以及形态学梯度

#顶帽操作,突出更明亮的区域
#根据自己指定的核大小进行顶帽操作
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)
cv_show('tophat',tophat)

结果:

4.3.Sobel算子进行高通滤波

一些形态学操作可看:Sobel算子

# ksize:是Sobel算子的大小,即卷积核的大小,必须为奇数,默认值为3(ksize=-1相当于用3*3的)
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")print (np.array(gradX).shape)
cv_show('gradX',gradX)

结果:

4.4.闭操作,二值化

之后2次闭操作(先膨胀,再腐蚀)将数字连在一起,中间可以用THRESH_OTSU进行二值化处理,其优点在于可以自动寻找合适的阈值

#通过闭操作(先膨胀,再腐蚀)将数字连在一起
gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)
cv_show('gradX',gradX)
#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)

第1次闭操作:

二值化处理:

第2次闭操作:

4.5.计算轮廓

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

结果:

4.5.过滤轮廓

之后过滤轮廓,即通过计算所有轮廓外接矩形的大小,找到有价值的数字区域,把这4个区域放入locs列表进行排序

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))# 将符合的轮廓从左到右排序
locs = sorted(locs, key=lambda x:x[0])

locs列表内容:

5.模板匹配

5.1.模板匹配

先把轮廓稍微放大,之后遍历每一个轮廓中的数字,和上面的方法类似,找到每个数字后,在模板中计算每一个得分,得到最合适的数字并画出来:

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)# 计算每一组的轮廓# group_,digitCnts,hierarchy = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)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 = []# 在模板中计算每一个得分for (digit, digitROI) in digits.items():# 模板匹配result = cv2.matchTemplate(roi, digitROI,cv2.TM_CCOEFF)(_, score, _, _) = cv2.minMaxLoc(result)scores.append(score)# 得到最合适的数字groupOutput.append(str(np.argmax(scores)))# 画出来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)

部分结果:


output列表:

5.2.打印结果

# 打印结果
print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
print("Credit Card #: {}".format("".join(output)))
cv2.imshow("Image", image)
cv2.waitKey(0)

结果:

信用卡数字识别(opencv,轮廓计算)相关推荐

  1. 信用卡数字识别—opencv

    信用卡数字识别:就是识别信用卡的卡号,然后将卡号打印出来! 然后对应的数字模板如下图所示: 接下来我们就一步步的分析程序吧 1.导入相关的包 # 导入工具包 from imutils import c ...

  2. 信用卡数字识别OpenCV实现(含代码)【DataWhale项目】

    参考课程:Opencv计算机视觉实战(Python版) 基本材料准备 一张仅含数字的图像作为模板. 一张银行卡的图像作为检测样本. 代码编写或者阅读的习惯 常打断点 勤展示数组的shape等,以及数组 ...

  3. OpenCV实践小项目(一): 信用卡数字识别

    1. 写在前面 今天整理一个OpenCV实践的小项目, 前几天整理了一篇OpenCV处理图像的知识笔记,后面,就通过一些小项目把这些知识运用到实践中去,一个是加深理解,另一个是融会贯通,连成整体,因为 ...

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

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

  5. (八)OpenCV入门,代码练习,详细注释【信用卡数字识别】【240行】【原创】

    文章目录 信用卡图片 数字模板图片 一.数字模板图片处理步骤 1,读取模板图片 2,灰度处理图片 3,二值化处理图片 4,检测数字轮廓图片 二.识别信用卡图片处理步骤 1,图片信用卡 2,图片灰度处理 ...

  6. 【项目实战】基于python+pycharm+OpenCV的信用卡数字识别

    一.pycharm实现参数配置 直接运行程序会报错: usage: ocr_template_match.py [-h] -i IMAGE -t TEMPLATE ocr_template_match ...

  7. python信用卡客户_Python开发之基于模板匹配的信用卡数字识别功能

    环境介绍 python 3.6 + OpenCV 3.4.1.15 原理介绍 首先,提取出模板中每一个数字的轮廓,再对信用卡图像进行处理,提取其中的数字部分,将该部分数字与模板进行匹配,即可得到结果. ...

  8. opencv-实战-信用卡数字识别

    信用卡-数字识别 功能说明 简要步骤 先得到轮廓的外接矩形 然后对模板和图像进行轮廓检测得到外轮廓 例如先对4进行外接轮廓检测后再一一和模板里面的一一匹配 处理 先读入图像转入灰度图 对两个图像先re ...

  9. 基于openCV的项目实战1:信用卡数字识别

    目的:识别信用卡卡号: 方法:基于模板匹配: 模板匹配思想:拿4和左边模板进行一一匹配,算一下平方项的差异,恰好4和左边模板中的4差异最小,所以就知道当前的数字是4: 具体步骤: 第一步:找到与你当前 ...

最新文章

  1. 大数据时代:从1.0到3.0 | 专访清华社会学系教授罗家德
  2. es6 promise
  3. gcc的调试调研——gdb
  4. 键盘控制事件应用教程大全
  5. WinCE 修改系统字体 开启ClearType平滑字体
  6. 在静态页面中使用Scss(windows)
  7. [AlwaysOn Availability Groups]排查:AG配置
  8. 【疾病分类】基于matlab LBP果实病害检测分类【含Matlab源码 1714期】
  9. 图解通信原理与案例分析-33:传感器种类以及传感器工作原理详解
  10. W5500以太网控制器芯片(五):实现FTP客户端
  11. 大众点评优略点评。。
  12. 施耐德SoMachine Basic中存在高危漏洞(CVE-2018-7783),可读取目标系统上的任意文件...
  13. 虚幻竞技场3中的配置文件
  14. 平板电脑安装软件_哪个便签可以横屏?平板电脑横屏便签软件推荐
  15. idea设置svn上传或下拉代码
  16. 子平真诠释疑笔记(二)
  17. php htmlpurifier,htmlpurifierPHP过滤库
  18. javascript玩转ElasticSearch(一)
  19. 常见的数据埋点方式介绍
  20. 【动态规划】牛客NC20035打鼹鼠

热门文章

  1. uwb定位系统,室内定位技术
  2. java变短加密解密算法_java----加密/解密常用算法
  3. printf和println和print区别
  4. 【转】国家天文大地网
  5. hadoop 历史版本下载
  6. s19文件反编译成c语言,S19文件反编译器使用说明.ppt
  7. python斐波拉契数列(Fibonacci)
  8. brocade 300 java版本_博科Brocade 300光纤交换机配置zone教程
  9. jQuery框架的介绍以及基本用法--操作dom
  10. 数据技术嘉年华专列10月28日抵达广州,请做好接站准备