【opencv】信用卡号识别实验

实验环境:anaconda、jupyter notebook(其它的ide也行)

实验用的包:numpy、matplotlib、opencv

实验目标:

识别信用卡的卡号

信用卡图片:

数字模板图片:

一、包引入

import cv2
import matplotlib.pyplot as plt
import numpy as np

二、数字模板特征提取

图片二值化处理

template = cv2.imread('template.png')# 灰度处理
template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
# 二值处理
ret,template_bin = cv2.threshold(template_gray,127,255,cv2.THRESH_BINARY_INV)plt.imshow(template_bin, 'gray')
plt.show()

数字模板二值化处理.png

检测数字模板外轮廓

# 只检测外轮廓
binary, template_contours, hierarchy = cv2.findContours(template_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
template_copy = template.copy()template_contours_img = cv2.drawContours(template_copy, template_contours, -1, (0,0,255),1)plt.imshow(template_contours_img)
plt.show()

数字模板外轮廓.png

找到外接矩形

# 外接矩形
tangles = []
template_copy = template.copy()
for cnt in template_contours:x,y,w,h = cv2.boundingRect(cnt)tangles.append((x,y,w,h))template_copy = cv2.rectangle(template_copy, (x, y), (x + w, y + h), (0,255,0), 2)
plt.imshow(cv2.cvtColor(template_copy, cv2.COLOR_BGR2RGB))
plt.show()
# 根据x值狠狠排序
tangles.sort()
print(tangles)

数字模板外接矩形.png

通过外接矩形截取数字图片

# 拿到数字对应的图片
number_size = (50,100)
digits = {}
for i in range(len(tangles)):(x,y,w,h) = tangles[i]digits[i] = cv2.resize(template_bin[y:y+h, x: x+w], number_size)plt.subplot(1,10,1 + i)plt.xticks([])plt.yticks([])plt.imshow(digits[i],'gray')
plt.show()

数字模板.png

三、信用卡卡面特征提取

初始化卷积核、处理卡片

# 初始化卷积核
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT,(9,3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))# 读入信用卡图片
card = cv2.imread('card.png')
# 处理为灰度图
card_gray = cv2.cvtColor(card, cv2.COLOR_BGR2GRAY)
# 处理为礼帽处理
card_tophat = cv2.morphologyEx(card_gray, cv2.MORPH_TOPHAT, rectKernel)plt.imshow(card_tophat,'gray')
plt.show()

信用卡礼帽.png

对信用卡图片梯度处理

gradx = cv2.Sobel(card_tophat, ddepth=cv2.CV_32F, dx=1,dy=0, ksize=-1)
card_gradx = np.absolute(gradx)
(min_val,max_val) = (np.min(card_gradx), np.max(card_gradx))
card_gradx = (255 * ((card_gradx - min_val) / (max_val - min_val)))
card_gradx = card_gradx.astype('uint8')plt.imshow(card_gradx,'gray')
plt.show()

信用卡梯度处理.png

把特征轮廓合成一片,方便提取

闭操作

card_closing = cv2.morphologyEx(card_gradx, cv2.MORPH_CLOSE,rectKernel)plt.imshow(card_closing,'gray')
plt.show()

信用卡闭操作.png

二值化

# 二值化,自动判断
ret,card_bin = cv2.threshold(card_closing,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)plt.imshow(card_bin,'gray')
plt.show()

信用卡二值化处理.png

膨胀操作

# 膨胀操作,加强卡号特征
card_dilate = cv2.dilate(card_bin, rectKernel, iterations=1)plt.imshow(card_dilate,'gray')
plt.show()

信用卡膨胀.png

获取外轮廓

