opencv 之 实战项目 识别银行卡上的数字

news/2024/12/20 21:59:51/

OpenCV 之 实战项目:识别银行卡上的数字

引言

在日常生活中,银行卡的识别是一个常见的需求,特别是在金融领域。本实战项目旨在使用 OpenCV 库来识别银行卡上的数字。我们将通过模板匹配的方法,结合图像处理技术,来准确识别银行卡上的数字序列。

项目准备

本项目需要安装 Python 和 OpenCV 库。确保已经安装了必要的库,并准备好银行卡图像和数字模板图像。

        实验素材


        定义函数
import cv2def 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](cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),key=lambda b:b[1][i],reverse=reverse))#zip(*...)使用星号操作符解包排序后的元组列表,并将其重新组合成两个列表:一个包含所有轮廓,另一个包含所有边界框。return cnts, boundingBoxesdef 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)    #默认为cV2.INTER_AREA,即面积插值,适用于缩放图像。return resized
        传入参数
        
代码详解
  1. 导入库和设置参数
    import numpy as np
    import argparse
    import cv2
    import myutilsap = 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 OCR-A image")
    args = vars(ap.parse_args())

    解释:

    • 导入必要的库。
    • 使用 argparse 库来设置命令行参数,包括输入图像路径和模板图像路径。
    • 解析命令行参数并将结果存储在 args 字典中。
  2. 指定信用卡类型
    FIRST_NUMBER = {"3": "American Express","4": "Visa","5": "MasterCard","6": "Discover Card"}

    解释:

    • 定义一个字典,根据银行卡号的第一个数字来确定其类型。
  3. 模板图像处理
    img = cv2.imread(args["template"])
    ref = cv2.cvtColor(img, 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 = 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

    解释:

    • 读取模板图像并转换为灰度图。
    • 将灰度图转换为二值图。
    • 计算模板图像中的轮廓,并按照从左到右的顺序排序。
    • 提取每个数字的 ROI(感兴趣区域),并将其存储在 digits 字典中。
  4. 银行卡图像处理
    image = cv2.imread(args["image"])
    image = myutils.resize(image, width=300)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
    sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
    tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)
    closeX = cv2.morphologyEx(tophat, cv2.MORPH_CLOSE, rectKernel)
    thresh = cv2.threshold(closeX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)
    _, threshCnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = threshCnts
    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 and (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])

    解释:

    • 读取银行卡图像并调整大小。
    • 转换为灰度图。
    • 使用顶帽操作增强图像中的数字区域。
    • 使用形态学闭操作连接数字区域。
    • 计算阈值并进一步处理图像。
    • 计算图像中的轮廓,并筛选出符合条件的数字区域。
    • 将数字区域按照从左到右的顺序排序。
  5. 数字识别
    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]_, digitCnts, _ = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)digitCnts = myutils.sort_contours(digitCnts, method="left-to-right")[0]for c in digitCnts:(x, y, w, h) = cv2.boundingRect(c)roi = group[y:y + h, x: x + w]roi = cv2.resize(roi, (57, 88))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)

    解释:

    • 对每个数字区域进行处理,提取每个数字的 ROI。
    • 使用模板匹配计算每个数字区域与模板的匹配得分。
    • 将得分最高的模板对应的数字添加到结果中。
    • 在图像上绘制矩形框和识别结果。
  6. 打印结果
    print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
    print("Credit Card #:{}".format("".join(output)))
    cv2.imshow("Image", image)
    cv2.waitKey(0)

    解释:

    • 打印识别出的信用卡类型和号码。
    • 显示处理后的图像。
  7. 输出结果:
总结

通过本实战项目,我们展示了如何使用 OpenCV 进行银行卡上数字的识别。整个过程包括模板图像处理、银行卡图像预处理、数字区域定位、模板匹配以及结果展示。这种技术在金融领域有着广泛的应用,可以帮助自动化处理大量的银行卡识别任务。通过适当的图像处理技术和模板匹配方法,我们可以准确地识别出银行卡上的数字序列。


http://www.ppmy.cn/news/1527399.html

相关文章

《A++ 敏捷开发》- 26 根与翼

中国社会一直非常强调家庭价值观&#xff0c;希望实现家族的持续传承&#xff0c;家族有族谱&#xff0c;代代相传的关系对每个家庭成员的成长产生深远影响。我们每个人都只是人类进化过程中的短暂过渡。父母普遍希望把最好的东西传承给下一代。然而我们需要问自己&#xff0c;…

MySQL 变量查询如何使用索引

MySQL 变量查询如何使用索引 1. 问题现象 在存储过程中&#xff0c;有通过变量进行数据查询&#xff0c;执行时间长&#xff0c;不符和预期&#xff0c;经过分析&#xff0c;发现是有一个变量查询的效率低&#xff0c;不走索引造成的。 在定义变量查询&#xff0c;不能使用索…

secureCRT 工具连接sshd服务报错

报错如下&#xff1a; Key exchange failed. No compatible key exchange method. The server supports these methods: sntrup761x25519-sha512openssh.com,curve25519-sha256,ecdh-sha2-nistp256,diffie-hellman-group14-sha256 No compatible hostkey. The server supports…

prometheus 集成 grafana 保姆级别安装部署

前言 本文 grafana 展示效果只需要 prometheus node_exporter grafana 其他的选择安装 环境和版本号 系统: CentOS 7.9 prometheus: 2.54.1 pushgateway: 1.9.0 node_exporter: 1.8.2 alertmanager: 0.27.0 grafana:11.2.0 官网:https://prometheus.io/ 下载地址:h…

【使用C语言创建一个简单的HTTP服务器】

创建一个简单的HTTP服务器使用C语言涉及到网络编程的基础&#xff0c;特别是使用套接字&#xff08;sockets&#xff09;进行网络通信。这里提供一个非常基础的HTTP服务器实现案例&#xff0c;该服务器能够监听HTTP请求&#xff0c;对简单的GET请求返回HTML页面。 准备工作 确…

堪比理科博士生的最强AI大模型:GPT-o1全面测评它来了

❤️作者主页&#xff1a;小虚竹 ❤️作者简介&#xff1a;大家好,我是小虚竹。2022年度博客之星&#x1f3c6;&#xff0c;Java领域优质创作者&#x1f3c6;&#xff0c;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;掘金年度人气作者&#x1…

K8s利用etcd定时备份集群结合钉钉机器人通知

如何通过脚本的方式进行K8s集群的备份 查看K8s中master节点中etcd集群的状态 kubectl get pods -n kube-system | grep etcd由于使用的etcd服务是K8s搭建时自身携带的,并不是独立搭建的etcd集群信息。使用 K8s 搭建集群时,etcd 是 Kubernetes 集成的一个重要组件因此需要查…

2024 年至今回顾:The Sandbox 创作者的历程及下一步展望

2024 年上半年是 The Sandbox 令人振奋的旅程&#xff01;从激动人心的里程碑、丰厚的奖励到创新的功能&#xff0c;我们见证了来自充满活力的社区的惊人创造力。 作为平台的生命线&#xff0c;我们致力于帮助创作者发光发热。让我们深入了解过去六个月中最激动人心的时刻和更…