当前位置: 首页 > article >正文

Opencv实现提取卡号(数字识别)

直接开始

实行方法

  1. 解析命令行参数:使用argparse库来解析命令行输入,确保用户提供了输入图像和模板图像的路径。

  2. 读取模板图像:使用cv2.imread()函数读取模板图像的路径,并显示原始图像。

  3. 图像预处理

    • 将图像转换为灰度图,以简化后续处理。
    • 应用二值化操作(使用阈值10)将图像转换为二值图像(黑白图),并通过cv2.THRESH_BINARY_INV反转颜色,使前景(数字)为白色,背景为黑色。
    • 显示预处理后的二值图像。
  4. 轮廓检测

    • 使用cv2.findContours()函数在二值图像上检测轮廓。这里只检测外部轮廓,并使用cv2.CHAIN_APPROX_SIMPLE方法来简化轮廓形状。
    • 在原始图像上绘制检测到的轮廓,并显示结果。
  5. 轮廓排序

    • 使用自定义的myutils.sort_contours()函数对检测到的轮廓进行排序,这里假设该函数按照从左到右的顺序排序轮廓。

自定义的myutils库

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))
    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
  1. 数字模板提取

    • 遍历排序后的轮廓,对每个轮廓计算其外接矩形,并裁剪出相应的区域(ROI,Region of Interest)。
    • 将每个裁剪出的ROI区域缩放到固定大小(57x88),以便于后续与输入图像中的数字进行匹配。
    • 将每个缩放后的ROI存储到digits字典中,其中键为轮廓的索引,值为对应的数字模板图像。

接下来,你可能会想要使用这些数字模板与输入图像中的数字进行匹配,以确定输入图像中每个数字的具体值。这通常涉及到模板匹配技术,如使用cv2.matchTemplate()函数。

  • 读取输入图像。
  • 对输入图像进行类似的预处理步骤。
  • 在输入图像上检测可能的数字区域。
  • 对每个检测到的数字区域,使用提取的模板进行匹配,以确定其值。
  • 根据识别出的数字进行进一步的处理或分析(如确定信用卡类型等)。
import argparse
import cv2
import myutils

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())

#创建ArgumentParser对象来解析命令行参数。
#添加两个必需的参数:-i/--image(输入图像路径)和-t/--template(模板图像路径)。
#使用parse_args()解析命令行输入,并将结果转换为字典存储在args中。

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.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, refCnts, -1, (0, 0, 255), 3)
cv_show('img', img)

#使用findContours函数检测二值图像中的轮廓。
#在原始图像上绘制检测到的轮廓。
#假设myutils.sort_contours函数存在,并按从左到右的顺序对轮廓进行排序。注意这里[0]可能是为了处理#sort_contours返回值的格式,具体取决于该函数的实现。
#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))  # 缩放到指定的大小
    digits[i] = roi  # 每一个数字对应每一个模板
#遍历排序后的轮廓。
#对每个轮廓,计算其外接矩形,并裁剪出相应的区域(ROI)。
#将每个ROI缩放到固定大小(57x88)。
#将缩放后的ROI存储在digits字典中,键为轮廓的索引

代码效果:


http://www.kler.cn/a/298919.html

相关文章:

  • PostgreSQL标识符长度限制不能超过63字节
  • Vue(二)
  • 2024_12_20_生活记录
  • 国标GB28181协议平台Liveweb:搭建建筑工地无线视频联网监控系统方案
  • MVVM、MVC、MVP 的区别
  • OpenGL ES 01 渲染一个四边形
  • React 发现无webpack相关的配置的目录,使用eject进行创建, 安装插件需要进行配置
  • 三十六、Gin注册功能-检查账号是否存在
  • 基于SpringBoot的在线购物平台
  • 【计算机组成原理】带符号整数的表示——补码与反码
  • ChatGPT在论文写作领域的应用:初稿设计
  • ChoETL:支持多数据库读写.Net开源库,包含 CSV、XML、JSON等8个格式
  • 【数据结构】详解二叉搜索树及其实现
  • 王道考研操作系统笔记(一)
  • 解读 MySQL 底层设计:连接管理与并发控制策略
  • 从头开始学Spring—06初识声明式事务
  • 间隙锁在其他数据库管理系统中的类似实现
  • 发现用 Go 写桌面程序真的太爽了...
  • Proteus仿真综合实例(1)
  • 使用 JAXB 将内嵌的JAVA对象转换为 xml文件
  • MIT6.824 课程-MapReduce
  • vue3如何创建多环境变量
  • Anti-honeypot - 自动识别Web蜜罐Chrome插件,附下载链接
  • 英文站外链如何建设?
  • 启动程序时遇到0xc000007b应用程序无法正常启动问题
  • Mongodb 4.2.25 安装教程