【OpenCV】 ⚠️实战⚠️ 银行卡卡号读取 ☢️建议手收藏☢️

【OpenCV】 ⚠️实战⚠️ 银行卡卡号读取

  • 概述
  • 预处理
    • 代码
    • 模板预处理
    • 银行卡预处理
  • 计算轮廓
    • 代码
    • 模板轮廓
    • 银行卡轮廓
  • 其他程序
  • 主函数
    • 代码
    • 数字分割
    • 最终结果

概述

今天带大家使用我们之前学会的知识来实现银行卡卡号读取. 代码分为四个部分: 主函程序, 预处理, 计算轮廓, 其他程序.

在这里插入图片描述

预处理

通过灰度转换, 二值化, 膨胀, 腐蚀, 边缘检测等方法, 去除图片噪声, 突出我们想要得到的结果.

在这里插入图片描述

代码

import numpy as np
import cv2
from matplotlib import pyplot as plt
from my_functions import resizedef read_template(image_path, visualize=False):"""读取模板:param image_path: 图片路径:param visualize: 可视化, 默认为False:return: 返回模板, 二值化后的模板"""# 读取模板template = cv2.imread(image_path)# 转换成灰度图template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)# 二值化ret, template_thresh = cv2.threshold(template_gray, 10, 255, cv2.THRESH_BINARY_INV)# 如果展示为真if visualize:"""图片展示"""# 绘制子图f, ax = plt.subplots(3, 1, figsize=(10, 8))ax[0].imshow(template)ax[1].imshow(template_gray, "gray")ax[2].imshow(template_thresh, "gray")# 标题ax[0].set_title("template")ax[1].set_title("template gray")ax[2].set_title("template binary inverse")plt.show()# 返回return template, template_threshdef read_image(image_path, visualize=False):"""读取银行卡图片:param image_path: 图片路径:param visualize: 可视化, 默认为False:return: 返回裁剪后的图片, 灰度图, 处理后的图"""# 初始化卷积核rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))# 读取图片image = cv2.imread(image_path)# 更改尺寸image_resize = resize(image, width=300)# 转换成灰度图image_gray = cv2.cvtColor(image_resize, cv2.COLOR_BGR2GRAY)# 礼帽操作, 突出明亮区域tophat = cv2.morphologyEx(image_gray, cv2.MORPH_TOPHAT, rectKernel)# Sobel边缘检测edge = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)edge = np.absolute(edge)# 标准化edge = 255 * cv2.normalize(edge, None, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)edge = edge.astype("uint8")# 通过闭操作(先膨胀,再腐蚀)将数字连在一起edge_close = cv2.morphologyEx(edge, cv2.MORPH_CLOSE, rectKernel)# THRESH_OTSU会自动寻找合适的阈值,适合双峰,需把阈值参数设置为0ret, thresh = cv2.threshold(edge_close, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)# 再来一个闭操作thresh_close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)  # 再来一个闭操作# 如果展示为真if visualize:"""图片展示"""# 绘制子图f, ax = plt.subplots(2, 2, figsize=(12, 8))ax[0, 0].imshow(cv2.cvtColor(image_resize, cv2.COLOR_BGR2RGB))ax[0, 1].imshow(image_gray, "gray")ax[1, 0].imshow(tophat, "gray")ax[1, 1].imshow(edge, "gray")# 标题ax[0, 0].set_title("image resize")ax[0, 1].set_title("image gray")ax[1, 0].set_title("image tophat")ax[1, 1].set_title("image edge")plt.show()# 绘制子图f, ax = plt.subplots(2, 2, figsize=(12, 8))ax[0, 0].imshow(edge, "gray")ax[0, 1].imshow(edge_close, "gray")ax[1, 0].imshow(thresh, "gray")ax[1, 1].imshow(thresh_close, "gray")# 标题ax[0, 0].set_title("image edge")ax[0, 1].set_title("image close")ax[1, 0].set_title("image binary")ax[1, 1].set_title("image binary close")plt.show()# 返回return image_resize, image_gray, thresh

模板预处理

在这里插入图片描述

银行卡预处理

在这里插入图片描述

在这里插入图片描述

计算轮廓

代码

