opencv计算机视觉--传参方法&银行卡识别&身份证识别案例

一、传参方法

使用库:argparse

python 复制代码
cuancan=argparse.ArgumentParser()
  • argparse.ArgumentParser 是一个类

  • argparse.ArgumentParser() 是调用该类的构造函数

  • 创建了一个 ArgumentParser 类的实例对象,并赋值给变量 cuancan

python 复制代码
cuancan.add_argument('--a',type=int,default=20,help='物体的高')
cuancan.add_argument('--b',type=int,default=80,help='物体的长')
cuancan.add_argument('-c','--c',type=float,default=31.8,help='物体的宽')

使用add_argument想cuancan中添加一些参数

参数解释:
1. '-c', '--c' - 多个参数名称(短选项+长选项)
  • -c:短选项

    • 单字符,使用单横线

    • 简洁方便,适合常用选项

  • --c:长选项

    • 多字符(这里也是单字符,但格式是长选项)

    • 更易读,适合脚本中使用

  • 作用 :用户可以使用 -c--c 来指定该参数

2. type=float - 参数类型
  • 作用:将输入值转换为浮点数
3. default=31.8 - 默认值
  • 作用:用户未提供时的默认值

  • 注意 :默认值类型要与 type 匹配

4. help='物体的宽' - 帮助信息
  • 作用:在帮助文档中显示描述
python 复制代码
opt=cuancan.parse_args()
h=opt.a
l=opt.b
w=opt.c
print('物体的体积:',h*l*w)

opt = cuancan.parse_args()解析命令行参数 的关键语句

  • cuancan :之前创建的 ArgumentParser 对象

  • .parse_args() :调用该对象的 parse_args() 方法

  • opt :将解析结果赋值给变量 opt(通常命名为 args

将参数a、b、c的值赋值给h、l、w,输出h*l*w的值

1)使用代码的默认值运行:

2)右击鼠标

3)点击软件下方终端,进入终端模式

二、银行卡识别案例

任务书:要为某家银行设计一套智能卡号识别的系统。

要求:传入一张图片,就自动输出信用卡图片中的数字

1)模板预处理
python 复制代码
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

下个代码中使用的 import myutils中myutils是这个代码的文件名

python 复制代码
import numpy as np
import argparse  # python内置库
import cv2
import myutils

# 设置参数
ap = argparse.ArgumentParser()  # 创建 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())  # vars()是Python中的一个内置函数,用于返回对象的属性和值的字典。

# 指定信用卡类型
FIRST_NUMBER = {
    "3": "American Express",
    "4": "Visa",
    "5": "MasterCard",
    "6": "Discover Card"
}

def cv_show(name, img):  # 绘图展示
    cv2.imshow(name, img)
    cv2.waitKey(0)

# ... 模板图像中数字的定位处理......
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)

# 计算轮廓: cv2.findContours()函数接受的参数为二值图,即黑白的(不是灰度图),
# cv2.RETR_EXTERNAL只检测外轮廓,cv2.CHAIN_APPROX_SIMPLE只保留终点坐标
# refCnts, hierarchy = cv2.findContours(ref, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)#opencv是3点几版本,所以要使用下面的
# 将第 38 行改为:
_, refCnts, hierarchy = cv2.findContours(ref, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, refCnts, -1, (0, 0, 255), 3)
cv_show('refCnts', img)

refCnts = myutils.sort_contours(refCnts, method="left-to-right")[0]  # 排序,从左到右,从上到下
digits = {}  # 保存模板中每个数字对应的像素值

for (i, c) in enumerate(refCnts):  # 遍历每一个轮廓
    (x, y, w, h) = cv2.boundingRect(c)  # 计算外接矩形并resize成合适大小
    roi = ref[y:y + h, x:x + w]
    roi = cv2.resize(roi, (57, 88))  # 缩放到指定的大小
    cv_show('roi', roi)
    digits[i] = roi  # 每一个数字对应每一个模板

print(digits)
2)银行卡图形处理
python 复制代码
image=cv2.imread(args['image'])
cv_show('image',image)
image=myutils.resize(image,width=300)
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv_show('gray',gray)

#图形形态学
rectKernel=cv2.getStructuringElement(cv2.MORPH_RECT,(9,3))
sqKernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))

#顶帽操作
tophat=cv2.morphologyEx(gray,cv2.MORPH_TOPHAT,rectKernel)
cv_show('tophat',tophat)

#闭操作
close1=cv2.morphologyEx(tophat,cv2.MORPH_CLOSE,rectKernel)
cv_show('close1',close1)

#二值化
thresh=cv2.threshold(close1,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1]
cv_show('thresh',thresh)

#闭操作
close2=cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,rectKernel)
cv_show('close2',close2)

#轮廓检测
_,cnts,h=cv2.findContours(close2.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts_img=image.copy()

cv2.drawContours(cnts_img,cnts,-1,(0,0,255),3)
cv_show('cnts_img',cnts_img)
python 复制代码
locs=[]
for c in cnts:
    (x,y,w,h)=cv2.boundingRect(c)
    ar=w/float(h)
    if 2.5<ar<4.0:
        if(40<w<55)and(10<h<20):
            locs.append((x,y,w,h))

    # if (100<y<105)and(10<h<20):
        # locs.append((x,y,h,w))
locs=sorted(locs,key=lambda x:x[0])
print(locs)

筛选所需要的轮廓

3)模板匹配
python 复制代码
output = []
# 遍历每一个轮廓中的数字
for (gx, gy, gw, gh) in locs:
    groupOutput = []
    group = gray[gy - 5:gy + gh + 5, gx - 5:gx + gw + 5]  # 适当加一点边界
    cv_show('group', group)
    # 预处理
    group = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
    cv_show('group', group)
    # 计算每一组的轮廓
    group_, digitCnts, hierarchy = 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:
        # 找到当前数值的轮廓,resize成合适的大小
        (x, y, w, h) = cv2.boundingRect(c)
        roi = group[y:y + h, x:x + w]
        roi = cv2.resize(roi, (57, 88))
        cv_show('roi', roi)
        '''---使用模板匹配,计算匹配得分---'''
        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)  # 得到结果 将一个列表的元素添加到另一个列表的末尾。

