Python银行卡基于open-cv的OCR识别

作者: 浪漫矢志不渝 | 来源:发表于2021-12-15 14:09 被阅读0次

在学习人工智能的路上,自己接触到了很多比较有意思的小demo,感觉比较有意思的也就拿出来作为分享了,这里主要是应用open-cv的一些特性进行银行卡号的识别。

主要代码
# python ocr_template_match.py 执行脚本文件
from imutils import contours
import numpy as np
import imutils
import cv2

# 定义了一个字典 FIRST_NUMBER  ,它将第一个数字映射到相应的信用卡类型。
FIRST_NUMBER = {
    "3": "American Express",
    "4": "Visa",
    "5": "MasterCard",
    "6": "Discover Card"
}
# 参考数字图像,用于匹配
# 灰度化及二值化
ref = cv2.imread("images/ocr_a_reference.png")
ref = cv2.cvtColor(ref, cv2.COLOR_BGR2GRAY)
ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]
# 查找轮廓,从左往右排序
refCnts = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL,
                           cv2.CHAIN_APPROX_SIMPLE)
refCnts = imutils.grab_contours(refCnts)
refCnts = contours.sort_contours(refCnts, method="left-to-right")[0]
digits = {}
# 对于其中每一个轮廓进行提循环,i为数字名称,c为轮廓,我们将每个数字0-9(字典键)与第30行的每个roi   图像(字典值)相关联 。
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
# 初始化几个结构化内核,构造了两个这样的内核 - 一个矩形和一个正方形。我们将使用矩形的一个用于Top-hat形态运算符,将方形一个用于关闭操作。
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

# 加载信用卡图像
image = cv2.imread("images/credit_card_05.png")
image = imutils.resize(image, width=300)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 执行Top-hat形态操作,将结果存储为 tophat,Top-hat操作显示了深色背景下的亮区(即信用卡号)
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)
# 计算沿x方向的渐变在计算gradX   数组中每个元素的绝对值之后 ,我们采取一些步骤将值缩放到范围[0-255](因为图像当前是浮点数据类型)。要做到这一点,我们计算 MINVAL
#   和 MAXVAL   的 gradX   (线72),然后由我们的缩放方程上显示  线73(即,最小/最大归一化)。最后一步是将gradX转换   为 uint8   ,其范围为[0-255]
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")
# 执行gradX 图像的Otsu和二进制阈值,然后是另一个关闭操作,对数字分段
gradx = cv2.morphologyEx(gradx, cv2.MORPH_CLOSE, rectKernel)
thresh = cv2.threshold(gradx, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)
# 找到轮廓并初始化数字分组位置列表
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
locs = []
# 循环遍历轮廓,同时根据每个的宽高比进行过滤,允许我们从信用卡的其他不相关区域修剪数字组位置
for (i, c) in enumerate(cnts):
    # 计算轮廓的边界框,然后使用边界框坐标导出长宽比
    (x, y, w, h) = cv2.boundingRect(c)
    ar = w / float(h)
    # 因为信用卡使用4组固定大小的字体,我们可以修剪潜在轮廓基于纵横比
    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 = []
# 遍历四个排序的分组并确定其中的数字,循环的第一个块中,我们在每一侧提取并填充组5个像素(第125行),应用阈值处理(第126和127行),并查找和排序轮廓(第129-135行)

for (i, (gX, gY, gW, gH)) in enumerate(locs):
    # 初始化组数字列表
    groupOutput = []

    # 从灰度图像中提取4位的组感兴趣区域,然后应用阈值分割数字从信用卡背景
    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]

    # 检测组中每一个数字的轮廓,然后排序数字轮廓从左到右
    digitCnts = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL,
                                 cv2.CHAIN_APPROX_SIMPLE)
    digitCnts = imutils.grab_contours(digitCnts)
    digitCnts = contours.sort_contours(digitCnts,
                                       method="left-to-right")[0]

    # 循环数字轮廓
    for c in digitCnts:
        # 计算单个数字的边界框,提取该数字,并调整其大小,使其具有相同的固定大小参考cra图像
        (x, y, w, h) = cv2.boundingRect(c)
        roi = group[y:y + h, x:x + w]
        roi = cv2.resize(roi, (57, 88))

        # 初始化匹配分数的模板列表
        scores = []

        # 循环参考数字名称和数字ROI
        for (digit, digitROI) in digits.items():
            # 应用基于相关性的模板匹配,取score,并更新分数列表
            result = cv2.matchTemplate(roi, digitROI,
                                       cv2.TM_CCOEFF)
            (_, score, _, _) = cv2.minMaxLoc(result)
            scores.append(score)

        # 对数字ROI的分类将作为参考模板匹配分数最大的数字名
        groupOutput.append(str(np.argmax(scores)))

    # 在组周围画出数字分类
    cv2.rectangle(image, (gX - 5, gY - 5),
                  (gX + gW + 5, gY + gH + 5), (0, 0, 255), 2)
    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)))
# 进行图片识别标注展示
cv2.imshow("Image", image) 
cv2.waitKey(0)

参考数字图像:

ocr_a_reference.png
测试银行卡图片:
credit_card_05.png
测试识别结果
image.png

其实这个demo的识别率不高,主要还是在对数字识别的一些处理上存在一些差异。后续了解一些相关技术后,再来做一些优化。

相关文章

  • Python银行卡基于open-cv的OCR识别

    在学习人工智能的路上,自己接触到了很多比较有意思的小demo,感觉比较有意思的也就拿出来作为分享了,这里主要是应用...

  • OCR图片识别文字

    参考文章Python+OCR图片文字识别,验证码识别,银行卡识别 准备工作:1.安装pytesseract库:py...

  • Python+OCR图片文字识别,验证码识别,银行卡识别

    Python+OCR图片文字识别,验证码识别,银行卡识别 利用测试如下: 1.识别文字 2.识别简单的验证码 3....

  • 银行卡深度学习识别技术

    随着移动互联网的发展,很多技术都开始向移动发展,OCR技术也不例外。目前基于移动的OCR技术有银行卡号识别,身份证...

  • CV学习笔记(二十三):发票类OCR识别

    在基本完成了银行卡识别之后,开始新的任务:发票类OCR识别。发票类OCR识别一直以来也是OCR之中的热点,包括证件...

  • 银行卡识别的知识与应用

    关键词:银行卡识别、移动端银行卡二次开发、银行卡识别SDK、OCR识别 今天小编主要来分享下银行卡识别二次开发的一...

  • 车牌识别API接口车牌识别SDK

    OCR移动端车牌识别技术描述 OCR移动端车牌识别技术是我公司开发的基于移动平台的车牌识别软件开发包,支持andr...

  • pyocr光学识别

    PyOCR是python的光学字符识别(OCR)工具包装器。它有助于使用Python程序中的OCR工具。 PyOC...

  • 2018-06-14

    百度 OCR 识别银行卡号 的踩坑之旅 1. “AipOcrSdk/AipOcrSdk.h” file not ...

  • 白描取字,更快更高效的图片转文字体验

    白描取字,基于白描最核心的 OCR 文字识别功能开发而成的纯 OCR 版本,更快更高效的文字识别体验,值得尝试。 ...

网友评论

    本文标题:Python银行卡基于open-cv的OCR识别

    本文链接:https://www.haomeiwen.com/subject/wynjfrtx.html