# 检测外轮廓
binary, card_contours, hierarchy = cv2.findContours(card_dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
card_copy = card.copy()card_contours_img = cv2.drawContours(card_copy, card_contours, -1, (0,0,255),2)plt.imshow(cv2.cvtColor(card_contours_img,cv2.COLOR_BGR2RGB))
plt.show()

此时拿到的外轮廓有很多不需要的地方

信用卡外轮廓.png

获取需要的外轮廓

card_copy = card.copy()
locs = []
for (i, sit) in enumerate(card_contours):(x,y,w,h) = cv2.boundingRect(sit)ar = w / float(h)if ar > 2.5 and ar < 4.0:if 65 < w < 70 and 15 < h < 25:locs.append((x,y,w,h))
locs.sort()
for (x,y,w,h) in locs:card_copy = cv2.rectangle(card_copy, (x, y), (x + w, y + h), (0,255,0), 2)plt.imshow(cv2.cvtColor(card_copy, cv2.COLOR_BGR2RGB))
plt.show()

信用卡卡号外轮廓提取.png

四、卡号识别

output = []
card_copy = card.copy()
for (i,(x,y,w,h)) in enumerate(locs):group_output = []# 获取每组卡号group = card_gray[y - 5 : y + h + 5, x - 5 : x + w + 5]# 转为二值图像ret, group = cv2.threshold(group,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)# 外轮廓检测binary, group_contours, hierarchy = cv2.findContours(group, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)data_sites = []for data_sit in group_contours:data_sites.append(cv2.boundingRect(data_sit))data_sites.sort()for (gx, gy, gw, gh) in data_sites:data = cv2.resize(group[gy : gy + gh, gx : gx + gw], number_size)scores = []# 计算分数for (digit, digit_img) in digits.items():result = cv2.matchTemplate(data, digit_img, cv2.TM_CCOEFF_NORMED)(_,score,_,_) = cv2.minMaxLoc(result)scores.append(score)group_output.append(str(np.argmax(scores)))cv2.rectangle(card_copy,(x - 5, y - 5), (x + w +5, y + h + 5), (0,255,0),2)cv2.putText(card_copy, "".join(group_output), (x, y - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0,0,255),2)output.extend(group_output)plt.imshow(cv2.cvtColor(card_copy, cv2.COLOR_BGR2RGB))
plt.show()
print(output)

成功识别卡号

信用卡卡号识别.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/11812.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kubernetes集群svc的代理模式-iptables修改为ipvs

一、概述\ 我们都知道&#xff0c;k8s集群的外部网络分发&#xff0c;借助kube-proxy组件来完成&#xff1b; 问题&#xff1a;我们为什么要将代理模式修改为ipvs而不继续使用iptables呐&#xff1f; 1&#xff0c;iptables底层使用四表五链完成网络代理&#xff0c;效率比较低…

RiProV2主题美化【支付页弹窗增加价格提示语】Ritheme主题美化RiProV2-网站WordPress美化二开

背景: 楼主的网站是用WordPress搭建的,并使用了正版主题RiProV2,但RiProV2在支付弹窗页没有价格,只在文章详情页会展示价格。本文就是美化这个支付弹窗,在支付弹窗页把价格字段加上,如下图所示: 美化前: 美化后 美化步骤: (1)定位到文件:/www/wwwroot/www.uu2i…

基于SpringBoot设计模式之创建型设计模式·抽象工厂模式

文章目录 介绍开始架构图&#xff08;以穿搭举例&#xff09;样例一&#xff08;html关于列表和表格的应用&#xff09;定义抽象工厂&#xff08;html&#xff09;定义抽象工厂需要制作抽象产物&#xff08;托盘&#xff09;定义具体工厂&#xff08;列表、表格&#xff09;定义…

海洋环境保护论文阅读记录

海洋环境保护 论文1&#xff1a;Critical role of wave–seabed interactions in the extensive erosion of Yellow River estuarine sediments 波浪-海床相互作用在黄河河口广泛侵中的关键作用 estuatine 河口的&#xff0c;港湾的 erodibility侵蚀度 sediment erodibility …

【Golang】Golang 的 HTTP 使用 Header 指南

文章目录 前言一、Header 解释二、代码实现三、hearder常见枚举值四、总结 前言 在构建和处理 HTTP 请求和响应时&#xff0c;Headers 扮演着重要的角色。它们提供了关于请求或响应的元数据&#xff0c;例如内容类型&#xff0c;编码&#xff0c;认证等。在 Go 语言中&#xf…

[PythonWeb:Django框架]:前后端请求调用;

文章目录 接着上篇项目app包下面创建static包&#xff0c;引入jquery&#xff0c;bootstrap 相关js文件views.py编写apicompute文件夹下面的urls.py路由模块引入views.py刚刚定义的函数html发送ajax请求 接着上篇 https://blog.csdn.net/Abraxs/article/details/138739727?sp…

24年湖南三支一扶报名详细流程(电脑报名)

24年湖南三支一扶报名详细流程&#xff08;电脑报名&#xff09; #湖南三支一扶 #湖南三支一扶考试 #三支一扶报名照片 #三支一扶考试 #三支一扶 #湖南省三支一扶

[语言月赛 202404] 吃苹果

题目描述 一共有 n 只苹果&#xff0c;你想要选择其中恰好两只苹果。 每只苹果有一个营养值 a1​,a2​,⋯,an​&#xff0c;你需要选择一只营养值最大的给 gza 吃&#xff0c;选择一只营养值最小的给 gza 的朋友 azg 吃。 请注意&#xff0c;由于某些苹果会有虫蚀等等&#…

Java基础(34)大型网站在架构上应当考虑哪些问题

大型网站的架构设计面临着多方面的挑战&#xff0c;这些挑战要求开发者和架构师在设计之初就需要考虑全面。以下是一些最关键的考虑因素&#xff0c;它们共同决定了一个大型网站是否能够成功满足业务需求、用户体验和技术发展的需要。 1. 可扩展性&#xff08;Scalability&…

深度剖析深度神经网络(DNN):原理、实现与应用

目录 引言 一、DNN基本原理 二、DNN核心算法原理 三、DNN具体操作步骤 四、代码演示 引言 在人工智能和机器学习的浪潮中&#xff0c;深度神经网络&#xff08;Deep Neural Network&#xff0c;简称DNN&#xff09;已经成为了一种非常重要的工具。DNN模仿人脑神经网络的结…

paddle ocr v4 2.6.1实战笔记

目录 效果图&#xff1a; 安装 模型权重是自动下载&#xff0c;如果提前下载会报错。 识别orc&#xff0c;并opencv可视化结果&#xff0c;支持中文可视化 官方原版预测可视化&#xff1a; 效果图&#xff1a; 安装 安装2.5.2识别结果为空 pip install paddlepaddle-gpu…

二维数组:行列互换/求最大值及其所在位置/求各行各列的和/矩阵乘积/深入理解二维数组

二维数组 1.定义 只有行号可以省略&#xff0c;初始化 全部初始化/部分初始化/不初始化 2.元素引用 3.存储形式 :顺序存储 按行存储 4.深入理解二维数组 #include<stdio.h> #include<stdlib.h>#define M 2 #define N 3int mian() {int a[M][N] {{1,2,3},{4,5,6}}…

【Python探索之旅】选择结构(条件语句)

文章目录 条件结构&#xff1a; 1.1 if单分支结构 1.2 if-else 多分支结构 1.3 if-elif 多重结构&#xff1a; 完结撒花​ 前言 Python条件语句是通过一条或多条语句的执行结果&#xff08;True或者False&#xff09;来决定执行的代码块。 Python提供了顺序、选择、循环三…

redis和mysql数据库主要的区别

MySQL和Redis作为两种不同类型的数据库&#xff0c;它们之间存在显著的区别&#xff0c;主要体现在以下几个方面&#xff1a; 数据结构与类型&#xff1a; MySQL&#xff1a;是一种关系型数据库管理系统(RDBMS)&#xff0c;支持丰富的数据结构&#xff0c;如表格形式的行和列&a…

Git详解之六:Git工具

现在&#xff0c;你已经学习了管理或者维护 Git 仓库&#xff0c;实现代码控制所需的大多数日常命令和工作流程。你已经完成了跟踪和提交文件的基本任务&#xff0c;并且发挥了暂存区和轻量级的特性分支及合并的威力。 接下来你将领略到一些 Git 可以实现的非常强大的功能&…

重学java 37.多线程基本了解

尽管走自己的路&#xff0c;别被那些三言两语击倒 —— 24.5.13 一、多线程_线程和进程 进程&#xff1a;在内存中执行的应用程序 线程:是进程中最小的执行单元线程作用:负责当前进程中程序的运行,一个进程中至少有一个线程,一个进程还可以有多个线程,这…

缓存淘汰(LRU)算法

LRU&#xff08;最近最少使用&#xff09;算法是一种常见的缓存淘汰策略&#xff0c;广泛应用于操作系统、数据库缓存、网页缓存等领域。该算法的核心思想是优先淘汰那些最长时间未被使用的数据&#xff0c;基于的假设是如果数据最近被访问过&#xff0c;那么将来被访问的可能性…

英伟达科学家展望:OpenAI或将引领AI多模态语音助手新时代

在人工智能领域,语音助手一直是人们关注的焦点。随着技术的不断发展,从简单的语音指令识别到复杂的对话系统,语音AI正逐渐融入我们的日常生活。今晚凌晨2点,OpenAI可能发布的AI多模态语音助手无疑将再次引发业界的热烈讨论。英伟达科学家KOL近日对此进行了深入解读,为我们…

永嘉原厂8×16点阵数码管驱动抗干扰数码管驱动IC防干扰数显芯片VK1640 SOP28

产品型号&#xff1a;VK1640 产品品牌&#xff1a;永嘉微电/VINKA 封装形式&#xff1a;SOP28 原厂&#xff0c;工程服务&#xff0c;技术支持&#xff01; 概述 VK1640是一种数码管或点阵LED驱动控制专用芯片&#xff0c;内部集成有数据锁存器、LED 驱动等电路。SEG脚接LE…