import cv2
from matplotlib import pyplot as plt, gridspec
from my_functions import sort_contoursdef template_calculate_contours(template, template_binary, visualize=False):"""计算模板轮廓:param template: 模板:param template_binary: 二值化的模板:return: 轮廓"""# 获取轮廓contours, hierarchy = cv2.findContours(template_binary.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 轮廓排序, 从左到右, 从上到下contours = sort_contours(contours)digits = {}# 遍历每一个轮廓for (i, c) in enumerate(contours):# 计算矩阵(x, y, w, h) = cv2.boundingRect(c)# 获取roiroi = template_binary[y:y + h, x:x + w]roi = cv2.resize(roi, (57, 88))# 每一个数字对应每一个模板digits[i] = roiif visualize:"""图片展示"""# 绘制子图plt.figure(figsize=(12, 6))gs = gridspec.GridSpec(2, 10)# 轴1plt.subplot(gs[0, :10])plt.imshow(template, "gray")plt.xticks([])plt.yticks([])plt.title("original")# 轴2for (number, image) in digits.items():plt.subplot(gs[1, number])plt.xticks([])plt.yticks([])plt.imshow(image, "gray")plt.title("number: {}".format(number))plt.show()print(digits)return digitsdef image_calculate_contours(image, thresh, visualize=False):"""计算轮廓:param image: 图片:param thresh: 处理后的图片:param visualize: 可视化, 默认为False:return: 轮廓"""# 获取轮廓contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 绘制轮廓cur_img = image.copy()image_with_contour = cv2.drawContours(cur_img, contours, -1, (0, 0, 255), 3)# 位置locations = []# 遍历轮廓for (i, c) in enumerate(contours):# 计算矩形(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):# 符合的留下来locations.append((x, y, w, h))# 将符合的轮廓从左到右排序locs = sorted(locations, key=lambda x: x[0])if visualize:"""图片展示"""# 绘制子图f, ax = plt.subplots(2, 1, figsize=(12, 8))ax[0].imshow(cv2.cvtColor(image_with_contour, cv2.COLOR_BGR2RGB))for r in locs:(x, y, w, h) = rrectangle = cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)ax[1].imshow(cv2.cvtColor(rectangle, cv2.COLOR_BGR2RGB))# 标题ax[0].set_title("original")ax[1].set_title("detect")plt.show()return locs

模板轮廓

在这里插入图片描述

银行卡轮廓

在这里插入图片描述

其他程序

import cv2def img_show(name, img):"""图片展示"""cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()def sort_contours(contours):"""轮廓排序 (从左到右):param contours: 轮廓:return: 返回排序好的轮廓"""boundingBoxes = [cv2.boundingRect(c) for c in contours]  # 用一个最小的矩形,把找到的形状包起来x,y,h,w(contours, boundingBoxes) = zip(*sorted(zip(contours, boundingBoxes), key=lambda b: b[1][0]))return contoursdef resize(image, width=None, height=None, inter=cv2.INTER_AREA):"""修改图片大小:param image: 原图:param width: 宽:param height: 高:param inter: 模式:return: 修改好的图片"""dim = None(h, w) = image.shape[:2]if width is None and height is None:return imageif 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)return resized

主函数

代码

import numpy as np
import argparse
import cv2
from matplotlib import pyplot as plt
from my_functions import sort_contours
from pre_process import read_template
from pre_process import read_image
from calculate_contours import template_calculate_contours
from calculate_contours import image_calculate_contoursdef extract_number(image_gray, locations, digits, visualize=False):"""提取数字:param image_gray: 灰度图:param locations: 图片轮廓:param digits: 模板轮廓:param visualize: 可视化, 默认为False:return: 读取完数字的图片"""# 输出output = []# 图片total_img = []# 遍历每一个轮廓中的数字for (i, (gX, gY, gW, gH)) in enumerate(locations):# 组输出groupOutput = []group_img = []# 根据坐标提取每一个组group = image_gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]# 预处理group_binary = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]# 计算每一组的轮廓digitCnts, hierarchy = cv2.findContours(group_binary.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)digitCnts = sort_contours(digitCnts)# 计算每一组中的每一个数值for c in digitCnts:# 找到当前数值的轮廓,resize成合适的的大小(x, y, w, h) = cv2.boundingRect(c)roi = group[y:y + h, x:x + w]roi = cv2.resize(roi, (57, 88))group_img.append(roi)# 计算匹配得分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)# 添加图片total_img.append(group_img)if visualize:"""图片展示"""# 绘制子图f, ax = plt.subplots(4, 4, figsize=(8, 8))for i, group_im in enumerate(total_img):for j, im in enumerate(group_im):ax[i, j].imshow(im, "gray")ax[i, j].set_xticks([])ax[i, j].set_yticks([])ax[i, j].set_title("group: {}".format(i + 1))plt.show()# 展示最终图片plt.figure(figsize=(10, 8))plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))plt.title("Final Result")plt.show()return imagedef parse_opt():"""设置参数"""parser = argparse.ArgumentParser()parser.add_argument("--image_path", type=str, default="images/credit_card_01.png", help="输入图片路径")parser.add_argument("--template_path", type=str, default="template/template.png", help="模板图片路径")args = parser.parse_args()return argsif __name__ == "__main__":args = parse_opt()# 读取模板template, template_binary = read_template(args.template_path, True)# 计算模板轮廓digits = template_calculate_contours(template=template, template_binary=template_binary, visualize=True)# 读取图片image, image_gray, thresh = read_image(args.image_path, visualize=True)# 计算图片轮廓locations = image_calculate_contours(image, thresh, visualize=True)# 提取数字result = extract_number(image_gray=image_gray, locations=locations, digits=digits, visualize=True)# 保存最终结果cv2.imwrite("Final_result.png", result)

