Python基于模板怎么实现匹配信用卡数字识别功能
发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,本篇内容主要讲解"Python基于模板怎么实现匹配信用卡数字识别功能",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Python基于模板怎么实现匹配信用卡数
千家信息网最后更新 2026年10月31日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安全错误
数据库的锁怎样保障安全
耶加雪菲
互联网科技开发公司
互联网 科技创业
善班互联网科技
广州互联网络科技有限公司
奇酷互联网络科技公司
碳银互联网科技有限公司
顺玮阁互联网科技
互联网科技素材视频竖屏
互联网科技公司的市场部门
栖莱科技互联网股份有限公司
岳阳华臻互联网科技有限公司
呼和浩特新华互联网科技学院
畅思互联网科技
迪庆互联网科技招生
华夏恒生互联网科技013171
宇信科技在杭州互联网排第几
信承诺互联网科技有限公司
上海互联网科技园景观
知域互联网科技有限公司官网
博彦科技互联网金融
互联网科技的未来发展
海南购全球互联网科技
西藏七维空间互联网科技有限公司
怎样加入科技互联网
互联网时代科技型公司的机会
恒生科技指数 中概互联网
青岛易易互联网科技
互联网科技创业计划的风险分析
网互联网络科技