基于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+'/'+file
                     img = 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.shape
    v = [0] * width
    z = [0] * height
    a = 0
    #垂直投影:统计并存储每一列的黑点数
    for x in range(0, width):
        for y in range(0, height):
            if img[y, x] == 255:
                continue
            else:
                a = a + 1
        v[x] = a
        a = 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 = 0
    Wend = 0
    W_Start = 0
    W_End = 0
    v[0], v[len(v) - 1] = 0, 0
    for j in range(len(v)):
        if v[j] > 0 and Wstart == 0:
            W_Start = j
            Wstart = 1
            Wend = 0
        if v[j] <= 0 and Wstart == 1:
            W_End = j
            Wstart = 0
            Wend = 1
        if Wend == 1:
            Position.append([W_Start, 0, W_End, height])
            Wend = 0
    i = 0
    for 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.shape
            temp_label = [0.0] * 10
            temp_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.0
            for j in range(8):
                label.append(temp_label)
            i += 1
#添加噪声
def sp_noise(image,prob):
    output = np.zeros(image.shape,np.uint8)
    thres = 1 - prob
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            rdn = random.random()
            if rdn < prob:
                output[i][j] = 0
            elif rdn > thres:
                output[i][j] = 255
            else:
                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.shape
     x, y, w, h = 0, 0, 0, 0
     for 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]
             break
     return num_split(img)
#得到卡号区域后,绘制垂直投影直方图,字符分割,再将单个字符归一化为16*16大小的图像
#图像分割
def num_split(img):
    height, width = img.shape
    v = [0] * width
    z = [0] * height
    a = 0 
    #垂直投影:统计并存储每一列的黑点数
    #逐行存储
    for x in range(0, width):
        for y in range(0, height):
            if img[y, x] == 255:
                continue
            else:
                a = a + 1
        v[x] = a
        a = 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
    Position = []
    Wstart = 0
    Wend = 0
    W_Start = 0
    W_End = 0
    v[0], v[len(v)-1] = 0, 0
    for j in range(len(v)):
        if v[j] > 0 and Wstart == 0:
            W_Start = j
            Wstart = 1
            Wend = 0
        if v[j] <= 0 and Wstart == 1:
            W_End = j
            Wstart = 0
            Wend = 1
        if Wend == 1:
            Position.append([W_Start, 0, W_End, height])
            Wend = 0
    data = []
    #对单个字符处理 
    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.shape
        if w1 > h1:
            return []
        temp_img = cv2.resize(temp_img, (16, 16))
        h0, w0 = temp_img.shape
        temp_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相关资料,希望能帮助到所有小伙伴们。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

政府指导89元保330万 “聊惠保”2024年度正式上线!

11月15日&#xff0c;“聊惠保”2024年度启动仪式在聊城市融媒体中心举行。市政府领导&#xff0c;省直、市直相关部门单位和共保体成员单位负责同志参加仪式。“聊惠保”2024年度正式上线&#xff01;“聊惠保”项目组为聊城市医疗救助困难群体捐赠“聊惠保”2024年度团体保险…

python基础练习题库实验八

文章目录 前言题目1代码 题目2代码 题目3代码 总结 前言 &#x1f388;关于python小题库的这模块我已经两年半左右没有更新了&#xff0c;主要是在实习跟考研&#xff0c;目前已经上岸武汉某211计算机&#xff0c;目前重新学习这门课程&#xff0c;也做了一些新的题目 &#x…

LeetCode34-34. 在排序数组中查找元素的第一个和最后一个位置

&#x1f517;:代码随想录:二分查找的算法讲解:有关left<right和left<right的区别 class Solution {public int[] searchRange(int[] nums, int target) {int nnums.length;int l0,hn-1;if(numsnull){return null; }if(n0){return new int[]{-1,-1}; }if(target&l…

阿里云99元ECS云服务器老用户也能买,续费同价!

阿里云近日宣布了2023年的服务器优惠活动&#xff0c;令用户们振奋不已。最引人瞩目的消息是&#xff0c;阿里云放开了老用户的购买资格&#xff0c;99元服务器也可以供老用户购买&#xff0c;并且享受续费的99元优惠。此外&#xff0c;阿里云还推出了ECS经济型e实例&#xff0…

8年经验的软件工程师建议

我希望在职业生涯早期就开始做的事情和我希望以不同的方式做的事情。 大家好&#xff0c;我已经做了八年半的软件工程师。这篇文章来源于我最近对自己在职业生涯中希望早点开始做的事情以及希望以不同方式做的事情的自我反思。 我在这里分享的对任何希望提高和进步到高级甚至…

Java远程操作Linux服务器命令

Java可以通过SSH协议远程连接Linux服务器&#xff0c;然后使用JSch库或者Apache Commons Net库来执行远程Linux命令。以下是一个使用JSch库的示例代码&#xff1a; import com.jcraft.jsch.*;public class RemoteCommandExecutor {private String host;private String user;pr…

2023年亚太杯数学建模思路 - 复盘:人力资源安排的最优化模型

文章目录 0 赛题思路1 描述2 问题概括3 建模过程3.1 边界说明3.2 符号约定3.3 分析3.4 模型建立3.5 模型求解 4 模型评价与推广5 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 描述 …

ubuntu 20通过docker安装onlyoffice,并配置https访问

