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

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


http://www.mrgr.cn/news/24143.html

相关文章:

  • 用Windows资源管理器解压zip,中文文件夹和文件出现乱码
  • 【Qt】QSS
  • 收银系统源码-商品条码标签/价签打印
  • SPPF创新改进为SPPF_UniRepLK,能与YOLO系列结合进行创新
  • 机器学习和深度学习区别
  • 万物皆AI:联发科技 Genio 130 与 ChatGPT 的火花 - 基于 MTK Genio 130 结合 ChatGPT 功能的解决方案
  • 微软面向所有用户推出 Xbox Game Pass Standard
  • LabVIEW程序员每天会阅读哪些技术网站来提升自己
  • Redis中的AOF重写过程及其实际应用
  • Redis 主从复制的原理详解
  • 【Prompt Engineering:自我一致性、生成知识提示、链式提示】
  • 基于51单片机的打点滴监控系统proteus仿真
  • Vue入门学习笔记-计算属性和监听属性
  • c++,移动语义以及noexcept关键字
  • 【C++ Primer Plus习题】14.4
  • 【.NET全栈】ASP.NET开发Web应用——LINQ技术
  • Java反射机制:动态访问和修改类属性
  • Java | Leetcode Java题解之第397题整数替换
  • 【目标检测数据集】棉花叶子病虫害数据集14400张8类别VOC+YOLO格式
  • 高级 - CodeSplit代码分割