数字分割

在这里插入图片描述

最终结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

openCV实践项目:银行卡卡号识别

本文用于对之前openCV知识点学习的复习及实践。要求达到以下效果&#xff1a; 一、基本流程思路分析 本项目本质上就是进行模板匹配。 注&#xff1a;为多用到所学知识&#xff0c;为了加深理解多加了些步骤&#xff0c;实际上本项目可以很简单就能完成。 1.1 模板处理 模…

什么是物联网平台

1、什么是物联网平台 阿里云物联网平台为设备提供安全可靠的连接通信能力&#xff0c;向下连接海量设备&#xff0c;支撑设备数据采集上云&#xff1b;向上提供云端API&#xff0c;服务端通过调用云端API将指令下发至设备端&#xff0c;实现远程控制。 物联网平台消息通信流程…

新兴 IoT 物联网场景中 MQTT 与 TCP 通信协议对比

在IoT 物联网开发中&#xff0c;大多数通信模组都支持 TCP、UDP、MQTT、CoAP、HTTP、LwM2M 等网络通信协议&#xff0c;其中既有传输层协议&#xff0c;也有应用层的协议&#xff0c;不同协议适用的场景也不同。 我们在设计IoT硬件产品时&#xff0c;通常只需选择一种协议即可。…

lot物联网场景通用架构分享

1.通用参考架构&#xff1a; 2.lot物联网硬件设备上云技术方案&#xff1a; #lot物联网业务链路包含&#xff1a;数据采集&#xff0c;通信连接&#xff0c;数据存储&#xff0c;数据可视化&#xff0c;洞察&#xff0c;行动决策&#xff1b;其中以设备端各种厂商提供得协议差…

物联网网络通讯知识

RTU是什么 RTU英文全称Remote Terminal Units&#xff0c;中文全称为远程终端单元。远程终端设备(RTU)是安装在远程现场的电子设备&#xff0c;用来监视和测量安装在远程现场的传感器和设备。通俗理解就是能够编程的还可以将数据传输到服务器的工具。RTU内部是包含通讯模块的&…

APP与服务器之间通过 http(POST、GET)进行数据交互 ( 实现一个简单的物联网系统-1 )

文章目录 一、APP POST 数据到服务器二、APP 从服务器 GET 数据三、APP 界面部分四、相关疑问五、学习方法六、专栏地址 一、APP POST 数据到服务器 首先 post 的数据应该包括识别这个花卉的信息和我们想要浇水的量&#xff0c;这里我们识别花卉采用花卉的名字&#xff0c;这样…

什么是物联网(Internet of Things)?

你可能在某些时候会听到物联网这个词&#xff0c;但是你对它可能不知所以然&#xff0c;这篇文章让你弄清楚什么是物联网&#xff0c;以及它代表什么&#xff1f; 物联网&#xff08;Internet of Things&#xff09;是指设备到互联网的连接。汽车&#xff0c;厨房电器&#xff…

物联网网关有哪些能力和哪些应用?

工业物联网的应用受到越来越多企业的关注&#xff0c;很多人都了解网关这个概念。网关就是一个网络连接到另一个网口的桥梁&#xff0c;起到协议解析、数据采集的作用&#xff0c;实现运行状态数据的高效利用。 物联网网关具备的能力 1、广泛连接的能力 目前各个行业、不同设…

一文了解物联网网关

物联网是指通过射频识别(RFID)、红外感应器、GPS、激光扫描器等信息传感设备&#xff0c;按约定的协议&#xff0c;实现任何时间、任何地点、任何物体进行信息交换和通信&#xff0c;以实现智能化识别、定位、监控和管理的一种网络。物联网是具有全面感知、可靠传输、智能处理特…

什么是物联网?有哪些应用?终于有人讲明白了