目录 一、安装docker &#xff08;一&#xff09;更新包列表和安装依赖项 &#xff08;二&#xff09;添加Docker的官方GPG密钥 &#xff08;三&#xff09;添加Docker存储库 &#xff08;四&#xff09;安装Docker &#xff08;五&#xff09;启动Docker服务并设置它随系…

2024年上半年:加密领域迎来无限机遇与重大突破!

2024年上半年将成为加密行业发展的关键时期&#xff0c;一系列重大事件和计划将为这一领域带来深远的影响。这些举措不仅有望吸引更多机构投资者和资金流入加密市场&#xff0c;还将进一步提升比特币的认可度和流动性&#xff0c;推动整个行业迈向新的阶段。 SEC批准比特币现货…

消息通讯——MQTT WebHookSpringBoot案例

目录 EMQX WebHook介绍EMQX WebHook是什么EMQX WebHook配置项如何使用EMQX WebHook配置WebHook配置事件推送参数详解 SpringBoot集成Webhook实现客户端断连监控1. 实现前提2. 代码实现接口3. 监听结果 总结 EMQX WebHook介绍 EMQX WebHook是什么 EMQX WebHook 是由 emqx_web_…

大语言模型概述|亚马逊这些互联网公司为什么花巨资训练自己的模型?

2023年可谓是大语言模型元年&#xff0c;OpenAI、亚马逊、谷歌等互联网公司争先恐后推出了自己的大语言模型&#xff1a;GPT-4、Titan、PaLM 2&#xff0c;还有亚马逊即将推出的第二个大语言模型Olympus等等。这一革命性技术如今已经在全球范围内引发了广泛的讨论和关注&#x…

保姆级fastDFS安装教程

一、软件准备 环境需要准备四个包&#xff0c;分别是&#xff1a; 1. libfastcommon_1.0.36 2. FastdfsFastdfs_v5.11 3. fastdfs-nginx-module5.11 4. nginxnginx-1.12.2 二、环境准备 安装perl环境&#xff0c;后续编译fastdfs会用到 yum -y install perl* yum -y ins…

Python武器库开发-flask篇之URL重定向(二十三)

flask篇之URL重定向(二十三) 通过url_for()函数构造动态的URL&#xff1a; 我们在flask之中不仅仅是可以匹配静态的URL&#xff0c;还可以通过url_for()这个函数构造动态的URL from flask import Flask from flask import url_forapp Flask(__name__)app.route(/) def inde…

为忙碌的软件工程师精心准备的编码面试准备材料,超过 100,000 人受益!

这是一个针对技术面试准备的手册。它收集了大量的面试问题和答案&#xff0c;涵盖了算法、系统设计、前端等主题&#xff0c;并且还在不断更新和完善中。 这个项目是“Tech Interview Handbook”&#xff0c;解决了求职者在技术面试中遇到的各种难题&#xff0c;帮助他们更好地…

Jenkins的一些其他操作

Jenkins的一些其他操作 1、代码仓库Gogs的搭建与配置 Gogs 是一款极易搭建的自助 Git 服务&#xff0c;它的目标在于打造一个最简单、快速和轻松的方式搭建 Git 服务。使用 Go 语言开发的它能够通过独立的二进制进行分发&#xff0c;支持了 Go 语言支持的所有平台&#xff0…

vivado产生报告阅读分析-Report Power4

在布线后会生成“ Power Report ” &#xff08; 功耗报告 &#xff09;&#xff0c; 它基于当前器件工作条件和设计的切换率来报告功耗详情。功耗分析要求网表已完成综合或设计已完成布局布线。 • set_operating_conditions 命令用于设置工作条件。 • set_switching_ac…

【深度学习】SimSwap: An Efficient Framework For High Fidelity Face Swapping 换脸,实战

代码&#xff1a;https://github.com/neuralchen/SimSwap 文章目录 摘要介绍RELATED WORK实验结论代码实操 SimSwap是一个高保真度人脸交换的高效框架。它将源脸的身份转移到目标脸上&#xff0c;同时保留目标脸的属性。该框架包括ID注入模块&#xff08;IIM&#xff09;&#…

【Python基础篇】标识符

博主&#xff1a;&#x1f44d;不许代码码上红 欢迎&#xff1a;&#x1f40b;点赞、收藏、关注、评论。 格言&#xff1a; 大鹏一日同风起&#xff0c;扶摇直上九万里。 文章目录 一 Python中的标识符二 Python中常见的关键字三 合法的标识符 一 Python中的标识符 定义&…

计算机视觉的应用16-基于pytorch框架搭建的注意力机制,在汽车品牌与型号分类识别的应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用16-基于pytorch框架搭建的注意力机制&#xff0c;在汽车品牌与型号分类识别的应用&#xff0c;该项目主要引导大家使用pytorch深度学习框架&#xff0c;并熟悉注意力机制模型的搭建&#xff0c;这个…

Spring Framework 核心容器详解:Core、Beans、Context 和 Expression Language 模块

Spring可能成为您的所有企业应用程序的一站式商店。但是&#xff0c;Spring是模块化的&#xff0c;允许您挑选适用于您的模块&#xff0c;而无需引入其他模块。下面的部分提供了Spring Framework中所有可用模块的详细信息。 Spring Framework提供了大约20个模块&#xff0c;可…