opencv学习:信用卡卡号识别

该代码用于从信用卡图像中自动识别和提取数字信息。该系统将识别信用卡类型,并输出信用卡上的数字序列。

1.创建命令行参数

数字模板

信用卡

python 复制代码
# 创建命令行参数解析器
ap = argparse.ArgumentParser()
# 添加命令行参数 -i/--image,指定输入图像路径
ap.add_argument("-i", "--image", required=True, help="path to input image")
# 添加命令行参数 -t/--template,指定模板图像路径
ap.add_argument("-t", "--template", required=True, help="path to template OCR-A image")
# 解析命令行参数
args = vars(ap.parse_args())

2.指定信用卡类型

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

3.将模板数字图像转换为二值图像

python 复制代码
def cv_show(name, img):  # 绘图展示
    cv2.imshow(name, img)
    cv2.waitKey(0)

# 读取模板图像
img = cv2.imread(args["template"])
ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转换为灰度图
ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]  # 二值图像

4.找到二值图像的轮廓

python 复制代码
# 找到二值图像中的轮廓
_, refCnts, _ = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, refCnts, -1, (0, 0, 255), 3)  # 在原始图像上绘制轮廓

5.使用自定义函数对轮廓进行排序

python 复制代码
# 使用自定义函数对轮廓进行排序
refCnts = 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  # 每一个数字对应每一个模板

6.获取信用卡灰度图

python 复制代码
# 读取信用卡图像
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 转换为灰度图

7.使用形态学操作来增强图像中的数字

python 复制代码
# 使用形态学操作来增强图像中的数字
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)

8.找到处理后的图像中的轮廓

python 复制代码
# 找到处理后的图像中的轮廓
_, threshCnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = threshCnts

9.绘制轮廓

python 复制代码
# 绘制轮廓
cur_img = image.copy()
cv2.drawContours(cur_img, cnts, -1, (0, 0, 255), 3)

10.存储所识别的排序后的数字

python 复制代码
# 初始化一个空列表,用于存储检测到的数字的位置信息
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:
        if (w > 40 and w < 55) and (h > 10 and h < 20):
            locs.append((x, y, w, h))

# 根据x坐标对位置信息进行排序,确保从左到右识别数字
locs = sorted(locs, key=lambda x: x[0])

11.识别所有卡号的数字,并在原图上面写下卡号

python 复制代码
# 初始化一个空列表,用于存储识别出的数字
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]

    # 找到当前数字组中的每个数字的轮廓
    group_, digitCnts, _ = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # 对数字轮廓进行排序
    digitCnts = 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)

12.打印信用卡类型和ID

python 复制代码
# 打印信用卡类型和ID
print("card Type:{}".format(FIRST_NUMBER[output[0]]))
print("card ID:{}".format("".join(output)))

# 显示最终结果
cv2.imshow("image", image)
cv2.waitKey(0)

13.实验结果

相关推荐
QxQ么么3 小时前
移远通信(桂林)26校招-助理AI算法工程师-面试纪录
人工智能·python·算法·面试
('-')5 小时前
《从根上理解MySQL是怎样运行的》第十章学习笔记
笔记·学习·mysql
hd51cc5 小时前
MFC学习笔记 对话框
笔记·学习·mfc
雪碧聊技术5 小时前
深度学习、机器学习、人工智能三者的关系
人工智能·深度学习·机器学习
β添砖java5 小时前
机器学习初级
人工智能·机器学习
Mz12215 小时前
day05 移动零、盛水最多的容器、三数之和
数据结构·算法·leetcode
SoleMotive.5 小时前
如果用户反映页面跳转得非常慢,该如何排查
jvm·数据库·redis·算法·缓存
Radan小哥5 小时前
Docker学习笔记—day0010
笔记·学习·docker
念越5 小时前
判断两棵二叉树是否相同(力扣)
算法·leetcode·入门
im_AMBER5 小时前
Canvas架构手记 05 鼠标事件监听 | 原生事件封装 | ctx 结构化对象
前端·笔记·学习·架构