作者&#xff1a;佩里利&#xff08;Perry Lea&#xff09; 来源&#xff1a;大数据DT&#xff08;ID&#xff1a;hzdashuju&#xff09; 我们将从连接设备的角度来研究物联网&#xff0c;这些设备之前未必相互连接或接入互联网。它们可能一直没有太多的计算或通信能力。我们假…

LPWA物联网通信

物联网LPWA是物联网中的无线通信技术之一。 根据物联网无线通信技术的覆盖距离&#xff0c;大致可分为两类&#xff1a;一类是短距离通信技术&#xff0c;包括蓝牙(蓝牙)&#xff1b;NFC,Zigbee、WIFI、NFC&#xff0c;主要用于室内智能家庭、消费电子等场景&#xff1b;另一种…

物联网通讯协议:MQTT,NB-IOT,Zigbee,CoAP,RFID,BLUETOOTH,NFC,4G,HTTP

目录 一、按网络四层协议分类二、按需要网关来分类三、NB-IoT&#xff0c;4G对比四、应用层协议&#xff1a;MQTT和COAP对比物联网组网技术WIFI蓝牙ZigBee2G/4G/5GNB-IoTLoRa网关 物联网中常见的物联通信协议TCPUDPTCP和UDP比较HTTPMQTTCoAPLwM2M 一、按网络四层协议分类 NB-I…

chatgpt赋能python:如何使用Python拷贝微信聊天记录的图片?

如何使用Python拷贝微信聊天记录的图片&#xff1f; 微信聊天记录中的图片是我们很重要的一部分。它们记录了我们和我们的朋友、家人和同事之间的重要时刻和特殊瞬间。然而&#xff0c;有些时候我们需要把这些图片从微信聊天记录中拷贝出来&#xff0c;以便于备份和共享。本文…

《辉煌优配》科技股强势引领A股反弹 沪深两市日成交额再超万亿元

受美联储再度加息扰动&#xff0c;昨日早盘沪深两市指数低开&#xff0c;随后科技股强势拉升&#xff0c;带动商场回暖。到收盘&#xff0c;上证综指报3286.65点&#xff0c;上涨0.64%&#xff1b;深证成指报11605.29点&#xff0c;上涨0.94%&#xff1b;创业板指报2361.41点&a…

深度分析台积电的投资价值:伟大的公司,伟大的投资

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 公司介绍 台积电&#xff08;TSM&#xff09;是一家在1987年成立于台湾的半导体公司&#xff0c;并在全球范围内率先实施了“商业晶圆厂”代工模式。该公司为部分或全部外包生产的半导体生产商提供晶圆代工服务。台积电的产…

汇正财经靠谱吗?沪深创再现调整

盘面回顾&#xff1a; 周三A股开盘时间段&#xff0c;人民币再现快速贬值&#xff0c;再加上5月PMI数据不及预期&#xff0c;空头情绪放大&#xff0c;沪深创再陷调整&#xff0c;截止收盘沪指跌0.61%&#xff0c;深成指跌0.7%&#xff0c;创业板指跌1.14%。全天唯独科创50能逆…

超级模型GPT-4发布!

本文来源 量子位 一觉醒来&#xff0c;万众期待的GPT-4&#xff0c;它来了&#xff01; OpenAI老板Sam Altman直接开门见山地介绍说&#xff1a; 这是我们迄今为止功能最强大的模型&#xff01; 有多强&#xff1f; 根据OpenAI官方的介绍&#xff0c;GPT-4是一个超大的多模态…

透过现象看本质 | GPT爆火的背后

前言&#xff1a; 近年来&#xff0c;GPT&#xff08;Generative Pre-trained Transformer&#xff09;作为一种革命性的语言模型&#xff0c;以其强大的文本生成能力和广泛的应用领域引发了全球范围内的热议。然而&#xff0c;GPT爆火的背后&#xff0c;是一个更加深刻的本质。…

2014年考研英语二作文PartB图表题

作文详细解析 题目 Write an essay based on the following chart, in which you should interpret the chart, and give your comments You should write about 150 words on the ANSWER SHEET.(15 points) 注意点 1.图表题在第一段描述图表信息时,一定要写清楚y轴变化…

【考研】2018-Part B 作文(英一)

前言 10月要开始冲刺英一作文&#xff0c;会陆续推出 2013 - 2022 英一 Part A 和 PartB 的优秀范文&#xff0c;并用红色字体标明应用模板&#xff0c;并列举重点单词和词组&#xff0c;以积累词汇。 一、2018 Part B &#xff08;一&#xff09;题目及解析 提示信息信息解析…