首页 > 其他分享 >opencv学习:信用卡卡号识别

opencv学习:信用卡卡号识别

时间:2024-09-15 20:20:25浏览次数:12  
标签:信用卡 数字 image cv2 opencv 卡号 图像 轮廓 模板

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

1.创建命令行参数

数字模板

信用卡

# 创建命令行参数解析器
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.指定信用卡类型

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

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

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.找到二值图像的轮廓

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

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

# 使用自定义函数对轮廓进行排序
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.获取信用卡灰度图

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

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

# 使用形态学操作来增强图像中的数字
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.找到处理后的图像中的轮廓

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

9.绘制轮廓

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

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

# 初始化一个空列表,用于存储检测到的数字的位置信息
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.识别所有卡号的数字,并在原图上面写下卡号

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

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

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

13.实验结果

标签:信用卡,数字,image,cv2,opencv,卡号,图像,轮廓,模板
From: https://blog.csdn.net/mohanyelong/article/details/142107637

相关文章

  • OpenCV和Tesseract OCR识别复杂验证码喽~~
    目录代码实现思路流程:主要流程:整体代码效果展示原图处理之后的图总结流程图代码实现思路使用OpenCV进行图像预处理,并通过TesseractOCR来识别验证码中的字符。以下是其实现思路的详细讲解:流程:加载验证码图像:使用cv2.imread()读取验证码图片,将其加载为......
  • OpenCV运动分析和目标跟踪(1)累积操作函数accumulate()的使用
    操作系统:ubuntu22.04OpenCV版本:OpenCV4.9IDE:VisualStudioCode编程语言:C++11算法描述将一个图像添加到累积图像中。该函数将src或其部分元素添加到dst中:dst(......
  • 新电脑安装和配置pytorch、anaconda、CUDA、cuDNN、pycharm、OpenCV的过程记录
    显卡驱动和CUDA一、升级显卡驱动到官方最新版    1、打开英伟达官网,输入显卡芯片型号,手动搜索并下载显卡驱动。 NVIDIA官方驱动 ​    2、下载完成后安装驱动。 二、确认显卡支持的最高CUDA版本    1、键盘"win+R",调出运行输入cmd后点”......
  • OpenCV(cv::split())
    目录1.函数定义2.工作原理3.示例4.使用场景5.注意事项cv::split()是OpenCV提供的一个函数,用于将多通道图像分割成其各个单通道。该函数主要用于处理彩色图像和多通道矩阵,通常用于对图像中的每个颜色通道单独进行处理。1.函数定义voidcv::split(constMat&src,s......
  • OpenCV添加中文文字
    代码如下,随机在摄像头中添加文字importcv2importnumpyasnpfromrandomimportrandintfromPILimportImage,ImageDraw,ImageFontCOLOR=(255,0,0)font_size=24cap=cv2.VideoCapture(0)whilecap.isOpened():ret,frame=cap.read()width,height......
  • OpenCV(cv::dilate())
    目录1.函数定义2.工作原理3.示例4.应用场景5.膨胀和腐蚀的对比总结cv::dilate()是OpenCV中用于图像形态学变换的函数之一,与cv::erode()相对,它执行图像的膨胀操作。膨胀是一种将图像中的前景(白色区域)扩展的操作,通常用于填补图像中的小孔洞、连接分离的物体、或增强图......
  • OpenCV(cv::erode())
    目录1.函数定义2.工作原理3.示例4.应用场景总结cv::erode()是OpenCV中的图像形态学变换函数之一,用于执行图像的腐蚀操作。腐蚀是一种将图像中的白色区域缩小的操作,通常用于去除噪声、分离相邻的物体,或将小的图像细节消除。1.函数定义voidcv::erode(InputArraysrc......
  • OpenCV(cv::GaussianBlur())
    目录1.函数定义2.高斯模糊原理2.1高斯核\((3\times3)\)2.1.1高斯核的创建2.1.2卷积操作2.1.3边界处理2.1.4完成模糊处理2.1.5总结2.2高斯核\((5\times5)\)3.示例4.高斯核的生成5.高斯模糊的应用场景6.高斯模糊与其他模糊方式的对比7.总结cv::GaussianBlur()......
  • opencv-python学习笔记9-图像分割
    目录一、图像分割的概述、技术现状、应用:技术现状:传统图像分割技术:深度学习驱动的图像分割技术:应用领域:二、 图像分割的方法和分类:(1)基于阈值的分割方法:(2)基于区域的分割方法:(3)基于边缘的分割方法:(4)基于特定理论的分割方法:(5)基于深度学习的分割方法:三、图像分割的原理:......
  • 如何订阅支付DeepL,订阅DeepL Pro以及申请DeepL API?深度解析DeepL,虚拟信用卡WildCard绑
    十里不同音,五里不同调在现今世界中,跨语言的交流能力愈发重要,无论是国际友人之间的沟通交流,还是与客户或者合作伙伴之间的业务沟通,高质量的语言翻译都是一种刚性需求。今天,我们就来看一家这样的独角兽企业——一个机器翻译平台DeepL,它可以立即准确、轻松地将书面内容翻译......