python opencv实现信用卡的数字识别

本项目利用python以及opencv实现信用卡的数字识别

前期准备

  • 导入工具包
  • 定义功能函数

模板图像处理

  • 读取模板图像 cv2.imread(img)
  • 灰度化处理 cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
  • 二值化 cv2.threshold()
  • 轮廓 - 轮廓

信用卡图像处理

  • 读取信用卡图像 cv2.imread(img)
  • 灰度化处理 cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
  • 礼帽处理 cv2.morphologyEx(gray,cv2.MORPH_TOPHAT,rectKernel)
  • Sobel边缘检测 cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)
  • 闭操作 cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)
  • 计算轮廓 cv2.findContours
  • 模板检测 cv2.matchTemplate(roi, digitROI,cv2.TM_CCOEFF)

原始数据展示

结果展示

1 前期准备

# 导入工具包
# opencv读取图片的格式为b g r
# matplotlib图片的格式为 r g b
import numpy as np
import cv2
from imutils import contours
import matplotlib.pyplot as plt
%matplotlib inline
# 信用卡的位置
predict_card = "images/credit_card_01.png"
# 模板的位置
template = "images/ocr_a_reference.png"
# 指定信用卡类型
FIRST_NUMBER = {
  "3": "American Express",
  "4": "Visa",
  "5": "MasterCard",
  "6": "Discover Card"
}
# 定义一些功能函数

# 对框进行排序
def sort_contours(cnts, method="left-to-right"):
  reverse = False
  i = 0

  if method == "right-to-left" or method == "bottom-to-top":
    reverse = True

  if method == "top-to-bottom" or method == "bottom-to-top":
    i = 1
  boundingBoxes = [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

# 调整图片尺寸大小
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 image
  if 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

# 定义cv2展示函数
def cv_show(name,img):
  cv2.imshow(name,img)
  cv2.waitKey(0)
  cv2.destroyAllWindows()

2 对模板图像进行预处理操作

读取模板图像

# 读取模板图像
img = cv2.imread(template)
cv_show("img",img)
plt.imshow(img)
<matplotlib.image.AxesImage at 0x2b2e04ad128>

模板图像转灰度图像

# 转灰度图
ref = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv_show("ref",ref)
plt.imshow(ref)
<matplotlib.image.AxesImage at 0x2b2e25d9e48>

转为二值图像

ref = cv2.threshold(ref,10,255,cv2.THRESH_BINARY_INV)[1]
cv_show("ref",ref)
plt.imshow(ref)
<matplotlib.image.AxesImage at 0x2b2e2832a90>

计算轮廓

#cv2.findContours()函数接受的参数为二值图,即黑白的(不是灰度图),cv2.RETR_EXTERNAL只检测外轮廓,cv2.CHAIN_APPROX_SIMPLE只保留终点坐标
#返回的list中每个元素都是图像中的一个轮廓
# 在二值化后的图像中计算轮廓
refCnts,hierarchy = cv2.findContours(ref.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
# 在原图上画出轮廓
cv2.drawContours(img,refCnts,-1,(0,0,255),3)
cv_show("img",img)
plt.imshow(img)
<matplotlib.image.AxesImage at 0x2b2e256f908>

print(np.array(refCnts).shape)
# 排序,从左到右,从上到下
refCnts = sort_contours(refCnts,method="left-to-right")[0]
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

(10,)

3 对信用卡进行处理

初始化卷积核

rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

读取信用卡

image = cv2.imread(predict_card)
cv_show("image",image)
plt.imshow(image)
<matplotlib.image.AxesImage at 0x2b2e294c9b0>

对图像进行预处理操作

# 先对图像进行resize操作
image = resize(image,width=300)
# 灰度化处理
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv_show("gray",gray)
plt.imshow(gray)
<matplotlib.image.AxesImage at 0x2b2e255d828>

对图像礼帽操作

  • 礼帽 = 原始输入-开运算结果
  • 开运算:先腐蚀,再膨胀
  • 突出更明亮的区域
tophat = cv2.morphologyEx(gray,cv2.MORPH_TOPHAT,rectKernel)
cv_show("tophat",tophat)
plt.imshow(tophat)
<matplotlib.image.AxesImage at 0x2b2eb008e48>

用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")
print (np.array(gradX).shape)
cv_show("gradX",gradX)
plt.imshow(gradX)
(189, 300)
<matplotlib.image.AxesImage at 0x2b2e0797400>

对图像闭操作

  • 闭操作:先膨胀,再腐蚀
  • 可以将数字连在一起
gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)
cv_show("gradX",gradX)
plt.imshow(gradX)
<matplotlib.image.AxesImage at 0x2b2e097cc88>

#THRESH_OTSU会自动寻找合适的阈值,适合双峰,需把阈值参数设置为0
thresh = cv2.threshold(gradX, 0, 255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv_show("thresh",thresh)
plt.imshow(thresh)
<matplotlib.image.AxesImage at 0x2b2e24a0dd8>

# 再进行一次闭操作
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel) #再来一个闭操作
cv_show("thresh",thresh)
plt.imshow(thresh)
<matplotlib.image.AxesImage at 0x2b2e25fe748>

计算轮廓

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)
plt.imshow(cur_img)
<matplotlib.image.AxesImage at 0x2b2eb17c780>

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])
output = []

