基于opencv+tensorflow+神经网络的智能银行卡卡号识别系统——深度学习算法应用(含python、模型源码)+数据集(二)

目录

  • 前言
  • 总体设计
    • 系统整体结构图
    • 系统流程图
  • 运行环境
  • 模块实现
    • 1. 训练集图片处理
      • 1)数据加载
      • 2)图像处理
    • 2. 测试图片处理
      • 1)图像读取
      • 2)图像处理
  • 相关其它博客
  • 工程源代码下载
  • 其它资料下载


在这里插入图片描述

前言

本项目基于从网络获取的多种银行卡数据集,采用OpenCV库的函数进行图像处理,并通过神经网络进行模型训练。最终实现对常规银行卡号的智能识别和输出。

首先,通过网络获取了多样化的银行卡数据集,其中包含各种类型和设计的银行卡图像。这些图像数据将作为训练集和测试集,用于训练智能识别模型。

其次,利用OpenCV库的功能,项目对银行卡图像进行处理。包括图像增强、边缘检测、文本定位等技术,以优化图像并提高卡号的提取准确性。

接下来,通过神经网络进行模型训练。神经网络采用深度学习框架TensorFlow,通过学习大量银行卡图像,使模型能够理解和准确识别不同银行卡号的模式和特征。

最终,训练完成的神经网络模型能够智能地识别并输出常规银行卡号。这使得在图像中提取卡号的过程更为自动化和高效。

总体而言,本项目集成了数据采集、图像处理和深度学习技术,为银行卡号的智能识别提供了一种先进的解决方案。这对于自动化银行卡信息提取的场景,如金融服务或身份验证系统,具有潜在的实际应用价值。

总体设计

本部分包括系统整体结构图和系统流程图。

系统整体结构图

系统整体结构如图所示。

在这里插入图片描述

系统流程图

系统流程如图所示。

在这里插入图片描述

运行环境

本部分包括Python环境、TensorFlow环境和OpenCV环境。

详见博客。

模块实现

本项目包括4个模块:训练集图片处理、测试图片处理、模型训练及保存、模型测试。下面分别介绍各模块的功能及相关代码。

1. 训练集图片处理

数据集下载网址为http://www.cnsoftbei.com/plus/view.php?aid=348。训练集为1000张人工处理银行卡号截图中选取的120张大小不一、由4个银行卡字符单位组成的图片。这些数据集已打包存放在名为images的文件夹中,如图所示。

在这里插入图片描述

1)数据加载

相关代码如下:

def img_handle():for root, dirs, files in os.walk('./images'):for file in files:img_path = root+'/'+fileimg = cv2.imread(img_path, 0)get_img(img, file)return data, label

2)图像处理

将图片以灰度图像读入,对其进行高斯模糊、二值化处理。绘制垂直投影直方图,从左到右逐列扫描,本列有多少黑色像素点,对应直方图列就有多高。将直方图按列从左到右扫描,凡遇到直方图高度"由无到有"或者"由有到无"的列做一个标记,根据这些标记对字符分割,单个字符归一化为16×16。分割字符之后,由于数据量较少,通过对训练集做平移、添加噪声处理,进行增强。相关代码如下:

