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

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

引言

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

项目准备

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

        实验素材


        定义函数
import cv2

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]
    (cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),
                                        key=lambda b:b[1][i],reverse=reverse))
    #zip(*...)使用星号操作符解包排序后的元组列表,并将其重新组合成两个列表:一个包含所有轮廓,另一个包含所有边界框。
    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)    #默认为cV2.INTER_AREA,即面积插值,适用于缩放图像。
    return resized
        传入参数
        
代码详解
  1. 导入库和设置参数
    import numpy as np
    import argparse
    import cv2
    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 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 进行银行卡上数字的识别。整个过程包括模板图像处理、银行卡图像预处理、数字区域定位、模板匹配以及结果展示。这种技术在金融领域有着广泛的应用,可以帮助自动化处理大量的银行卡识别任务。通过适当的图像处理技术和模板匹配方法,我们可以准确地识别出银行卡上的数字序列。

OpenCV(Open Source Computer Vision Library)是一款开源的计算机视觉库,专门为图像和视频处理任务设计,广泛应用于学术研究、工业应用以及个人项目中。以下是关于OpenCV的详细介绍: 历史与发展 起源:OpenCV于1999年由英特尔公司发起,旨在促进计算机视觉技术的普及和商业化应用。该项目旨在创建一个易于使用、高效且跨平台的库,为开发者提供实现计算机视觉算法所需的基础工具。 社区与支持:随着时间的推移,OpenCV吸引了全球众多开发者和研究人员的参与,形成了活跃的社区。目前,OpenCV由非盈利组织OpenCV.org维护,并得到了全球开发者、研究机构以及企业的持续贡献和支持。 主要特点 跨平台:OpenCV支持多种操作系统,包括但不限于Windows、Linux、macOS、Android和iOS,确保代码能够在不同平台上无缝运行。 丰富的功能:库中包含了数千个优化过的函数,涵盖了计算机视觉领域的诸多方面,如图像处理(滤波、形态学操作、色彩空间转换等)、特征检测与描述(如SIFT、SURF、ORB等)、物体识别与检测(如Haar级联分类器、HOG、DNN等)、视频分析、相机校正、立体视觉、机器学习(SVM、KNN、决策树等)、深度学习(基于TensorFlow、PyTorch后端的模型加载与部署)等。 高效性能:OpenCV代码经过高度优化,能够利用多核CPU、GPU以及特定硬件加速(如Intel IPP、OpenCL等),实现高速图像处理和实时计算机视觉应用。 多语言支持:尽管OpenCV主要使用C++编写,但它提供了丰富的API绑定,支持包括C、Python、Java、MATLAB、JavaScript等多种编程语言,方便不同领域的开发者使用。 开源与免费:OpenCV遵循BSD开源许可证发布,用户可以免费下载、使用、修改和分发库及其源代码,无需担心版权问题。 架构与核心模块 OpenCV的架构围绕核心模块构建,这些模块提供了不同层次的功能: Core:包含基本的数据结构(如cv::Mat用于图像存储和操作)、基本的图像和矩阵操作、数学函数、文件I/O等底层功能。 ImgProc:提供图像预处理、滤波、几何变换、形态学操作、直方图计算、轮廓发现与分析等图像处理功能。 HighGui:提供图形用户界面(GUI)支持,如图像和视频的显示、用户交互(如鼠标事件处理)以及简单的窗口管理。 VideoIO:负责视频的读写操作,支持多种视频格式和捕获设备。 Objdetect:包含预训练的对象检测模型(如Haar级联分类器用于人脸检测)。 Features2D:提供特征点检测(如SIFT、ORB)与描述符计算、特征匹配与对应关系估计等功能。 Calib3d:用于相机标定、立体视觉、多视图几何等问题。 ML:包含传统机器学习算法,如支持向量机(SVM)、K近邻(KNN)、决策树等。 DNN:深度神经网络模块,支持导入和运行预训练的深度学习模型,如卷积神经网络(CNN)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值