Python OpenCV 命令行参数解析及银行卡卡号识别实战
介绍如何使用 Python 的 argparse 模块进行命令行参数解析,并结合 OpenCV 的模板匹配技术实现银行卡卡号识别。内容涵盖 argparse 基础用法、模板匹配原理、形态学操作预处理以及完整的代码实现流程,帮助读者掌握从参数配置到视觉实战的技术细节。

介绍如何使用 Python 的 argparse 模块进行命令行参数解析,并结合 OpenCV 的模板匹配技术实现银行卡卡号识别。内容涵盖 argparse 基础用法、模板匹配原理、形态学操作预处理以及完整的代码实现流程,帮助读者掌握从参数配置到视觉实战的技术细节。

在计算机视觉领域,OpenCV 是一款功能强大的开源库,而结合 Python 的命令行参数解析工具 argparse,能让我们的视觉处理程序更灵活、更通用。本文将从 argparse 基础用法讲起,逐步深入到模板匹配的经典应用——银行卡卡号识别,带你掌握从参数配置到视觉实战的完整流程。
在编写视觉处理程序时,我们经常需要动态调整输入路径、阈值、串口号等参数,如果每次都修改代码内部的常量,效率极低。Python 内置的 argparse 模块可以轻松解决这个问题,它能解析命令行传入的参数,让程序的参数配置脱离代码硬编码。
先看一个简单的示例,理解 argparse 的核心流程:
import argparse
# 1. 创建 ArgumentParser 对象,作为参数解析的容器
parser = argparse.ArgumentParser()
# 2. 添加参数:支持不同类型、默认值、帮助信息
# 字符串类型参数,指定报警器串口号,默认值 COM5
parser.add_argument("--SERIAL_PORT1", type=str, default='COM5', help='第一个报警器的串口号')
# 整数类型参数,物体面积阈值,默认值 1600
parser.add_argument("--area_thred", type=int, default=1600, help='物体面积的阈值')
# 浮点数类型参数,识别置信度,默认值 0.8
parser.add_argument("--confid_level", type=float, default=0.8, help='识别的置信度')
# 短参数 + 长参数结合,整数类型,默认值 10
parser.add_argument('-b', "--bbb", type=int, default=10)
# 3. 解析命令行参数,返回包含所有参数的 Namespace 对象
opt = parser.parse_args()
# 4. 调用参数
a = opt.area_thred
b = opt.bbb
print(f"面积阈值:{a},参数 bbb:{b},两者之和:{a+b}")
模板匹配是 OpenCV 中最简单的匹配算法,核心思想是:用一个小的模板图像,在目标图像上滑动,逐像素计算相似度,找到匹配度最高的区域。
以'在可乐图片中匹配瓶盖模板'为例,代码如下:
import cv2
# 读取目标图像和模板图像
kele = cv2.imread('kele.png')
template = cv2.imread('template.png')
# 显示原始图像
cv2.imshow('kele', kele)
cv2.imshow('template', template)
# 获取模板的高、宽
h, w = template.shape[:2]
# 执行模板匹配(归一化相关系数匹配,值越大匹配度越高)
res = cv2.matchTemplate(kele, template, cv2.TM_CCOEFF_NORMED)
# 找到匹配度最高的位置:minMaxLoc 返回最小/大值、最小/大值坐标
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
# 绘制匹配框:左上角坐标 + 右下角坐标(模板宽高偏移)
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
kele_template = cv2.rectangle(kele, top_left, bottom_right, (0,255,0), 2)
# 显示匹配结果
cv2.imshow('Kele_template', kele_template)
cv2.waitKey(0)
cv2.destroyAllWindows()
(此处为匹配结果示意图)
结合 argparse 动态传参和模板匹配技术,我们可以实现银行卡卡号的自动识别,核心流程分为「模板处理」和「银行卡图像识别」两部分。
import numpy as np
import argparse
import cv2
# 自定义工具函数(简化代码,模拟 myutils)
def sort_contours(contours, 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 contours]
(contours, boundingBoxes) = zip(*sorted(zip(contours, boundingBoxes),
key=lambda x: x[1][i], reverse=reverse))
return (contours, 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 / (w)
dim = (width, (h * r))
resized = cv2.resize(image, dim, interpolation=inter)
resized
():
cv2.imshow(name, img)
ap = argparse.ArgumentParser()
ap.add_argument(, , required=, =)
ap.add_argument(, , required=, =)
args = (ap.parse_args())
FIRST_NUMBER = {
: ,
: ,
: ,
: ,
:
}
ref = cv2.imread(args[])
ref_gray = cv2.cvtColor(ref, cv2.COLOR_BGR2GRAY)
ref_thresh = cv2.threshold(ref_gray, , , cv2.THRESH_BINARY_INV)[]
_, refCnts, _ = cv2.findContours(ref_thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
refCnts = sort_contours(refCnts, method=)[]
digits = {}
(i, c) (refCnts):
(x, y, w, h) = cv2.boundingRect(c)
roi = ref_thresh[y:y+h, x:x+w]
roi = cv2.resize(roi, (, ))
digits[i] = roi
image = cv2.imread(args[])
image = resize(image, width=)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (, ))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (, ))
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)
closeX = cv2.morphologyEx(tophat, cv2.MORPH_CLOSE, rectKernel)
thresh = cv2.threshold(closeX, , , cv2.THRESH_BINARY | cv2.THRESH_OTSU)[]
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)
_, cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
locs = []
(i, c) (cnts):
(x, y, w, h) = cv2.boundingRect(c)
ar = w / (h)
< ar < ( < w < ) ( < h < ):
locs.append((x, y, w, h))
locs = (locs, key= x: x[])
output = []
(i, (gX, gY, gW, gH)) (locs):
groupOutput = []
group = gray[gY - :gY + gH + , gX - :gX + gW + ]
group_thresh = cv2.threshold(group, , , cv2.THRESH_BINARY | cv2.THRESH_OTSU)[]
_, digitCnts, _ = cv2.findContours(group_thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
digitCnts = sort_contours(digitCnts, method=)[]
c digitCnts:
(x, y, w, h) = cv2.boundingRect(c)
roi = group_thresh[y:y+h, x:x+w]
roi = cv2.resize(roi, (, ))
scores = []
(digit, digitROI) digits.items():
result = cv2.matchTemplate(roi, digitROI, cv2.TM_CCOEFF)
(_, score, _, _) = cv2.minMaxLoc(result)
scores.append(score)
groupOutput.append((np.argmax(scores)))
cv2.rectangle(image, (gX-, gY-), (gX+gW+, gY+gH+), (,,), )
cv2.putText(image, .join(groupOutput), (gX, gY-),
cv2.FONT_HERSHEY_SIMPLEX, , (, , ), )
output.extend(groupOutput)
()
()
cv2.imshow(, image)
cv2.waitKey()
cv2.destroyAllWindows()
python 17.银行卡卡号识别.py -i card1.png -t kahao.png
(此处为识别结果示意图)
让程序从'硬编码参数'变为'动态传参',适配不同输入场景,是工业级程序的基础;
适合目标形状固定、光照变化小的场景(如数字、logo 识别),缺点是无法应对旋转、缩放;
通过本文的学习,你不仅掌握了 argparse 的参数解析技巧,还理解了模板匹配的核心原理,并能落地到银行卡卡号识别这样的实战场景。OpenCV 的玩法远不止于此,后续可尝试结合更多形态学操作、特征提取算法,解锁更多视觉应用!

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online