def get_img(img, file):blur = cv2.GaussianBlur(img, (3, 3), 0)  #高斯模糊ret, img = cv2.threshold(blur, 60, 255, cv2.THRESH_BINARY)  #二值化height, width = img.shapev = [0] * widthz = [0] * heighta = 0#垂直投影:统计并存储每一列的黑点数for x in range(0, width):for y in range(0, height):if img[y, x] == 255:continueelse:a = a + 1v[x] = aa = 0#创建空白图片,绘制垂直投影图l = len(v)emptyImage = np.full((height, width), 255, dtype=np.uint8)for x in range(0, width):for y in range(0, v[x]):emptyImage[y, x] = 0#分割字符Position = []Wstart = 0Wend = 0W_Start = 0W_End = 0v[0], v[len(v) - 1] = 0, 0for j in range(len(v)):if v[j] > 0 and Wstart == 0:W_Start = jWstart = 1Wend = 0if v[j] <= 0 and Wstart == 1:W_End = jWstart = 0Wend = 1if Wend == 1:Position.append([W_Start, 0, W_End, height])Wend = 0i = 0for m in range(len(Position)):if Position[m][3]/(Position[m][2]-Position[m][0]) > 1 and Position[m][3]/(Position[m][2]-Position[m][0]) < 5:temp_img = img[Position[m][1]:Position[m][3], Position[m][0]:Position[m][2]]temp_img = cv2.resize(temp_img, (16, 16))       #大小归一化
#数据增强blur1 = cv2.GaussianBlur(temp_img, (1, 1), 0)  #高斯模糊blur2 = cv2.GaussianBlur(temp_img, (3, 3), 0)  #高斯模糊noise = sp_noise(temp_img, 0.01)                  #噪声h0, w0 = temp_img.shapetemp_label = [0.0] * 10temp_data = []for hx in range(h0):for wx in range(w0):temp_data.append(float(temp_img[hx, wx]))data.append(temp_data)temp_data = []for hx in range(h0):for wx in range(w0):temp_data.append(float(blur1[hx, wx]))data.append(temp_data)temp_data = []for hx in range(h0):for wx in range(w0):temp_data.append(float(blur2[hx, wx]))data.append(temp_data)temp_data = []for hx in range(h0):for wx in range(w0):temp_data.append(float(noise[hx, wx]))data.append(temp_data)temp_data = []                                      #左移for hx in range(h0):for wx in range(w0):if wx < w0-1:temp_data.append(float(temp_img[hx, wx+1]))else:temp_data.append(255.0)data.append(temp_data)temp_data = []                                      #右移for hx in range(h0):for wx in range(w0):if wx > 0:temp_data.append(float(temp_img[hx, wx - 1]))else:temp_data.append(255.0)data.append(temp_data)temp_data = []                                      #上移for hx in range(h0):if hx < h0-1:for wx in range(w0):temp_data.append(float(temp_img[hx+1, wx]))else:for wx in range(w0):temp_data.append(255.0)data.append(temp_data)temp_data = []                                      #下移for hx in range(h0):if hx > 0:for wx in range(w0):temp_data.append(float(temp_img[hx-1, wx]))else:for wx in range(w0):temp_data.append(255.0)data.append(temp_data)temp_label[int(file[i])] = 1.0for j in range(8):label.append(temp_label)i += 1
#添加噪声
def sp_noise(image,prob):output = np.zeros(image.shape,np.uint8)thres = 1 - probfor i in range(image.shape[0]):for j in range(image.shape[1]):rdn = random.random()if rdn < prob:output[i][j] = 0elif rdn > thres:output[i][j] = 255else:output[i][j] = image[i][j]return output

2. 测试图片处理

1)图像读取

拍摄的测试图片已打包放入test_images文件夹,加载代码如下:

def image_process(file_path):
file_path = 'test_images/x.jpg'
#其中x.jpg为test_images文件夹中的任意图片

2)图像处理

与训练集预处理相似,直接将图片以灰度图像读入,对其进行高斯模糊、二值化、膨胀腐蚀处理和字符分割。由于银行卡图像上不仅有卡号,还有其他图形或字符,因此,需要对卡号进行定位。此外,这里不需要再进行数据增强处理。相关代码如下:

#图像处理
def image_process(file_path):img = cv2.imread(file_path, 0)blur = cv2.GaussianBlur(img, (3, 3), 0)     #高斯模糊ret, binary = cv2.threshold(blur, 50, 255, cv2.THRESH_BINARY) #二值化kernel = np.ones((1, 50), np.uint8)erosion = cv2.erode(binary, kernel)         #膨胀dilation = cv2.dilate(erosion, kernel)      #腐蚀
#通过边缘检测得到多条色块,再根据银行卡号分布的特征设定阈值,判定银行卡号的区域contours, hierarchy = cv2.findContours(dilation, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)sp = dilation.shapex, y, w, h = 0, 0, 0, 0for i in range(0, len(contours)):      
#矩形边框,返回值x、y是矩阵左上点的坐标,w、h是矩阵的宽和高x, y, w, h = cv2.boundingRect(contours[i])#计算矩形是否圈住银行卡号if h > sp[0]*0.05 and w > sp[1]*0.5 and y > sp[0]*0.2 and y < sp[0]*0.8 and w/h > 5:img = binary[y:y + h, x:x + w]breakreturn num_split(img)
#得到卡号区域后,绘制垂直投影直方图,字符分割,再将单个字符归一化为16*16大小的图像
#图像分割
def num_split(img):height, width = img.shapev = [0] * widthz = [0] * heighta = 0 #垂直投影:统计并存储每一列的黑点数#逐行存储for x in range(0, width):for y in range(0, height):if img[y, x] == 255:continueelse:a = a + 1v[x] = aa = 0#创建空白图片,绘制垂直投影图l = len(v)emptyImage = np.full((height, width), 255, dtype=np.uint8)for x in range(0, width):for y in range(0, v[x]):emptyImage[y, x] = 0#分割字符#将字符坐标及宽度存放到PositionPosition = []Wstart = 0Wend = 0W_Start = 0W_End = 0v[0], v[len(v)-1] = 0, 0for j in range(len(v)):if v[j] > 0 and Wstart == 0:W_Start = jWstart = 1Wend = 0if v[j] <= 0 and Wstart == 1:W_End = jWstart = 0Wend = 1if Wend == 1:Position.append([W_Start, 0, W_End, height])Wend = 0data = []#对单个字符处理 for m in range(len(Position)):temp_img = img[Position[m][1]:Position[m][3], Position[m][0]:Position[m][2]]#获得单个字符的宽度和高度h1, w1 = temp_img.shapeif w1 > h1:return []temp_img = cv2.resize(temp_img, (16, 16))h0, w0 = temp_img.shapetemp_data = []for hx in range(h0):for wx in range(w0):temp_data.append(float(temp_img[hx, wx]))data.append(temp_data)return data

