【计算机视觉】OpenCV 模板匹配银行卡数字识别---上

文章目录


前言

本文基于 OpenCV + Python ,实现银行卡卡号数字提取、模板数字匹配功能,面向编程、计算机视觉零基础学习者。


一、项目整体介绍与环境准备

日常生活中银行卡卡号由固定字体、固定大小的数字组成,我们先准备一张标准数字模板图(0~9 十个数字依次排列),通过 OpenCV 图像处理技术:

  1. 读取数字模板图片;

  2. 对图片做灰度、二值化预处理,让数字和背景区分更明显;

  3. 检测图片中每一个数字的轮廓;

  4. 对轮廓从左到右排序,保证数字顺序不乱;

  5. 逐个截取 0~9 单个数字,保存为模板,供后续识别真实银行卡图片使用。

银行卡图片:

卡号图片:

首先安装环境:

c 复制代码
# 安装OpenCV、数值计算库
pip install opencv-python numpy

然后再准备两个文件:

图片文件:card1.png(待识别银行卡)、kahao.png(数字模板图,0-9 横向排列)

myutils.py(自定义工具脚本,用作轮廓排序)。

myutils.py

c 复制代码
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))
    return cnts, boundingBoxes

二、代码详解与介绍

代码整体执行流程

  1. 导入所有依赖库;

  2. 创建命令行参数,接收银行卡图片和数字模板图片路径;

  3. 定义银行卡卡号首位数字与卡种的映射字典;

  4. 定义自定义窗口显示函数;

  5. 读取数字模板图片;

  6. 图像预处理:彩色图 → 灰度图 → 二值黑白图;

  7. 检测图像中所有数字轮廓,并绘制轮廓;

  8. 对轮廓从左到右排序,保证数字顺序为 0~9;

  9. 逐个截取单个数字区域,统一尺寸,存入字典;

  10. 打印最终提取的数字模板字典,程序结束。

导入库

c 复制代码
import numpy as np
import argparse
import cv2
import myutils

import argparse是Python 内置命令行参数解析模块。

import myutils会导入自定义工具脚本 myutils.py

把重复使用的工具函数(轮廓排序、图像缩放、旋转等)单独封装,简化主代码。

命令行参数

c 复制代码
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())
c 复制代码
ap = argparse.ArgumentParser()

创建一个空的参数管理器,后续所有输入参数都由它管理。就像创建一张 "表格",用来登记我们需要的外部参数。

c 复制代码
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')

-i:短参数名(命令行简写,使用方便);--image:长参数名(代码内部使用的变量名,语义清晰);required=True:必传参数。运行代码时必须传入该参数,否则程序直接报错,强制用户输入图片路径;help:参数说明,输入 --help 时会展示提示文字,方便使用者理解参数作用。

c 复制代码
args = vars(ap.parse_args())

vars():将解析后的参数对象,转为 Python 字典;

我们进入程序后右击鼠标,进去设置脚本形参:

设置结束点击'Apply'应用即可,否则程序将会报错。

业务字典

c 复制代码
FIRST_NUMBER={'3':'American Express',
              '4':"Visa",
              "5": "MasterCard",
              "6":"Discover Card"}

卡号以 3 开头 → American Express

卡号以 4 开头 → Visa

卡号以 5 开头 → MasterCard

卡号以 6 开头 → Discover Card

根据银行卡第一位卡号数字判断银行卡类型。

自定义图像显示函数 cv_show

c 复制代码
def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)

封装为工具函数,一行调用。

使用格式:

c 复制代码
cv_show('xxx', img)

图像预处理

c 复制代码
img = cv2.imread(args['template'])
cv_show('img',img)
ref = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv_show('ref',ref)
ref = cv2.threshold(ref,10,255,cv2.THRESH_BINARY_INV)[1]
cv_show('ref',ref)

读取图像

c 复制代码
img = cv2.imread(args['template'])

从命令行参数字典中,取出数字模板图 kahao.png 的路径。

彩色图转灰度图

c 复制代码
ref = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

即使图片是黑白色的,我们依旧要使用转灰度图,这是因为彩图有3个颜色通道,灰度图只有一个通道,计算快捷,简化运算。

图像二值化

c 复制代码
ref = cv2.threshold(ref,10,255,cv2.THRESH_BINARY_INV)[1]

将灰度图只保留两种像素值:纯黑 (0)、纯白 (255)。

但是代码使用的是反向二值化,这是为了边缘检测时不会检测到边缘的那一圈轮廓

使用反向二值化就可以避免这个问题。

轮廓检测

c 复制代码
refCnts = cv2.findContours(ref,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]
cv2.drawContours(img,refCnts,-1,(0,0,255),3)

只检测最外层轮廓,忽略内部嵌套轮廓,数字内部也是有轮廓的。

refCnts是上一步检测到的轮廓列表,-1绘制所有轮廓,(0,0,255):绘制颜色,OpenCV BGR 格式 → (0,0,255) = 红色,3:轮廓线条宽度,数值越大线条越粗。

轮廓排序、单个数字区域提取

c 复制代码
refCnts = myutils.sort_contours(refCnts,method='lert=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))
    cv_show('roi',roi)
    digits[i] = roi
print(digits)

调用自定义工具 myutils.sort_contours,对轮廓排序,排序规则 从左到右。

检测到10个最小外接矩阵,对x排序进行排序,x越小,数字越小。

截取感兴趣区域 ROI

对图片进行切片,截取单个数字。

c 复制代码
roi = ref[y:y+h,x:x+w]

统一数字尺寸 resize

c 复制代码
roi = cv2.resize(roi,(57,88))

将所有数字统一缩放为 宽 57、高 88


总结

读者朋友们可以通过学习前半段代码,熟练掌控模块匹配算法,后续会有完整项目放出,请耐心等待,谢谢。

相关推荐
叫我:松哥2 小时前
基于卷积神经网络的人脸情绪识别算法,引入残差连接与SE注意力模块
人工智能·深度学习·神经网络·算法·cnn·迁移学习·图像识别
deephub2 小时前
2026 年开源 Agent 工具包选型指南:延迟、审计、可移植性与语言栈
人工智能·python·大语言模型·多智能体
ellenwan20262 小时前
期货量化尾盘没清仓:天勤 trading_time 过滤与收盘前平仓
python·区块链
谷哥的小弟2 小时前
大模型核心基础知识(17)—梯度下降
人工智能·深度学习·机器学习·大模型·大语言模型·梯度下降
QBoson2 小时前
Kaiwu-PyTorch-Plugin v0.2.0发布|支持Q-Diffusion,生成任务能力再拓宽
人工智能·pytorch·量子计算·生命科学
月诸清酒2 小时前
阿里千问推出高考志愿填报Agent
人工智能·高考
伊灵eLing2 小时前
GoLang 语言高级(1)
开发语言·后端·golang
掘金者阿豪2 小时前
PDO连金仓数据库,我把踩过的坑整理了一下(上篇)
后端
用户34232323763172 小时前
大规模采集架构——从单台网关到千点集群
后端