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.实验结果

相关推荐
南城花随雪。15 分钟前
单片机:实现FFT快速傅里叶变换算法(附带源码)
单片机·嵌入式硬件·算法
dundunmm30 分钟前
机器学习之scikit-learn(简称 sklearn)
python·算法·机器学习·scikit-learn·sklearn·分类算法
古希腊掌管学习的神31 分钟前
[机器学习]sklearn入门指南(1)
人工智能·python·算法·机器学习·sklearn
波音彬要多做32 分钟前
41 stack类与queue类
开发语言·数据结构·c++·学习·算法
m0_748256781 小时前
WebGIS实战开源项目:智慧机场三维可视化(学习笔记)
笔记·学习·开源
Schwertlilien1 小时前
图像处理-Ch5-图像复原与重建
c语言·开发语言·机器学习
程序员老冯头3 小时前
第十五章 C++ 数组
开发语言·c++·算法
南七澄江3 小时前
各种网站(学习资源及其他)
开发语言·网络·python·深度学习·学习·机器学习·ai
IT古董6 小时前
【漫话机器学习系列】014.贝叶斯法则(Bayes Theorem)
人工智能·机器学习
Crossoads7 小时前
【汇编语言】端口 —— 「从端口到时间:一文了解CMOS RAM与汇编指令的交汇」
android·java·汇编·深度学习·网络协议·机器学习·汇编语言