# 打印结果
print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
print("Credit Card #: {}".format("".join(output)))
cv2.imshow('images',image)
cv2.waitKey(0)
cv2.destroyAllWindows()

注:使用的模板大小,要和进行识别的图片中对应的图片大小一致,并且在进行二值化是,要使用同样的阈值类型标志

在运行这个代码的时候,会出现下图情况

是因为这时候没有给参数赋值,要先赋值再运行

三、身份证识别

由于和银行卡识别类似,这里我就只放了代码部分

python 复制代码
'''第一种方法'''
import argparse  # python内置库
import cv2
import myutils
import numpy as np

# 设置参数
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())


def cv_show(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)


# 模板处理...
img = cv2.imread(args["template"])
cv_show('img', img)
ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv_show('ref', ref)
ref = cv2.threshold(ref, 150, 255, cv2.THRESH_BINARY_INV)[1]
cv_show('ref', ref)

_, refCnts, hierarchy = cv2.findContours(ref, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, refCnts, -1, (0, 255, 0), 2)
cv_show('refCnts', img)

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-2:y + h+2, x-2:x + w+2]
    roi = cv2.resize(roi, (57, 88))
    cv_show('roi', roi)
    digits[i] = roi
cv2.destroyAllWindows()
# 加载身份证图像
image = cv2.imread(args['image'])
cv_show('image', image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv_show('gray', gray)

# 增强对比度
# clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(6, 6))
# gray_enhanced = clahe.apply(gray)
# cv_show('gray_enhanced', gray_enhanced)

# 二值化
# _, thresh_inv = cv2.threshold(gray_enhanced, 0,  255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
# cv_show('thresh_inv', thresh_inv)

thresh = cv2.threshold(gray, 120,255, cv2.THRESH_BINARY_INV)[1]
cv_show('adaptive_thresh', thresh)

# 查找轮廓
_, cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

a=cv2.drawContours(image.copy(), cnts, -1, (0, 0, 255), 2)
cv_show('all_contours', a)

# 筛选身份证号码区域的轮廓
locs=[]
for c in cnts:
    (x,y,w,h)=cv2.boundingRect(c)
    # ar=w/float(h)
    # if 2.5<ar<4.0:
    #     if(40<w<55)and(10<h<20):
    #         locs.append((x,y,w,h))

    if (x>220)and(330<y<360):
        locs.append((x,y,w,h))
locs=sorted(locs,key=lambda x:x[0])
print(locs)
output = []
# 遍历每一个轮廓中的数字
for (i,(gx, gy, gw, gh)) in enumerate(locs):
    groupOutput = []
    group = gray[gy - 2:gy + gh + 2, gx - 2:gx + gw + 2]  # 适当加一点边界
    cv_show('group', group)
    # 预处理
    group = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY_INV| cv2.THRESH_OTSU)[1]
    cv_show('group', group)

    roi = cv2.resize(group, (57, 88))
    cv_show('roi', roi)
    # 计算每一组中的每一个数值
    '''---使用模板匹配,计算匹配得分---'''
    scores = []
    # 在模板中计算每一个得分
    for (digit, digitROI) in digits.items():
        # 模板匹配
        result = cv2.matchTemplate(roi, digitROI, cv2.TM_CCOEFF)
        (_, score, _, _) = cv2.minMaxLoc(result)  # 修正:应该是4个返回值
        scores.append(score)

    # 得到最合适的数字
    jieguo = str(np.argmax(scores))
    output.append(jieguo)

    cv2.rectangle(image, (gx - 5, gy - 5), (gx + gw + 5, gy + gh + 5), (0, 0, 255), 1)
    cv2.putText(image, jieguo, (gx, gy - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)

# 打印结果
print("Card ID #: {}".format("".join(output)))
cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
相关推荐
棒棒的皮皮2 小时前
【深度学习】YOLO学习资源之官方文档&Darknet文档
深度学习·学习·yolo·计算机视觉
数字化顾问2 小时前
(133页PPT)大型集团管控业财一体化基于SAP锂电池数字化转型总体蓝图架构设计解决方案(附下载方式)
大数据·人工智能
夔曦2 小时前
【无标题】
python·强化学习算法
SAP工博科技2 小时前
装备制造SAP Cloud ERP实施指南:基于海铑机电的全流程落地方案
大数据·人工智能·制造
视***间2 小时前
视程空间算力模块Jetson AGX 275TOPS应用到人形机器人上
大数据·人工智能·边缘计算·ai算力开发板
weixin_437497772 小时前
部分LLM小参数模型特征汇总
人工智能·语言模型
科技云报道2 小时前
科技云报到:2026,AI开启“共生智能”新纪元
大数据·人工智能·科技
先做个垃圾出来………2 小时前
Python 中 kwargs.get() 方法详解
开发语言·python
综合热讯2 小时前
中国企业追光科技亮相CES 2026,聚焦消费电子低碳供能
人工智能·科技