Python基于模板怎么实现匹配信用卡数字识别功能
发表于:2025-02-24 作者:千家信息网编辑
千家信息网最后更新 2025年02月24日,本篇内容主要讲解"Python基于模板怎么实现匹配信用卡数字识别功能",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Python基于模板怎么实现匹配信用卡数
千家信息网最后更新 2025年02月24日Python基于模板怎么实现匹配信用卡数字识别功能
本篇内容主要讲解"Python基于模板怎么实现匹配信用卡数字识别功能",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Python基于模板怎么实现匹配信用卡数字识别功能"吧!
环境介绍
Python 3.6 + OpenCV 3.4.1.15
原理介绍
首先,提取出模板中每一个数字的轮廓,再对信用卡图像进行处理,提取其中的数字部分,将该部分数字与模板进行匹配,即可得到结果。
完整代码
# !/usr/bin/env python# -*- coding: utf-8 -*-# @Time: 2020/1/11 14:57# @Author: Martin# @File: utils.py# @Software:PyCharmimport cv2def sort_contours(cnts, method='left-to-right'): reverse = False i = 0 if method == 'right-to-left' or method == 'bottom-to-top': reverse = True if method == 'top-to-bottom' or method == 'bottom-to-top': i = 1 boundingboxes = [cv2.boundingRect(c) for c in cnts] (cnts, boundingboxes) = zip(*sorted(zip(cnts, boundingboxes), key=lambda b: b[1][i], reverse=reverse)) return cnts, boundingboxesdef resize(image, width=None, height=None, inter=cv2.INTER_AREA): (h, w) = image.shape[:2] if width is None and height is None: return image if 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# !/usr/bin/env python# -*- coding: utf-8 -*-# @Time: 2020/1/11 14:57# @Author: Martin# @File: template_match.py# @Software:PyCharm"""基于模板匹配的信用卡数字识别"""import cv2import utilsimport numpy as np# 指定信用卡类型FIRST_NUMBER = { '3' : 'American Express', '4' : 'Visa', '5' : 'MasterCard', '6' : 'Discover Card'}# 绘图显示def cv_show(name, image): cv2.imshow(name, image) cv2.waitKey(0) cv2.destroyAllWindows()# 读取模板图像img = cv2.imread('./images/ocr_a_reference.png')cv_show('img', img)# 转化成灰度图ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)cv_show('ref', ref)# 转化成二值图像ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]cv_show('ref', ref)# 计算轮廓ref_, refCnts, hierarchy = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)cv2.drawContours(img, refCnts, -1, (0, 0, 255), 3)cv_show('img', img)print(np.array(refCnts).shape)# 排序,从左到右,从上到下refCnts = utils.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# 初始化卷积核rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))# 读取输入图像,预处理img_path = input("Input the path and image name: ")image_input = cv2.imread(img_path)cv_show('image', image_input)image_input = utils.resize(image_input, width=300)gray = cv2.cvtColor(image_input, cv2.COLOR_BGR2GRAY)cv_show('gray', gray)# 礼帽操作,突出更明亮的区域tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)cv_show('tophat', tophat)gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)gradX = np.absolute(gradX)(minVal, maxVal) = (np.min(gradX), np.max(gradX))gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))gradX = gradX.astype("uint8")print(np.array(gradX).shape)cv_show('gradX', gradX)# 闭操作gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)cv_show('gradX', gradX)thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]cv_show('thresh', thresh)thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)cv_show('thresh', thresh)# 计算轮廓thresh_, threshCnts, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)cnts = threshCntscur_img = image_input.copy()cv2.drawContours(cur_img, cnts, -1, (0, 0, 255), 3)cv_show('img', cur_img)locs = []# 遍历轮廓for (i, c) in enumerate(cnts): (x, y, w, h) = cv2.boundingRect(c) ar = w / float(h) if 2.5 < ar < 4.0 and (40 < w < 55) and (10 < h < 20): locs.append((x, y, w, h))# 将符合的轮廓从左到右排序locs = sorted(locs, key=lambda ix: ix[0])output = []# 遍历每一个轮廓中的数字for (i, (gX, gY, gW, gH)) in enumerate(locs): groupOutput = [] group = gray[gY - 5:gY + gH + 5, gX - 5: gX + gW + 5] cv_show('group', group) # 预处理 group = cv2.threshold(group, 0, 255, cv2.THRESH_OTSU)[1] cv_show('group', group) # 计算每一组轮廓 group_, digitCnts, hierarchy = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) digitCnts = utils.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)) cv_show('roi', 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_input, (gX - 5, gY - 5), (gX + gW + 5, gY + gH + 5), (0, 0, 255), 1) cv2.putText(image_input, "".join(groupOutput), (gX, gY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2) # 得到结果 output.extend(groupOutput)# 打印结果print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))print("Credit Card #: {}".format("".join(output)))cv2.imshow("Image", image_input)cv2.waitKey(0)cv2.destroyAllWindows()
结果展示
Credit Card Type: VisaCredit Card #: 4020340002345678
到此,相信大家对"Python基于模板怎么实现匹配信用卡数字识别功能"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
数字
轮廓
模板
信用
信用卡
图像
结果
功能
内容
部分
utf-8
学习
排序
预处理
合适
实用
明亮
更深
代码
兴趣
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
检测服务器支持ipv6
服务器能管理其它计算机吗
网易实况足球有服务器么
和龙软件开发公司有哪些
服务器跟域名那样做才安全
唐山网站建设磐石网络安全
常见的网络安全设备毕业论文
游戏登录时服务器维护
网络安全为人民网络靠人民故事
网络安全使用小贴士
网络技术破解网
校园网络安全进展
我的世界怎么隐藏服务器ip地址
服务器安全狗 小红伞
软件开发费用怎么入账
电力系统信号分析软件开发
怎样创建多人编辑的数据库
全球网络安全公司有哪些
办公网络安全宣传周
数据库身份证长度约束
sass 软件开发模式
托管软件服务器
合肥信贷软件开发
数据库范式主码是什么
金算盘财务软件数据库
南京专业软件开发销售公司
服务器ip访问
桓台应用软件开发公司
辽事通修改手机号数据库操作异常
affy数据库是什么