相关其它博客

基于opencv+tensorflow+神经网络的智能银行卡卡号识别系统——深度学习算法应用(含python、模型源码)+数据集(一)

基于opencv+tensorflow+神经网络的智能银行卡卡号识别系统——深度学习算法应用(含python、模型源码)+数据集(三)

工程源代码下载

详见本人博客资源下载页


其它资料下载

如果大家想继续了解人工智能相关学习路线和知识体系,欢迎大家翻阅我的另外一篇博客《重磅 | 完备的人工智能AI 学习——基础知识学习路线,所有资料免关注免套路直接网盘下载》
这篇博客参考了Github知名开源平台,AI技术平台以及相关领域专家:Datawhale,ApacheCN,AI有道和黄海广博士等约有近100G相关资料,希望能帮助到所有小伙伴们。

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

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

相关文章

半平面求交 - 洛谷 - P3194 [HNOI2008] 水平可见直线

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 往期相关背景点击前往 题目大意 题目链接 https://www.luogu.com.cn/problem/P3194 在直角坐标系中给定一些直线&#xff0c;然后从Y轴无穷大处往0处看&#xff0c;…

iis特殊字符的轉義問題解決

今天發現有個問題&#xff0c;部分圖片的靜態資源帶有號&#xff0c;導致無法直接在瀏覽器獲取圖片&#xff0c;百度了一下&#xff0c;修改了注冊表&#xff0c;發現沒什麽軟用&#xff0c;最後找到一篇博客&#xff0c;解決了 解決

WorkPlus私有化部署的即时通讯软件,企业内部沟通协作的利器

随着企业的成长和信息科技的进步&#xff0c;团队协作变得越来越关键。为了更好地促进团队之间的信息共享和沟通&#xff0c;企业内部对聊天软件的需求也在不断增加。 WorkPlus是一个支持海量用户和高并发的私有化部署即时通讯能力&#xff0c;支持纯内网&#xff0c;内外网混…

服务号转订阅号如何操作

服务号和订阅号有什么区别&#xff1f;服务号转为订阅号有哪些作用&#xff1f;一、文章推送的篇数不同服务号在文章的推送篇数上是有所限制的&#xff08;每月推4次&#xff09;订阅号则每天可推送一篇文章。二、定义不同服务号主要是为关注用户提供服务使用的&#xff1b;订阅…

数据结构-数型查找

二叉排序树&#xff08;BST&#xff09; 二叉排序树&#xff0c;又称二叉查找树&#xff08;BST&#xff0c;Binary Search Tree&#xff09; 一颗二叉树或者是空二叉树&#xff0c;或者是具有如下性质的二叉树&#xff1a; 左子树上所有结点的关键字均小于根结点的关键字&…

Axure9 基本操作(一)

产品经理零基础入门&#xff08;四&#xff09;Axure 原型图教程&#xff0c;2小时学会_哔哩哔哩_bilibili Axure 9 从入门到精通全集&#xff0c;自学必备_哔哩哔哩_bilibili 1. 页面对应页面个数&#xff0c;概要对应每个页面的具体内容 2. 文件类型 3. 备用间隔改为5分钟 …

SOLIDWORKS 2024新功能之Visualize篇

SOLIDWORKS 2024新功能Visualize 增强了创建引人注目的外观的功能 SOLIDWORKS Visualize 使用 Dassault Systmes 的企业 PBR 着色模型 (DSPBR) 来准确复制金属、玻璃、塑料和其他曲面的逼真外观。 DSPBR 是材料模型&#xff0c;用于基于物理的渲染&#xff0c;受 3DEXPERIENCE…

如何在面试中胜出?接口自动化面试题安排上

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

【算法与数据结构】78、90、LeetCode子集I, II

文章目录 一、题目二、78.子集三、90.子集II三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、78.子集 思路分析&#xff1a;【算法与数据结构】77、LeetCode组合。本题可以参考77题的组合问题代码&#xff0…

小黑完成了最后一节健身课,顺利完成了跳绳比赛,乘飞机到达南京准备第二天领物资和南京城内闲逛的leetcode之旅:215. 数组中的第K个最大元素

小黑代码 class Solution:def findKthLargest(self, nums: List[int], k: int) -> int:# 数组长度n len(nums)nums list(map(lambda x:-x, nums))q []for i in range(n):heapq.heappush(q, nums[i])# 出堆target -1for i in range(k):target heapq.heappop(q)return -…

Matter 协议详解

目录 1、Matter 协议发展 1.1、什么是Matter 1.2、Matter能做什么 2、整体介绍 3、架构介绍 3.1、Matter网络拓扑结构 3.2、标识符 3.2.1、Fabric引用和Fabric标识符 3.2.2、供应商标识符&#xff08;Vendor ID&#xff0c;VID&#xff09; 3.2.3、产品标识符&#x…