模板匹配

# 遍历每一个轮廓中的数字
for (i, (gX, gY, gW, gH)) in enumerate(locs):
  # initialize the list of group digits
  groupOutput = []

  # 根据坐标提取每一个组
  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 = []
    # 在模板中计算每一个得分
    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)
# 打印结果
print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
print("Credit Card #: {}".format("".join(output)))
cv_show("Image",image)
plt.imshow(image)
Credit Card Type: Visa
Credit Card #: 4000123456789010

<matplotlib.image.AxesImage at 0x2b2eb040748>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • python实现基于SVM手写数字识别功能

    本文实例为大家分享了SVM手写数字识别功能的具体代码,供大家参考,具体内容如下 1.SVM手写数字识别 识别步骤: (1)样本图像的准备. (2)图像尺寸标准化:将图像大小都标准化为8*8大小. (3)读取未知样本图像,提取图像特征,生成图像特征组. (4)将未知测试样本图像特征组送入SVM进行测试,将测试的结果输出. 识别代码: #!/usr/bin/env python import numpy as np import mlpy import cv2 print 'loading ...'

  • Python使用gluon/mxnet模块实现的mnist手写数字识别功能完整示例

    本文实例讲述了Python使用gluon/mxnet模块实现的mnist手写数字识别功能.分享给大家供大家参考,具体如下: import gluonbook as gb from mxnet import autograd,nd,init,gluon from mxnet.gluon import loss as gloss,data as gdata,nn,utils as gutils import mxnet as mx net = nn.Sequential() with net.nam

  • python tensorflow基于cnn实现手写数字识别

    一份基于cnn的手写数字自识别的代码,供大家参考,具体内容如下 # -*- coding: utf-8 -*- import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data # 加载数据集 mnist = input_data.read_data_sets('MNIST_data', one_hot=True) # 以交互式方式启动session # 如果不使用交互式session,则在启动s

  • 机器学习python实战之手写数字识别

    看了上一篇内容之后,相信对K近邻算法有了一个清晰的认识,今天的内容--手写数字识别是对上一篇内容的延续,这里也是为了自己能更熟练的掌握k-NN算法. 我们有大约2000个训练样本和1000个左右测试样本,训练样本所在的文件夹是trainingDigits,测试样本所在的文件夹是testDigits.文本文件中是0~9的数字,但是是用二值图表示出来的,如图.我们要做的就是使用训练样本训练模型,并用测试样本来检测模型的性能. 首先,我们需要将文本文件中的内容转化为向量,因为图片大小是32*32,所以

  • Python(TensorFlow框架)实现手写数字识别系统的方法

    手写数字识别算法的设计与实现 本文使用python基于TensorFlow设计手写数字识别算法,并编程实现GUI界面,构建手写数字识别系统.这是本人的本科毕业论文课题,当然,这个也是机器学习的基本问题.本博文不会以论文的形式展现,而是以编程实战完成机器学习项目的角度去描述. 项目要求:本文主要解决的问题是手写数字识别,最终要完成一个识别系统. 设计识别率高的算法,实现快速识别的系统. 1 LeNet-5模型的介绍 本文实现手写数字识别,使用的是卷积神经网络,建模思想来自LeNet-5,如下图所示

  • Python tensorflow实现mnist手写数字识别示例【非卷积与卷积实现】

    本文实例讲述了Python tensorflow实现mnist手写数字识别.分享给大家供大家参考,具体如下: 非卷积实现 import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data data_path = 'F:\CNN\data\mnist' mnist_data = input_data.read_data_sets(data_path,one_hot=True) #offline da

  • kNN算法python实现和简单数字识别的方法

    本文实例讲述了kNN算法python实现和简单数字识别的方法.分享给大家供大家参考.具体如下: kNN算法算法优缺点: 优点:精度高.对异常值不敏感.无输入数据假定 缺点:时间复杂度和空间复杂度都很高 适用数据范围:数值型和标称型 算法的思路: KNN算法(全称K最近邻算法),算法的思想很简单,简单的说就是物以类聚,也就是说我们从一堆已知的训练集中找出k个与目标最靠近的,然后看他们中最多的分类是哪个,就以这个为依据分类. 函数解析: 库函数: tile() 如tile(A,n)就是将A重复n次

  • python opencv实现信用卡的数字识别

    本项目利用python以及opencv实现信用卡的数字识别 前期准备 导入工具包 定义功能函数 模板图像处理 读取模板图像 cv2.imread(img) 灰度化处理 cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 二值化 cv2.threshold() 轮廓 - 轮廓 信用卡图像处理 读取信用卡图像 cv2.imread(img) 灰度化处理 cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 礼帽处理 cv2.morphologyEx(gray

  • Python+OpenCV实现信用卡数字识别的方法详解

    目录 一.模板图像处理 二.信用卡图片预处理 一.模板图像处理 (1)灰度图.二值图转化 template = cv2.imread('C:/Users/bwy/Desktop/number.png') template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY) cv_show('template_gray', template_gray) # 形成二值图像,因为要做轮廓检测 ret, template_thresh = cv2.thre

  • python+opencv实现的简单人脸识别代码示例

    # 源码如下: #!/usr/bin/env python #coding=utf-8 import os from PIL import Image, ImageDraw import cv def detect_object(image): '''检测图片,获取人脸在图片中的坐标''' grayscale = cv.CreateImage((image.width, image.height), 8, 1) cv.CvtColor(image, grayscale, cv.CV_BGR2GR

  • Python OpenCV招商银行信用卡卡号识别的方法

    学在前面 从本篇博客起,我们将实际完成几个小案例,第一个就是银行卡号识别,预计本案例将写 5 篇左右的博客才可以完成,一起加油吧. 本文的目标是最终获取一套招商银行卡,0~9 数字的图,对于下图的数字,我们需要提取出来,便于后续模板匹配使用.不过下图中找到的数字不完整,需要找到尽量多的卡片,然后补齐这些数字. 提取卡片相关数字 先对上文中卡片中的数字进行相关提取操作,加载图片的灰度图,获取目标区域.在画板中模拟一下坐标区域,为了便于进行后续的操作. 具体代码如下: import cv2 as c

  • 如何基于opencv实现简单的数字识别

    目录 前言 要解决的问题 解决问题的思路 总结 前言 由于自己学识尚浅,不能用python深度学习来识别这里的数字,所以就完全采用opencv来识别数字,然后在这里分享.记录一下自己在学习过程中的一些所见所得和所想 要解决的问题 这是一个要识别的数字,我这里首先是对图像进行一个ROI的提取,提取结果就仅仅剩下数字,把其他的一些无关紧要的要素排除在外, 这是ROI图片,我们要做的就是识别出该照片中的数字, 解决问题的思路 1.先把这个图片中的数字分割,分割成为5张小图片,每张图片包含一个数字,为啥

  • caffe的python接口之手写数字识别mnist实例

    目录 引言 一.数据准备 二.导入caffe库,并设定文件路径 二.生成配置文件 三.生成参数文件solver 四.开始训练模型 五.完成的python文件 引言 深度学习的第一个实例一般都是mnist,只要这个例子完全弄懂了,其它的就是举一反三的事了.由于篇幅原因,本文不具体介绍配置文件里面每个参数的具体函义,如果想弄明白的,请参看我以前的博文: 数据层及参数 视觉层及参数 solver配置文件及参数 一.数据准备 官网提供的mnist数据并不是图片,但我们以后做的实际项目可能是图片.因此有些

  • python+opencv实现动态物体识别

    注意:这种方法十分受光线变化影响 自己在家拿着手机瞎晃的成果图: 源代码: # -*- coding: utf-8 -*- """ Created on Wed Sep 27 15:47:54 2017 @author: tina """ import cv2 import numpy as np camera = cv2.VideoCapture(0) # 参数0表示第一个摄像头 # 判断视频是否打开 if (camera.isOpened()

  • 使用python svm实现直接可用的手写数字识别

    目录 python svm实现手写数字识别--直接可用 1.训练 1.1.训练数据集下载--已转化成csv文件 1.2 .训练源码 2.预测单张图片 2.1.待预测图像 2.2.预测源码 2.3.预测结果 python svm实现手写数字识别--直接可用 最近在做个围棋识别的项目,需要识别下面的数字,如下图: 我发现现在网上很多代码是良莠不齐,-真是一言难尽,于是记录一下,能够运行成功并识别成功的一个源码. 1.训练 1.1.训练数据集下载--已转化成csv文件 下载地址 1.2 .训练源码 t

  • python+opencv轮廓检测代码解析

    首先大家可以对OpenCV有个初步的了解,可以参考:简单了解OpenCV 轮廓(Contours),指的是有相同颜色或者密度,连接所有连续点的一条曲线.检测轮廓的工作对形状分析和物体检测与识别都非常有用. 在轮廓检测之前,首先要对图片进行二值化或者Canny边缘检测.在OpenCV中,寻找的物体是白色的,而背景必须是黑色的,因此图片预处理时必须保证这一点. import cv2 #读入图片 img = cv2.imread("1.png") # 必须先转化成灰度图 gray = cv2

随机推荐